MyGUI  3.2.1
MyGUI_EditText.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #include "MyGUI_Precompiled.h"
00008 #include "MyGUI_EditText.h"
00009 #include "MyGUI_RenderItem.h"
00010 #include "MyGUI_FontManager.h"
00011 #include "MyGUI_RenderManager.h"
00012 #include "MyGUI_LanguageManager.h"
00013 #include "MyGUI_TextIterator.h"
00014 #include "MyGUI_IRenderTarget.h"
00015 #include "MyGUI_FontData.h"
00016 #include "MyGUI_CommonStateInfo.h"
00017 
00018 namespace MyGUI
00019 {
00020 
00021     const size_t VERTEX_IN_QUAD = 6;
00022     const size_t SIMPLETEXT_COUNT_VERTEX = 32 * VERTEX_IN_QUAD;
00023 
00024     EditText::EditText() :
00025         ISubWidgetText(),
00026         mEmptyView(false),
00027         mCurrentColourNative(0x00FFFFFF),
00028         mInverseColourNative(0x00000000),
00029         mCurrentAlphaNative(0xFF000000),
00030         mShadowColourNative(0x00000000),
00031         mTextOutDate(false),
00032         mTextAlign(Align::Default),
00033         mColour(Colour::White),
00034         mShadowColour(Colour::Black),
00035         mAlpha(ALPHA_MAX),
00036         mFont(nullptr),
00037         mTexture(nullptr),
00038         mFontHeight(0),
00039         mBackgroundNormal(true),
00040         mStartSelect(0),
00041         mEndSelect(0),
00042         mCursorPosition(0),
00043         mVisibleCursor(false),
00044         mInvertSelect(true),
00045         mShadow(false),
00046         mNode(nullptr),
00047         mRenderItem(nullptr),
00048         mCountVertex(SIMPLETEXT_COUNT_VERTEX),
00049         mIsAddCursorWidth(true),
00050         mShiftText(false),
00051         mWordWrap(false),
00052         mManualColour(false),
00053         mOldWidth(0)
00054     {
00055         mVertexFormat = RenderManager::getInstance().getVertexFormat();
00056 
00057         mCurrentColourNative = texture_utility::toColourARGB(mColour);
00058         texture_utility::convertColour(mCurrentColourNative, mVertexFormat);
00059 
00060         mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00061         mShadowColourNative =  (mShadowColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00062         mInverseColourNative = mCurrentColourNative ^ 0x00FFFFFF;
00063     }
00064 
00065     EditText::~EditText()
00066     {
00067     }
00068 
00069     void EditText::setVisible(bool _visible)
00070     {
00071         if (mVisible == _visible)
00072             return;
00073         mVisible = _visible;
00074 
00075         if (nullptr != mNode)
00076             mNode->outOfDate(mRenderItem);
00077     }
00078 
00079     void EditText::_correctView()
00080     {
00081         if (nullptr != mNode)
00082             mNode->outOfDate(mRenderItem);
00083     }
00084 
00085     void EditText::_setAlign(const IntSize& _oldsize)
00086     {
00087         if (mWordWrap)
00088         {
00089             // передается старая координата всегда
00090             int width = mCroppedParent->getWidth();
00091             if (mOldWidth != width)
00092             {
00093                 mOldWidth = width;
00094                 mTextOutDate = true;
00095             }
00096         }
00097 
00098         // необходимо разобраться
00099         bool need_update = true;//_update;
00100 
00101         // первоначальное выравнивание
00102         if (mAlign.isHStretch())
00103         {
00104             // растягиваем
00105             mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
00106             need_update = true;
00107             mIsMargin = true; // при изменении размеров все пересчитывать
00108         }
00109         else if (mAlign.isRight())
00110         {
00111             // двигаем по правому краю
00112             mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
00113             need_update = true;
00114         }
00115         else if (mAlign.isHCenter())
00116         {
00117             // выравнивание по горизонтали без растяжения
00118             mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
00119             need_update = true;
00120         }
00121 
00122         if (mAlign.isVStretch())
00123         {
00124             // растягиваем
00125             mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
00126             need_update = true;
00127             mIsMargin = true; // при изменении размеров все пересчитывать
00128         }
00129         else if (mAlign.isBottom())
00130         {
00131             // двигаем по нижнему краю
00132             mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
00133             need_update = true;
00134         }
00135         else if (mAlign.isVCenter())
00136         {
00137             // выравнивание по вертикали без растяжения
00138             mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
00139             need_update = true;
00140         }
00141 
00142         if (need_update)
00143         {
00144             mCurrentCoord = mCoord;
00145             _updateView();
00146         }
00147     }
00148 
00149     void EditText::_updateView()
00150     {
00151         bool margin = _checkMargin();
00152 
00153         mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
00154 
00155         mCurrentCoord.left = mCoord.left + mMargin.left;
00156         mCurrentCoord.top = mCoord.top + mMargin.top;
00157 
00158         // вьюпорт стал битым
00159         if (margin)
00160         {
00161             // проверка на полный выход за границу
00162             if (_checkOutside())
00163             {
00164                 // запоминаем текущее состояние
00165                 mIsMargin = margin;
00166 
00167                 // обновить перед выходом
00168                 if (nullptr != mNode)
00169                     mNode->outOfDate(mRenderItem);
00170                 return;
00171             }
00172         }
00173 
00174         // мы обрезаны или были обрезаны
00175         if (mIsMargin || margin)
00176         {
00177             mCurrentCoord.width = _getViewWidth();
00178             mCurrentCoord.height = _getViewHeight();
00179         }
00180 
00181         // запоминаем текущее состояние
00182         mIsMargin = margin;
00183 
00184         if (nullptr != mNode)
00185             mNode->outOfDate(mRenderItem);
00186     }
00187 
00188     void EditText::setCaption(const UString& _value)
00189     {
00190         mCaption = _value;
00191         mTextOutDate = true;
00192 
00193         checkVertexSize();
00194 
00195         if (nullptr != mNode)
00196             mNode->outOfDate(mRenderItem);
00197     }
00198 
00199     void EditText::checkVertexSize()
00200     {
00201         // если вершин не хватит, делаем реалок, с учетом выделения * 2 и курсора
00202         size_t need = (mCaption.size() * (mShadow ? 3 : 2) + 2) * VERTEX_IN_QUAD;
00203         if (mCountVertex < need)
00204         {
00205             mCountVertex = need + SIMPLETEXT_COUNT_VERTEX;
00206             if (nullptr != mRenderItem)
00207                 mRenderItem->reallockDrawItem(this, mCountVertex);
00208         }
00209     }
00210 
00211     const UString& EditText::getCaption() const
00212     {
00213         return mCaption;
00214     }
00215 
00216     void EditText::setTextColour(const Colour& _value)
00217     {
00218         mManualColour = true;
00219         _setTextColour(_value);
00220     }
00221 
00222     void EditText::_setTextColour(const Colour& _value)
00223     {
00224         if (mColour == _value)
00225             return;
00226 
00227         mColour = _value;
00228         mCurrentColourNative = texture_utility::toColourARGB(mColour);
00229 
00230         texture_utility::convertColour(mCurrentColourNative, mVertexFormat);
00231 
00232         mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00233         mInverseColourNative = mCurrentColourNative ^ 0x00FFFFFF;
00234 
00235         if (nullptr != mNode)
00236             mNode->outOfDate(mRenderItem);
00237     }
00238 
00239     const Colour& EditText::getTextColour() const
00240     {
00241         return mColour;
00242     }
00243 
00244     void EditText::setAlpha(float _value)
00245     {
00246         if (mAlpha == _value)
00247             return;
00248         mAlpha = _value;
00249 
00250         mCurrentAlphaNative = ((uint8)(mAlpha * 255) << 24);
00251         mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00252         mShadowColourNative = (mShadowColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00253         mInverseColourNative = mCurrentColourNative ^ 0x00FFFFFF;
00254 
00255         if (nullptr != mNode)
00256             mNode->outOfDate(mRenderItem);
00257     }
00258 
00259     float EditText::getAlpha() const
00260     {
00261         return mAlpha;
00262     }
00263 
00264     void EditText::setFontName(const std::string& _value)
00265     {
00266         mTexture = 0;
00267         mFont = FontManager::getInstance().getByName(_value);
00268         if (mFont != nullptr)
00269         {
00270             mTexture = mFont->getTextureFont();
00271 
00272             // если надо, устанавливаем дефолтный размер шрифта
00273             if (mFont->getDefaultHeight() != 0)
00274             {
00275                 mFontHeight = mFont->getDefaultHeight();
00276             }
00277         }
00278 
00279         mTextOutDate = true;
00280 
00281         // если мы были приаттаченны, то удаляем себя
00282         if (nullptr != mRenderItem)
00283         {
00284             mRenderItem->removeDrawItem(this);
00285             mRenderItem = nullptr;
00286         }
00287 
00288         // если есть текстура, то приаттачиваемся
00289         if (nullptr != mTexture && nullptr != mNode)
00290         {
00291             mRenderItem = mNode->addToRenderItem(mTexture, false, false);
00292             mRenderItem->addDrawItem(this, mCountVertex);
00293         }
00294 
00295         if (nullptr != mNode)
00296             mNode->outOfDate(mRenderItem);
00297     }
00298 
00299     const std::string& EditText::getFontName() const
00300     {
00301         return mFont->getResourceName();
00302     }
00303 
00304     void EditText::setFontHeight(int _value)
00305     {
00306         mFontHeight = _value;
00307         mTextOutDate = true;
00308 
00309         if (nullptr != mNode)
00310             mNode->outOfDate(mRenderItem);
00311     }
00312 
00313     int EditText::getFontHeight() const
00314     {
00315         return mFontHeight;
00316     }
00317 
00318     void EditText::createDrawItem(ITexture* _texture, ILayerNode* _node)
00319     {
00320         mNode = _node;
00321         // если уже есть текстура, то атачимся, актуально для смены леера
00322         if (nullptr != mTexture)
00323         {
00324             MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
00325 
00326             mRenderItem = mNode->addToRenderItem(mTexture, false, false);
00327             mRenderItem->addDrawItem(this, mCountVertex);
00328         }
00329     }
00330 
00331     void EditText::destroyDrawItem()
00332     {
00333         if (nullptr != mRenderItem)
00334         {
00335             mRenderItem->removeDrawItem(this);
00336             mRenderItem = nullptr;
00337         }
00338         mNode = nullptr;
00339     }
00340 
00341     size_t EditText::getTextSelectionStart() const
00342     {
00343         return mStartSelect;
00344     }
00345 
00346     size_t EditText::getTextSelectionEnd() const
00347     {
00348         return mEndSelect;
00349     }
00350 
00351     void EditText::setTextSelection(size_t _start, size_t _end)
00352     {
00353         mStartSelect = _start;
00354         mEndSelect = _end;
00355 
00356         if (nullptr != mNode)
00357             mNode->outOfDate(mRenderItem);
00358     }
00359 
00360     bool EditText::getSelectBackground() const
00361     {
00362         return mBackgroundNormal;
00363     }
00364 
00365     void EditText::setSelectBackground(bool _normal)
00366     {
00367         if (mBackgroundNormal == _normal)
00368             return;
00369         mBackgroundNormal = _normal;
00370 
00371         if (nullptr != mNode)
00372             mNode->outOfDate(mRenderItem);
00373     }
00374 
00375     bool EditText::isVisibleCursor() const
00376     {
00377         return mVisibleCursor;
00378     }
00379 
00380     void EditText::setVisibleCursor(bool _value)
00381     {
00382         if (mVisibleCursor == _value)
00383             return;
00384         mVisibleCursor = _value;
00385 
00386         if (nullptr != mNode)
00387             mNode->outOfDate(mRenderItem);
00388     }
00389 
00390     size_t EditText::getCursorPosition() const
00391     {
00392         return mCursorPosition;
00393     }
00394 
00395     void EditText::setCursorPosition(size_t _index)
00396     {
00397         if (mCursorPosition == _index)
00398             return;
00399         mCursorPosition = _index;
00400 
00401         if (nullptr != mNode)
00402             mNode->outOfDate(mRenderItem);
00403     }
00404 
00405     void EditText::setTextAlign(Align _value)
00406     {
00407         mTextAlign = _value;
00408 
00409         if (nullptr != mNode)
00410             mNode->outOfDate(mRenderItem);
00411     }
00412 
00413     Align EditText::getTextAlign() const
00414     {
00415         return mTextAlign;
00416     }
00417 
00418     IntSize EditText::getTextSize()
00419     {
00420         // если нуно обновить, или изменились пропорции экрана
00421         if (mTextOutDate)
00422             updateRawData();
00423 
00424         IntSize size = mTextView.getViewSize();
00425         // плюс размер курсора
00426         if (mIsAddCursorWidth)
00427             size.width += 2;
00428 
00429         if (mShadow)
00430         {
00431             if (!mIsAddCursorWidth)
00432                 size.width ++;
00433             size.height ++;
00434         }
00435 
00436         return size;
00437     }
00438 
00439     const VectorLineInfo& EditText::getLineInfo() const
00440     {
00441         return mTextView.getData();
00442     }
00443 
00444     void EditText::setViewOffset(const IntPoint& _point)
00445     {
00446         mViewOffset = _point;
00447 
00448         if (nullptr != mNode)
00449             mNode->outOfDate(mRenderItem);
00450     }
00451 
00452     IntPoint EditText::getViewOffset() const
00453     {
00454         return mViewOffset;
00455     }
00456 
00457     size_t EditText::getCursorPosition(const IntPoint& _point)
00458     {
00459         if (nullptr == mFont)
00460             return 0;
00461 
00462         if (mTextOutDate)
00463             updateRawData();
00464 
00465         IntPoint point = _point;
00466         point -= mCroppedParent->getAbsolutePosition();
00467         point += mViewOffset;
00468         point -= mCoord.point();
00469 
00470         return mTextView.getCursorPosition(point);
00471     }
00472 
00473     IntCoord EditText::getCursorCoord(size_t _position)
00474     {
00475         if (nullptr == mFont)
00476             return IntCoord();
00477 
00478         if (mTextOutDate)
00479             updateRawData();
00480 
00481         IntPoint point = mTextView.getCursorPoint(_position);
00482         point += mCroppedParent->getAbsolutePosition();
00483         point -= mViewOffset;
00484         point += mCoord.point();
00485 
00486         return IntCoord(point.left, point.top, 2, mFontHeight);
00487     }
00488 
00489     void EditText::setShiftText(bool _value)
00490     {
00491         if (mShiftText == _value)
00492             return;
00493         mShiftText = _value;
00494 
00495         if (nullptr != mNode)
00496             mNode->outOfDate(mRenderItem);
00497     }
00498 
00499     void EditText::setWordWrap(bool _value)
00500     {
00501         mWordWrap = _value;
00502         mTextOutDate = true;
00503 
00504         if (nullptr != mNode)
00505             mNode->outOfDate(mRenderItem);
00506     }
00507 
00508     void EditText::updateRawData()
00509     {
00510         if (nullptr == mFont)
00511             return;
00512         // сбрасывам флаги
00513         mTextOutDate = false;
00514 
00515         int width = -1;
00516         if (mWordWrap)
00517         {
00518             width = mCoord.width;
00519             // обрезать слова нужно по шарине, которую мы реально используем
00520             if (mIsAddCursorWidth)
00521                 width -= 2;
00522         }
00523 
00524         mTextView.update(mCaption, mFont, mFontHeight, mTextAlign, mVertexFormat, width);
00525     }
00526 
00527     void EditText::setStateData(IStateInfo* _data)
00528     {
00529         EditTextStateInfo* data = _data->castType<EditTextStateInfo>();
00530         if (!mManualColour && data->getColour() != Colour::Zero)
00531             _setTextColour(data->getColour());
00532         setShiftText(data->getShift());
00533     }
00534 
00535     void EditText::doRender()
00536     {
00537         if (nullptr == mFont || !mVisible || mEmptyView)
00538             return;
00539 
00540         if (mRenderItem->getCurrentUpdate() || mTextOutDate)
00541             updateRawData();
00542 
00543         Vertex* vertex = mRenderItem->getCurrentVertexBuffer();
00544 
00545         const RenderTargetInfo& renderTargetInfo = mRenderItem->getRenderTarget()->getInfo();
00546 
00547         // колличество отрисованных вершин
00548         size_t vertexCount = 0;
00549 
00550         // текущие цвета
00551         uint32 colour = mCurrentColourNative;
00552         uint32 inverseColour = mInverseColourNative;
00553         uint32 selectedColour = mInvertSelect ? inverseColour : colour | 0x00FFFFFF;
00554 
00555         const VectorLineInfo& textViewData = mTextView.getData();
00556 
00557         float top = (float)(-mViewOffset.top + mCoord.top);
00558 
00559         FloatRect vertexRect;
00560 
00561         const FloatRect& selectedUVRect = mFont->getGlyphInfo(mBackgroundNormal ? FontCodeType::Selected : FontCodeType::SelectedBack)->uvRect;
00562 
00563         size_t index = 0;
00564 
00565         for (VectorLineInfo::const_iterator line = textViewData.begin(); line != textViewData.end(); ++line)
00566         {
00567             float left = (float)(line->offset - mViewOffset.left + mCoord.left);
00568 
00569             for (VectorCharInfo::const_iterator sim = line->simbols.begin(); sim != line->simbols.end(); ++sim)
00570             {
00571                 if (sim->isColour())
00572                 {
00573                     colour = sim->getColour() | (colour & 0xFF000000);
00574                     inverseColour = colour ^ 0x00FFFFFF;
00575                     selectedColour = mInvertSelect ? inverseColour : colour | 0x00FFFFFF;
00576                     continue;
00577                 }
00578 
00579                 // смещение текстуры для фона
00580                 bool select = index >= mStartSelect && index < mEndSelect;
00581 
00582                 float fullAdvance = sim->getBearingX() + sim->getAdvance();
00583 
00584                 // Render the selection, if any, first.
00585                 if (select)
00586                 {
00587                     vertexRect.set(left, top, left + fullAdvance, top + (float)mFontHeight);
00588 
00589                     drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, selectedUVRect, selectedColour);
00590                 }
00591 
00592                 // Render the glyph shadow, if any.
00593                 if (mShadow)
00594                 {
00595                     vertexRect.left = left + sim->getBearingX() + 1.0f;
00596                     vertexRect.top = top + sim->getBearingY() + 1.0f;
00597                     vertexRect.right = vertexRect.left + sim->getWidth();
00598                     vertexRect.bottom = vertexRect.top + sim->getHeight();
00599 
00600                     drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, sim->getUVRect(), mShadowColourNative);
00601                 }
00602 
00603                 // Render the glyph itself.
00604                 vertexRect.left = left + sim->getBearingX();
00605                 vertexRect.top = top + sim->getBearingY();
00606                 vertexRect.right = vertexRect.left + sim->getWidth();
00607                 vertexRect.bottom = vertexRect.top + sim->getHeight();
00608 
00609                 drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, sim->getUVRect(), (!select || !mInvertSelect) ? colour : inverseColour);
00610 
00611                 left += fullAdvance;
00612                 ++index;
00613             }
00614 
00615             top += mFontHeight;
00616             ++index;
00617         }
00618 
00619         // Render the cursor, if any, last.
00620         if (mVisibleCursor)
00621         {
00622             IntPoint point = mTextView.getCursorPoint(mCursorPosition) - mViewOffset + mCoord.point();
00623             GlyphInfo* cursorGlyph = mFont->getGlyphInfo(static_cast<Char>(FontCodeType::Cursor));
00624             vertexRect.set((float)point.left, (float)point.top, (float)point.left + cursorGlyph->width, (float)(point.top + mFontHeight));
00625 
00626             drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, cursorGlyph->uvRect, mCurrentColourNative | 0x00FFFFFF);
00627         }
00628 
00629         // колличество реально отрисованных вершин
00630         mRenderItem->setLastVertexCount(vertexCount);
00631     }
00632 
00633     void EditText::setInvertSelected(bool _value)
00634     {
00635         if (mInvertSelect == _value)
00636             return;
00637         mInvertSelect = _value;
00638 
00639         if (nullptr != mNode)
00640             mNode->outOfDate(mRenderItem);
00641     }
00642 
00643     bool EditText::getInvertSelected() const
00644     {
00645         return mInvertSelect;
00646     }
00647 
00648     bool EditText::getShadow() const
00649     {
00650         return mShadow;
00651     }
00652 
00653     void EditText::setShadow(bool _value)
00654     {
00655         mShadow = _value;
00656         mTextOutDate = true;
00657 
00658         checkVertexSize();
00659 
00660         if (nullptr != mNode)
00661             mNode->outOfDate(mRenderItem);
00662     }
00663 
00664     void EditText::setShadowColour(const Colour& _value)
00665     {
00666         mShadowColour = _value;
00667         mShadowColourNative = texture_utility::toColourARGB(mShadowColour);
00668 
00669         texture_utility::convertColour(mShadowColourNative, mVertexFormat);
00670 
00671         mShadowColourNative = (mShadowColourNative & 0x00FFFFFF) | (mCurrentAlphaNative & 0xFF000000);
00672 
00673         if (nullptr != mNode)
00674             mNode->outOfDate(mRenderItem);
00675     }
00676 
00677     const Colour& EditText::getShadowColour() const
00678     {
00679         return mShadowColour;
00680     }
00681 
00682     void EditText::drawQuad(
00683         Vertex*& _vertex,
00684         size_t& _vertexCount,
00685         const FloatRect& _vertexRect,
00686         float _vertexZ,
00687         const FloatRect& _textureRect,
00688         uint32 _colour) const
00689     {
00690         _vertex[0].x = _vertexRect.left;
00691         _vertex[0].y = _vertexRect.top;
00692         _vertex[0].z = _vertexZ;
00693         _vertex[0].colour = _colour;
00694         _vertex[0].u = _textureRect.left;
00695         _vertex[0].v = _textureRect.top;
00696 
00697         _vertex[2].x = _vertexRect.left;
00698         _vertex[2].y = _vertexRect.bottom;
00699         _vertex[2].z = _vertexZ;
00700         _vertex[2].colour = _colour;
00701         _vertex[2].u = _textureRect.left;
00702         _vertex[2].v = _textureRect.bottom;
00703 
00704         _vertex[1].x = _vertexRect.right;
00705         _vertex[1].y = _vertexRect.top;
00706         _vertex[1].z = _vertexZ;
00707         _vertex[1].colour = _colour;
00708         _vertex[1].u = _textureRect.right;
00709         _vertex[1].v = _textureRect.top;
00710 
00711         _vertex[3].x = _vertexRect.right;
00712         _vertex[3].y = _vertexRect.top;
00713         _vertex[3].z = _vertexZ;
00714         _vertex[3].colour = _colour;
00715         _vertex[3].u = _textureRect.right;
00716         _vertex[3].v = _textureRect.top;
00717 
00718         _vertex[5].x = _vertexRect.left;
00719         _vertex[5].y = _vertexRect.bottom;
00720         _vertex[5].z = _vertexZ;
00721         _vertex[5].colour = _colour;
00722         _vertex[5].u = _textureRect.left;
00723         _vertex[5].v = _textureRect.bottom;
00724 
00725         _vertex[4].x = _vertexRect.right;
00726         _vertex[4].y = _vertexRect.bottom;
00727         _vertex[4].z = _vertexZ;
00728         _vertex[4].colour = _colour;
00729         _vertex[4].u = _textureRect.right;
00730         _vertex[4].v = _textureRect.bottom;
00731 
00732         _vertex += VERTEX_IN_QUAD;
00733         _vertexCount += VERTEX_IN_QUAD;
00734     }
00735 
00736     void EditText::drawGlyph(
00737         const RenderTargetInfo& _renderTargetInfo,
00738         Vertex*& _vertex,
00739         size_t& _vertexCount,
00740         FloatRect _vertexRect,
00741         FloatRect _textureRect,
00742         uint32 _colour) const
00743     {
00744         // символ залазиет влево
00745         float leftClip = (float)mCurrentCoord.left - _vertexRect.left;
00746         if (leftClip > 0.0f)
00747         {
00748             if ((float)mCurrentCoord.left < _vertexRect.right)
00749             {
00750                 _textureRect.left += _textureRect.width() * leftClip / _vertexRect.width();
00751                 _vertexRect.left += leftClip;
00752             }
00753             else
00754             {
00755                 return;
00756             }
00757         }
00758 
00759         // символ залазиет вправо
00760         float rightClip = _vertexRect.right - (float)mCurrentCoord.right();
00761         if (rightClip > 0.0f)
00762         {
00763             if (_vertexRect.left < (float)mCurrentCoord.right())
00764             {
00765                 _textureRect.right -= _textureRect.width() * rightClip / _vertexRect.width();
00766                 _vertexRect.right -= rightClip;
00767             }
00768             else
00769             {
00770                 return;
00771             }
00772         }
00773 
00774         // символ залазиет вверх
00775         float topClip = (float)mCurrentCoord.top - _vertexRect.top;
00776         if (topClip > 0.0f)
00777         {
00778             if ((float)mCurrentCoord.top < _vertexRect.bottom)
00779             {
00780                 _textureRect.top += _textureRect.height() * topClip / _vertexRect.height();
00781                 _vertexRect.top += topClip;
00782             }
00783             else
00784             {
00785                 return;
00786             }
00787         }
00788 
00789         // символ залазиет вниз
00790         float bottomClip = _vertexRect.bottom - (float)mCurrentCoord.bottom();
00791         if (bottomClip > 0.0f)
00792         {
00793             if (_vertexRect.top < (float)mCurrentCoord.bottom())
00794             {
00795                 _textureRect.bottom -= _textureRect.height() * bottomClip / _vertexRect.height();
00796                 _vertexRect.bottom -= bottomClip;
00797             }
00798             else
00799             {
00800                 return;
00801             }
00802         }
00803 
00804         float pix_left = mCroppedParent->getAbsoluteLeft() - _renderTargetInfo.leftOffset + _vertexRect.left;
00805         float pix_top = mCroppedParent->getAbsoluteTop() - _renderTargetInfo.topOffset + (mShiftText ? 1.0f : 0.0f) + _vertexRect.top;
00806 
00807         FloatRect vertexRect(
00808             ((_renderTargetInfo.pixScaleX * pix_left + _renderTargetInfo.hOffset) * 2.0f) - 1.0f,
00809             -(((_renderTargetInfo.pixScaleY * pix_top + _renderTargetInfo.vOffset) * 2.0f) - 1.0f),
00810             ((_renderTargetInfo.pixScaleX * (pix_left + _vertexRect.width()) + _renderTargetInfo.hOffset) * 2.0f) - 1.0f,
00811             -(((_renderTargetInfo.pixScaleY * (pix_top + _vertexRect.height()) + _renderTargetInfo.vOffset) * 2.0f) - 1.0f));
00812 
00813         drawQuad(_vertex, _vertexCount, vertexRect, mNode->getNodeDepth(), _textureRect, _colour);
00814     }
00815 
00816 } // namespace MyGUI