MyGUI
3.2.0
|
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