MyGUI  3.2.0
MyGUI_EditText.cpp
Go to the documentation of this file.
00001 
00006 /*
00007     This file is part of MyGUI.
00008 
00009     MyGUI is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     MyGUI is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 #include "MyGUI_Precompiled.h"
00023 #include "MyGUI_EditText.h"
00024 #include "MyGUI_RenderItem.h"
00025 #include "MyGUI_FontManager.h"
00026 #include "MyGUI_RenderManager.h"
00027 #include "MyGUI_LanguageManager.h"
00028 #include "MyGUI_TextIterator.h"
00029 #include "MyGUI_IRenderTarget.h"
00030 #include "MyGUI_FontData.h"
00031 #include "MyGUI_CommonStateInfo.h"
00032 
00033 namespace MyGUI
00034 {
00035 
00036     const size_t VERTEX_IN_QUAD = 6;
00037     const size_t SIMPLETEXT_COUNT_VERTEX = 32 * VERTEX_IN_QUAD;
00038 
00039     EditText::EditText() :
00040         ISubWidgetText(),
00041         mEmptyView(false),
00042         mCurrentColourNative(0x00FFFFFF),
00043         mInverseColourNative(0x00000000),
00044         mCurrentAlphaNative(0xFF000000),
00045         mShadowColourNative(0x00000000),
00046         mTextOutDate(false),
00047         mTextAlign(Align::Default),
00048         mColour(Colour::White),
00049         mShadowColour(Colour::Black),
00050         mAlpha(ALPHA_MAX),
00051         mFont(nullptr),
00052         mTexture(nullptr),
00053         mFontHeight(0),
00054         mBackgroundNormal(true),
00055         mStartSelect(0),
00056         mEndSelect(0),
00057         mCursorPosition(0),
00058         mVisibleCursor(false),
00059         mInvertSelect(true),
00060         mShadow(false),
00061         mNode(nullptr),
00062         mRenderItem(nullptr),
00063         mCountVertex(SIMPLETEXT_COUNT_VERTEX),
00064         mIsAddCursorWidth(true),
00065         mShiftText(false),
00066         mWordWrap(false),
00067         mManualColour(false),
00068         mOldWidth(0)
00069     {
00070         mVertexFormat = RenderManager::getInstance().getVertexFormat();
00071 
00072         mCurrentColourNative = texture_utility::toColourARGB(mColour);
00073         texture_utility::convertColour(mCurrentColourNative, mVertexFormat);
00074 
00075         mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00076         mShadowColourNative =  (mShadowColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00077         mInverseColourNative = mCurrentColourNative ^ 0x00FFFFFF;
00078     }
00079 
00080     EditText::~EditText()
00081     {
00082     }
00083 
00084     void EditText::setVisible(bool _visible)
00085     {
00086         if (mVisible == _visible)
00087             return;
00088         mVisible = _visible;
00089 
00090         if (nullptr != mNode)
00091             mNode->outOfDate(mRenderItem);
00092     }
00093 
00094     void EditText::_correctView()
00095     {
00096         if (nullptr != mNode)
00097             mNode->outOfDate(mRenderItem);
00098     }
00099 
00100     void EditText::_setAlign(const IntSize& _oldsize)
00101     {
00102         if (mWordWrap)
00103         {
00104             // передается старая координата всегда
00105             int width = mCroppedParent->getWidth();
00106             if (mOldWidth != width)
00107             {
00108                 mOldWidth = width;
00109                 mTextOutDate = true;
00110             }
00111         }
00112 
00113         // необходимо разобраться
00114         bool need_update = true;//_update;
00115 
00116         // первоначальное выравнивание
00117         if (mAlign.isHStretch())
00118         {
00119             // растягиваем
00120             mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
00121             need_update = true;
00122             mIsMargin = true; // при изменении размеров все пересчитывать
00123         }
00124         else if (mAlign.isRight())
00125         {
00126             // двигаем по правому краю
00127             mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
00128             need_update = true;
00129         }
00130         else if (mAlign.isHCenter())
00131         {
00132             // выравнивание по горизонтали без растяжения
00133             mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
00134             need_update = true;
00135         }
00136 
00137         if (mAlign.isVStretch())
00138         {
00139             // растягиваем
00140             mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
00141             need_update = true;
00142             mIsMargin = true; // при изменении размеров все пересчитывать
00143         }
00144         else if (mAlign.isBottom())
00145         {
00146             // двигаем по нижнему краю
00147             mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
00148             need_update = true;
00149         }
00150         else if (mAlign.isVCenter())
00151         {
00152             // выравнивание по вертикали без растяжения
00153             mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
00154             need_update = true;
00155         }
00156 
00157         if (need_update)
00158         {
00159             mCurrentCoord = mCoord;
00160             _updateView();
00161         }
00162     }
00163 
00164     void EditText::_updateView()
00165     {
00166         bool margin = _checkMargin();
00167 
00168         mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
00169 
00170         mCurrentCoord.left = mCoord.left + mMargin.left;
00171         mCurrentCoord.top = mCoord.top + mMargin.top;
00172 
00173         // вьюпорт стал битым
00174         if (margin)
00175         {
00176             // проверка на полный выход за границу
00177             if (_checkOutside())
00178             {
00179                 // запоминаем текущее состояние
00180                 mIsMargin = margin;
00181 
00182                 // обновить перед выходом
00183                 if (nullptr != mNode)
00184                     mNode->outOfDate(mRenderItem);
00185                 return;
00186             }
00187         }
00188 
00189         // мы обрезаны или были обрезаны
00190         if (mIsMargin || margin)
00191         {
00192             mCurrentCoord.width = _getViewWidth();
00193             mCurrentCoord.height = _getViewHeight();
00194         }
00195 
00196         // запоминаем текущее состояние
00197         mIsMargin = margin;
00198 
00199         if (nullptr != mNode)
00200             mNode->outOfDate(mRenderItem);
00201     }
00202 
00203     void EditText::setCaption(const UString& _value)
00204     {
00205         mCaption = _value;
00206         mTextOutDate = true;
00207 
00208         checkVertexSize();
00209 
00210         if (nullptr != mNode)
00211             mNode->outOfDate(mRenderItem);
00212     }
00213 
00214     void EditText::checkVertexSize()
00215     {
00216         // если вершин не хватит, делаем реалок, с учетом выделения * 2 и курсора
00217         size_t need = (mCaption.size() * (mShadow ? 3 : 2) + 2) * VERTEX_IN_QUAD;
00218         if (mCountVertex < need)
00219         {
00220             mCountVertex = need + SIMPLETEXT_COUNT_VERTEX;
00221             if (nullptr != mRenderItem)
00222                 mRenderItem->reallockDrawItem(this, mCountVertex);
00223         }
00224     }
00225 
00226     const UString& EditText::getCaption() const
00227     {
00228         return mCaption;
00229     }
00230 
00231     void EditText::setTextColour(const Colour& _value)
00232     {
00233         mManualColour = true;
00234         _setTextColour(_value);
00235     }
00236 
00237     void EditText::_setTextColour(const Colour& _value)
00238     {
00239         if (mColour == _value)
00240             return;
00241 
00242         mColour = _value;
00243         mCurrentColourNative = texture_utility::toColourARGB(mColour);
00244 
00245         texture_utility::convertColour(mCurrentColourNative, mVertexFormat);
00246 
00247         mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00248         mInverseColourNative = mCurrentColourNative ^ 0x00FFFFFF;
00249 
00250         if (nullptr != mNode)
00251             mNode->outOfDate(mRenderItem);
00252     }
00253 
00254     const Colour& EditText::getTextColour() const
00255     {
00256         return mColour;
00257     }
00258 
00259     void EditText::setAlpha(float _value)
00260     {
00261         if (mAlpha == _value)
00262             return;
00263         mAlpha = _value;
00264 
00265         mCurrentAlphaNative = ((uint8)(mAlpha * 255) << 24);
00266         mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00267         mShadowColourNative = (mShadowColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00268         mInverseColourNative = mCurrentColourNative ^ 0x00FFFFFF;
00269 
00270         if (nullptr != mNode)
00271             mNode->outOfDate(mRenderItem);
00272     }
00273 
00274     float EditText::getAlpha() const
00275     {
00276         return mAlpha;
00277     }
00278 
00279     void EditText::setFontName(const std::string& _value)
00280     {
00281         mTexture = 0;
00282         mFont = FontManager::getInstance().getByName(_value);
00283         if (mFont != nullptr)
00284         {
00285             mTexture = mFont->getTextureFont();
00286 
00287             // если надо, устанавливаем дефолтный размер шрифта
00288             if (mFont->getDefaultHeight() != 0)
00289             {
00290                 mFontHeight = mFont->getDefaultHeight();
00291             }
00292         }
00293 
00294         mTextOutDate = true;
00295 
00296         // если мы были приаттаченны, то удаляем себя
00297         if (nullptr != mRenderItem)
00298         {
00299             mRenderItem->removeDrawItem(this);
00300             mRenderItem = nullptr;
00301         }
00302 
00303         // если есть текстура, то приаттачиваемся
00304         if (nullptr != mTexture && nullptr != mNode)
00305         {
00306             mRenderItem = mNode->addToRenderItem(mTexture, false, false);
00307             mRenderItem->addDrawItem(this, mCountVertex);
00308         }
00309 
00310         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00311     }
00312 
00313     const std::string& EditText::getFontName() const
00314     {
00315         return mFont->getResourceName();
00316     }
00317 
00318     void EditText::setFontHeight(int _value)
00319     {
00320         mFontHeight = _value;
00321         mTextOutDate = true;
00322 
00323         if (nullptr != mNode)
00324             mNode->outOfDate(mRenderItem);
00325     }
00326 
00327     int EditText::getFontHeight() const
00328     {
00329         return mFontHeight;
00330     }
00331 
00332     void EditText::createDrawItem(ITexture* _texture, ILayerNode* _node)
00333     {
00334         mNode = _node;
00335         // если уже есть текстура, то атачимся, актуально для смены леера
00336         if (nullptr != mTexture)
00337         {
00338             MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
00339 
00340             mRenderItem = mNode->addToRenderItem(mTexture, false, false);
00341             mRenderItem->addDrawItem(this, mCountVertex);
00342         }
00343     }
00344 
00345     void EditText::destroyDrawItem()
00346     {
00347         if (nullptr != mRenderItem)
00348         {
00349             mRenderItem->removeDrawItem(this);
00350             mRenderItem = nullptr;
00351         }
00352         mNode = nullptr;
00353     }
00354 
00355     size_t EditText::getTextSelectionStart() const
00356     {
00357         return mStartSelect;
00358     }
00359 
00360     size_t EditText::getTextSelectionEnd() const
00361     {
00362         return mEndSelect;
00363     }
00364 
00365     void EditText::setTextSelection(size_t _start, size_t _end)
00366     {
00367         mStartSelect = _start;
00368         mEndSelect = _end;
00369 
00370         if (nullptr != mNode)
00371             mNode->outOfDate(mRenderItem);
00372     }
00373 
00374     bool EditText::getSelectBackground() const
00375     {
00376         return mBackgroundNormal;
00377     }
00378 
00379     void EditText::setSelectBackground(bool _normal)
00380     {
00381         if (mBackgroundNormal == _normal)
00382             return;
00383         mBackgroundNormal = _normal;
00384 
00385         if (nullptr != mNode)
00386             mNode->outOfDate(mRenderItem);
00387     }
00388 
00389     bool EditText::isVisibleCursor() const
00390     {
00391         return mVisibleCursor;
00392     }
00393 
00394     void EditText::setVisibleCursor(bool _value)
00395     {
00396         if (mVisibleCursor == _value)
00397             return;
00398         mVisibleCursor = _value;
00399 
00400         if (nullptr != mNode)
00401             mNode->outOfDate(mRenderItem);
00402     }
00403 
00404     size_t EditText::getCursorPosition() const
00405     {
00406         return mCursorPosition;
00407     }
00408 
00409     void EditText::setCursorPosition(size_t _index)
00410     {
00411         if (mCursorPosition == _index)
00412             return;
00413         mCursorPosition = _index;
00414 
00415         if (nullptr != mNode)
00416             mNode->outOfDate(mRenderItem);
00417     }
00418 
00419     void EditText::setTextAlign(Align _value)
00420     {
00421         mTextAlign = _value;
00422 
00423         if (nullptr != mNode)
00424             mNode->outOfDate(mRenderItem);
00425     }
00426 
00427     Align EditText::getTextAlign() const
00428     {
00429         return mTextAlign;
00430     }
00431 
00432     IntSize EditText::getTextSize()
00433     {
00434         // если нуно обновить, или изменились пропорции экрана
00435         if (mTextOutDate)
00436             updateRawData();
00437 
00438         IntSize size = mTextView.getViewSize();
00439 
00440         // плюс размер курсора
00441         if (mIsAddCursorWidth)
00442             size.width += 2;
00443 
00444         if (mShadow)
00445         {
00446             if (!mIsAddCursorWidth)
00447                 size.width ++;
00448             size.height ++;
00449         }
00450 
00451         return size;
00452     }
00453 
00454     void EditText::setViewOffset(const IntPoint& _point)
00455     {
00456         mViewOffset = _point;
00457 
00458         if (nullptr != mNode)
00459             mNode->outOfDate(mRenderItem);
00460     }
00461 
00462     IntPoint EditText::getViewOffset() const
00463     {
00464         return mViewOffset;
00465     }
00466 
00467     size_t EditText::getCursorPosition(const IntPoint& _point)
00468     {
00469         if (nullptr == mFont)
00470             return 0;
00471 
00472         if (mTextOutDate)
00473             updateRawData();
00474 
00475         IntPoint point = _point;
00476         point -= mCroppedParent->getAbsolutePosition();
00477         point += mViewOffset;
00478         point -= mCoord.point();
00479 
00480         return mTextView.getCursorPosition(point);
00481     }
00482 
00483     IntCoord EditText::getCursorCoord(size_t _position)
00484     {
00485         if (nullptr == mFont)
00486             return IntCoord();
00487 
00488         if (mTextOutDate)
00489             updateRawData();
00490 
00491         IntPoint point = mTextView.getCursorPoint(_position);
00492         point += mCroppedParent->getAbsolutePosition();
00493         point -= mViewOffset;
00494         point += mCoord.point();
00495 
00496         return IntCoord(point.left, point.top, 2, mFontHeight);
00497     }
00498 
00499     void EditText::setShiftText(bool _value)
00500     {
00501         if (mShiftText == _value)
00502             return;
00503         mShiftText = _value;
00504 
00505         if (nullptr != mNode)
00506             mNode->outOfDate(mRenderItem);
00507     }
00508 
00509     void EditText::setWordWrap(bool _value)
00510     {
00511         mWordWrap = _value;
00512         mTextOutDate = true;
00513 
00514         if (nullptr != mNode)
00515             mNode->outOfDate(mRenderItem);
00516     }
00517 
00518     void EditText::updateRawData()
00519     {
00520         if (nullptr == mFont)
00521             return;
00522         // сбрасывам флаги
00523         mTextOutDate = false;
00524 
00525         int width = -1;
00526         if (mWordWrap)
00527         {
00528             width = mCoord.width;
00529             // обрезать слова нужно по шарине, которую мы реально используем
00530             if (mIsAddCursorWidth)
00531                 width -= 2;
00532         }
00533 
00534         mTextView.update(mCaption, mFont, mFontHeight, mTextAlign, mVertexFormat, width);
00535     }
00536 
00537     void EditText::setStateData(IStateInfo* _data)
00538     {
00539         EditTextStateInfo* data = _data->castType<EditTextStateInfo>();
00540         if (!mManualColour && data->getColour() != Colour::Zero)
00541             _setTextColour(data->getColour());
00542         setShiftText(data->getShift());
00543     }
00544 
00545     void EditText::doRender()
00546     {
00547         if (nullptr == mFont)
00548             return;
00549         if (!mVisible || mEmptyView)
00550             return;
00551 
00552         bool _update = mRenderItem->getCurrentUpdate();
00553         if (_update)
00554             mTextOutDate = true;
00555 
00556         if (mTextOutDate)
00557             updateRawData();
00558 
00559         Vertex* vertex = mRenderItem->getCurrentVertexBuffer();
00560 
00561         const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
00562 
00563         // колличество отрисованных вершин
00564         size_t vertex_count = 0;
00565 
00566         // текущие цвета
00567         uint32 colour_current = mCurrentColourNative;
00568         uint32 colour = mCurrentColourNative;
00569         uint32 colour_inverse = mInverseColourNative;
00570         uint32 colour_shadow = mShadowColourNative;
00571 
00572         GlyphInfo* back_glyph = mFont->getGlyphInfo(mBackgroundNormal ? FontCodeType::Selected : FontCodeType::SelectedBack);
00573 
00574         const float vertex_z = info.maximumDepth;
00575 
00576         const VectorLineInfo& data = mTextView.getData();
00577 
00578         int left = - mViewOffset.left + mCoord.left;
00579         int top = - mViewOffset.top + mCoord.top;
00580         const int height = mFontHeight;
00581 
00582         size_t index = 0;
00583         for (VectorLineInfo::const_iterator line = data.begin(); line != data.end(); ++line)
00584         {
00585             left = line->offset - mViewOffset.left + mCoord.left;
00586             for (VectorCharInfo::const_iterator sim = line->simbols.begin(); sim != line->simbols.end(); ++sim)
00587             {
00588                 if (sim->isColour())
00589                 {
00590                     colour = sim->getColour() | (colour & 0xFF000000);
00591                     colour_inverse = colour ^ 0x00FFFFFF;
00592                     continue;
00593                 }
00594 
00595                 // смещение текстуры для фона
00596                 bool select = !((index >= mEndSelect) || (index < mStartSelect));
00597 
00598                 uint32 back_colour = 0;
00599 
00600                 // выделение символа
00601                 if (!select || !mInvertSelect)
00602                 {
00603                     colour_current = colour;
00604                     back_colour = colour | 0x00FFFFFF;
00605                 }
00606                 else
00607                 {
00608                     colour_current = colour_inverse;
00609                     back_colour = colour_inverse;
00610                 }
00611 
00612                 if (mShadow)
00613                     drawSimbol(sim, info, back_glyph, vertex, vertex_z, IntPoint(left + 1, top + 1), false, colour_shadow, 0, vertex_count);
00614 
00615                 drawSimbol(sim, info, back_glyph, vertex, vertex_z, IntPoint(left, top), select, colour_current, back_colour, vertex_count);
00616 
00617                 left += sim->getWidth();
00618                 index++;
00619             }
00620 
00621             top += height;
00622             index++;
00623         }
00624 
00625         if (mVisibleCursor)
00626             drawCursor(info, vertex, vertex_z, colour_current, vertex_count);
00627 
00628         // колличество реально отрисованных вершин
00629         mRenderItem->setLastVertexCount(vertex_count);
00630     }
00631 
00632     void EditText::setInvertSelected(bool _value)
00633     {
00634         if (mInvertSelect == _value)
00635             return;
00636         mInvertSelect = _value;
00637 
00638         if (nullptr != mNode)
00639             mNode->outOfDate(mRenderItem);
00640     }
00641 
00642     bool EditText::getInvertSelected() const
00643     {
00644         return mInvertSelect;
00645     }
00646 
00647     bool EditText::getShadow() const
00648     {
00649         return mShadow;
00650     }
00651 
00652     void EditText::setShadow(bool _value)
00653     {
00654         mShadow = _value;
00655         mTextOutDate = true;
00656 
00657         checkVertexSize();
00658 
00659         if (nullptr != mNode)
00660             mNode->outOfDate(mRenderItem);
00661     }
00662 
00663     void EditText::setShadowColour(const Colour& _value)
00664     {
00665         mShadowColour = _value;
00666         mShadowColourNative = texture_utility::toColourARGB(mShadowColour);
00667 
00668         texture_utility::convertColour(mShadowColourNative, mVertexFormat);
00669 
00670         mShadowColourNative = (mShadowColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00671 
00672         if (nullptr != mNode)
00673             mNode->outOfDate(mRenderItem);
00674     }
00675 
00676     const Colour& EditText::getShadowColour() const
00677     {
00678         return mShadowColour;
00679     }
00680 
00681     void EditText::drawQuad(
00682         Vertex*& _buff,
00683         const FloatRect& _vertexRect,
00684         float v_z,
00685         uint32 _colour,
00686         const FloatRect& _textureRect,
00687         size_t& _count) const
00688     {
00689         _buff[0].x = _vertexRect.left;
00690         _buff[0].y = _vertexRect.top;
00691         _buff[0].z = v_z;
00692         _buff[0].colour = _colour;
00693         _buff[0].u = _textureRect.left;
00694         _buff[0].v = _textureRect.top;
00695 
00696         _buff[1].x = _vertexRect.left;
00697         _buff[1].y = _vertexRect.bottom;
00698         _buff[1].z = v_z;
00699         _buff[1].colour = _colour;
00700         _buff[1].u = _textureRect.left;
00701         _buff[1].v = _textureRect.bottom;
00702 
00703         _buff[2].x = _vertexRect.right;
00704         _buff[2].y = _vertexRect.top;
00705         _buff[2].z = v_z;
00706         _buff[2].colour = _colour;
00707         _buff[2].u = _textureRect.right;
00708         _buff[2].v = _textureRect.top;
00709 
00710         _buff[3].x = _vertexRect.right;
00711         _buff[3].y = _vertexRect.top;
00712         _buff[3].z = v_z;
00713         _buff[3].colour = _colour;
00714         _buff[3].u = _textureRect.right;
00715         _buff[3].v = _textureRect.top;
00716 
00717         _buff[4].x = _vertexRect.left;
00718         _buff[4].y = _vertexRect.bottom;
00719         _buff[4].z = v_z;
00720         _buff[4].colour = _colour;
00721         _buff[4].u = _textureRect.left;
00722         _buff[4].v = _textureRect.bottom;
00723 
00724         _buff[5].x = _vertexRect.right;
00725         _buff[5].y = _vertexRect.bottom;
00726         _buff[5].z = v_z;
00727         _buff[5].colour = _colour;
00728         _buff[5].u = _textureRect.right;
00729         _buff[5].v = _textureRect.bottom;
00730 
00731         _buff += VERTEX_IN_QUAD;
00732         _count += VERTEX_IN_QUAD;
00733     }
00734 
00735     void EditText::drawCursor(
00736         const RenderTargetInfo& _info,
00737         Vertex*& _vertex,
00738         float _vertex_z,
00739         uint32 _colour,
00740         size_t& _vertex_count)
00741     {
00742         IntPoint point = mTextView.getCursorPoint(mCursorPosition);
00743         point -= mViewOffset;
00744         point += mCoord.point();
00745 
00746         bool draw = true;
00747 
00748         GlyphInfo* cursor_glyph = mFont->getGlyphInfo(FontCodeType::Cursor);
00749         FloatRect texture_rect = cursor_glyph->uvRect;
00750         int left = point.left;
00751         int top = point.top;
00752         const int width = 2;//cursor_glyph->width;
00753         const int height = mFontHeight;
00754 
00755         // конечные размеры
00756         int result_left = left;
00757         int result_top = top;
00758         int result_width = width;
00759         int result_height = height;
00760 
00761         // символ залазиет влево
00762         if (left < mCurrentCoord.left)
00763         {
00764             // символ вообще не виден
00765             if (left + width <= mCurrentCoord.left)
00766             {
00767                 draw = false;
00768             }
00769             // символ обрезан
00770             else
00771             {
00772                 result_left = mCurrentCoord.left;
00773                 result_width = width - (mCurrentCoord.left - left);
00774 
00775                 float texture_width = texture_rect.right - texture_rect.left;
00776                 texture_rect.left = texture_rect.right - (texture_width * (float)result_width / (float)width);
00777             }
00778         }
00779 
00780         // символ залазиет вправо
00781         if (left + width > mCurrentCoord.right())
00782         {
00783             // символ вообще не виден
00784             if (left >= mCurrentCoord.right())
00785             {
00786                 draw = false;
00787             }
00788             // символ обрезан
00789             else
00790             {
00791                 result_width = mCurrentCoord.right() - left;
00792 
00793                 float texture_width = texture_rect.right - texture_rect.left;
00794                 texture_rect.right = texture_rect.left + (texture_width * (float)result_width / (float)width);
00795             }
00796         }
00797 
00798         // символ залазиет вверх
00799         if (top < mCurrentCoord.top)
00800         {
00801             // символ вообще не виден
00802             if (top + height <= mCurrentCoord.top)
00803             {
00804                 draw = false;
00805             }
00806             // символ обрезан
00807             else
00808             {
00809                 result_top = mCurrentCoord.top;
00810                 result_height = height - (mCurrentCoord.top - top);
00811 
00812                 float texture_height = texture_rect.bottom - texture_rect.top;
00813                 texture_rect.top = texture_rect.bottom - (texture_height * (float)result_height / (float)height);
00814             }
00815         }
00816 
00817         // символ залазиет вниз
00818         if (top + height > mCurrentCoord.bottom())
00819         {
00820             // символ вообще не виден
00821             if (top >= mCurrentCoord.bottom())
00822             {
00823                 draw = false;
00824             }
00825             // символ обрезан
00826             else
00827             {
00828                 result_height = mCurrentCoord.bottom() - top;
00829 
00830                 float texture_height = texture_rect.bottom - texture_rect.top;
00831                 texture_rect.bottom = texture_rect.top + (texture_height * (float)result_height / (float)height);
00832             }
00833         }
00834 
00835         if (draw)
00836         {
00837             int pix_left = mCroppedParent->getAbsoluteLeft() - _info.leftOffset + result_left;
00838             int pix_top = mCroppedParent->getAbsoluteTop() - _info.topOffset + (mShiftText ? 1 : 0) + result_top;
00839 
00840             FloatRect vertexRect = FloatRect(
00841                 ((_info.pixScaleX * (float)(pix_left) + _info.hOffset) * 2) - 1,
00842                 - (((_info.pixScaleY * (float)(pix_top) + _info.vOffset) * 2) - 1),
00843                 ((_info.pixScaleX * (float)(pix_left + result_width) + _info.hOffset) * 2) - 1,
00844                 - (((_info.pixScaleY * (float)(pix_top + result_height) + _info.vOffset) * 2) - 1));
00845 
00846             drawQuad(_vertex, vertexRect, _vertex_z, _colour | 0x00FFFFFF, texture_rect, _vertex_count);
00847         }
00848     }
00849 
00850     void EditText::drawSimbol(
00851         VectorCharInfo::const_iterator _sim,
00852         const RenderTargetInfo& _info,
00853         GlyphInfo* _back_glyph,
00854         Vertex*& _vertex,
00855         float _vertex_z,
00856         const IntPoint& _point,
00857         bool _select,
00858         uint32 _colour,
00859         uint32 _back_colour,
00860         size_t& _vertex_count)
00861     {
00862         bool draw = true;
00863 
00864         // текущие размеры
00865         FloatRect texture_rect = _sim->getUVRect();
00866         const int width = _sim->getWidth();
00867         const int height = mFontHeight;
00868 
00869         // конечные размеры
00870         int result_left = _point.left;
00871         int result_top = _point.top;
00872         int result_right = _point.left + width;
00873         int result_bottom = _point.top + height;
00874 
00875         float texture_width = texture_rect.right - texture_rect.left;
00876         float texture_height = texture_rect.bottom - texture_rect.top;
00877 
00878         // символ залазиет влево
00879         if (_point.left < mCurrentCoord.left)
00880         {
00881             // символ вообще не виден
00882             if (_point.left + width <= mCurrentCoord.left)
00883             {
00884                 draw = false;
00885             }
00886             // символ обрезан
00887             else
00888             {
00889                 result_left = mCurrentCoord.left;
00890                 texture_rect.left += (texture_width * (float)(result_left - _point.left) / (float)width);
00891             }
00892         }
00893 
00894         // символ залазиет вправо
00895         if (_point.left + width > mCurrentCoord.right())
00896         {
00897             // символ вообще не виден
00898             if (_point.left >= mCurrentCoord.right())
00899             {
00900                 draw = false;
00901             }
00902             // символ обрезан
00903             else
00904             {
00905                 result_right = mCurrentCoord.right();
00906                 texture_rect.right -= (texture_width * (float)((_point.left + width) - result_right) / (float)width);
00907             }
00908         }
00909 
00910         // символ залазиет вверх
00911         if (_point.top < mCurrentCoord.top)
00912         {
00913             // символ вообще не виден
00914             if (_point.top + height <= mCurrentCoord.top)
00915             {
00916                 draw = false;
00917             }
00918             // символ обрезан
00919             else
00920             {
00921                 result_top = mCurrentCoord.top;
00922                 texture_rect.top += (texture_height * (float)(result_top - _point.top) / (float)height);
00923             }
00924         }
00925 
00926         // символ залазиет вниз
00927         if (_point.top + height > mCurrentCoord.bottom())
00928         {
00929             // символ вообще не виден
00930             if (_point.top >= mCurrentCoord.bottom())
00931             {
00932                 draw = false;
00933             }
00934             // символ обрезан
00935             else
00936             {
00937                 result_bottom = mCurrentCoord.bottom();
00938                 texture_rect.bottom -= (texture_height * (float)((_point.top + height) - result_bottom) / (float)height);
00939             }
00940         }
00941 
00942         if (draw)
00943         {
00944             int pix_left = mCroppedParent->getAbsoluteLeft() - _info.leftOffset + result_left;
00945             int pix_top = mCroppedParent->getAbsoluteTop() - _info.topOffset + (mShiftText ? 1 : 0) + result_top;
00946 
00947             FloatRect vertexRect = FloatRect(
00948                 ((_info.pixScaleX * (float)(pix_left) + _info.hOffset) * 2) - 1,
00949                 - (((_info.pixScaleY * (float)(pix_top) + _info.vOffset) * 2) - 1),
00950                 ((_info.pixScaleX * (float)(pix_left + result_right - result_left) + _info.hOffset) * 2) - 1,
00951                 - (((_info.pixScaleY * (float)(pix_top + result_bottom - result_top) + _info.vOffset) * 2) - 1));
00952 
00953             // если нужно рисуем выделение
00954             if (_select)
00955             {
00956                 FloatRect background_current = FloatRect(
00957                     _back_glyph->uvRect.left,
00958                     _back_glyph->uvRect.top,
00959                     _back_glyph->uvRect.left,
00960                     _back_glyph->uvRect.top);
00961                 drawQuad(_vertex, vertexRect, _vertex_z, _back_colour, background_current, _vertex_count);
00962             }
00963 
00964             drawQuad(_vertex, vertexRect, _vertex_z, _colour, texture_rect, _vertex_count);
00965         }
00966     }
00967 
00968 } // namespace MyGUI