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