double MLIFont::GetHeight(const string &s) { EnsureUIThread(); CheckScale(); int w, h; TTF_SizeUTF8(pTtfFont, s.c_str(), &w, &h); return (double)h / GetFontScale(); }
MyGUI::IntSize EditText::getTextSize() const { // если нуно обновить, или изменились пропорции экрана if (mTextOutDate) const_cast<EditText*>(this)->updateRawData(); MyGUI::IntSize size = mTextView.getViewSize(); float scale = GetFontScale(); size.width = size.width * scale; size.height = size.height * scale; // плюс размер курсора if (mIsAddCursorWidth) size.width += 2; return size; }
size_t EditText::getCursorPosition(const MyGUI::IntPoint& _point) { if (nullptr == mFont) return 0; if (mTextOutDate) updateRawData(); MyGUI::IntPoint point = _point; point -= mCroppedParent->getAbsolutePosition(); point += mViewOffset; point -= mCoord.point(); float scale = GetFontScale(); point.left = point.left / scale; point.top = point.top / scale; return mTextView.getCursorPosition(point); }
MyGUI::IntCoord EditText::getCursorCoord(size_t _position) { if (nullptr == mFont) return MyGUI::IntCoord(); if (mTextOutDate) updateRawData(); MyGUI::IntPoint point = mTextView.getCursorPoint(_position); float scale = GetFontScale(); point.left *= scale; point.top *= scale; point += mCroppedParent->getAbsolutePosition(); point -= mViewOffset; point += mCoord.point(); return MyGUI::IntCoord(point.left, point.top, 2, mFontHeight); }
void EditText::doRender(MyGUI::IRenderTarget* _target) { if (nullptr == mFont || !mVisible || mEmptyView) return; if (mRenderItem->getCurrentUpdate() || mTextOutDate) updateRawData(); const TextData& textViewData = mTextView.getData(); Graphics& g = *(static_cast<RenderManager*>(MyGUI::RenderManager::getInstancePtr())->graphics()); Color c = g.GetColor(); g.SetColor(c * Color(1.0f,1.0f,1.0f,mAlpha)); float scale = GetFontScale(); float top = (-mViewOffset.top + mCoord.top) + mCroppedParent->getAbsoluteTop(); float left = ( - mViewOffset.left + mCoord.left) + mCroppedParent->getAbsoluteLeft(); Transform2d tr = g.GetTransform(); g.SetTransform(tr.translated(left, top).scale(scale)); mFont->Draw(g, &m_attributes, textViewData); if (mVisibleCursor) { MyGUI::IntPoint point = mTextView.getCursorPoint(mCursorPosition); const FontData::Glypth* cursorGlyph = mFont->GetGlyph(static_cast<MyGUI::Char>(MyGUI::FontCodeType::Cursor)); if (cursorGlyph) { g.DrawImage(cursorGlyph->img, &m_attributes, point.left, point.top); } } g.SetTransform(tr); g.SetColor(c); }
double MLIFont::GetWidth(const string &s) { EnsureUIThread(); CheckScale(); double x = 0; for (string::const_iterator it = s.begin(); it < s.end();) { uint32_t c = 0; if (!GetNextFromStringIterator(it, s.end(), &c)) { break; } Image *pGlyphImage = cache[c]; if (pGlyphImage == NULL) { continue; } double deltaX = pGlyphImage->width; if (it < s.end()) { uint32_t c2 = 0; if (PeekNextFromStringIterator(it, s.end(), &c2)) { deltaX = GetKernedWidth(c, c2); } } x += deltaX / GetFontScale(); } return x; }
double MLIFont::GetLineDescent() { EnsureUIThread(); CheckScale(); return (double)TTF_FontDescent(pTtfFont) / GetFontScale(); }
void MLIFont::DrawInternal(const string &s, Vector2 position, Color color, double scale, RectangleWH clipRect) { EnsureUIThread(); // If we're trying to draw an empty string, we can just return - // we're not gonna draw anything anyhow. if (s.length() == 0) { return; } CheckScale(); double x = position.GetX(); double y = position.GetY(); for (string::const_iterator it = s.begin(); it < s.end();) { uint32_t c = 0; if (!GetNextFromStringIterator(it, s.end(), &c)) { break; } Image *pGlyphImage = cache[c]; if (pGlyphImage == NULL) { continue; } RectangleWH characterClipRect(0, 0, pGlyphImage->width / GetFontScale(), pGlyphImage->height / GetFontScale()); RectangleWH originalCharacterClipRect = characterClipRect; if (clipRect.GetWidth() < 0 || clipRect.GetX() < originalCharacterClipRect.GetWidth()) { if (clipRect.GetWidth() >= 0) { if (clipRect.GetX() > 0) { characterClipRect.SetX(originalCharacterClipRect.GetX() + clipRect.GetX()); characterClipRect.SetWidth(originalCharacterClipRect.GetWidth() - clipRect.GetX()); } if (clipRect.GetWidth() < characterClipRect.GetWidth()) { characterClipRect.SetWidth(clipRect.GetWidth()); } if (clipRect.GetY() > 0) { characterClipRect.SetY(min(originalCharacterClipRect.GetY() + clipRect.GetY(), originalCharacterClipRect.GetY() + originalCharacterClipRect.GetHeight())); characterClipRect.SetHeight(originalCharacterClipRect.GetHeight() - (characterClipRect.GetY() - originalCharacterClipRect.GetY())); } if (clipRect.GetHeight() < characterClipRect.GetHeight()) { characterClipRect.SetHeight(clipRect.GetHeight()); } } if (characterClipRect.GetWidth() > 0 && characterClipRect.GetHeight() > 0) { characterClipRect.SetHeight(characterClipRect.GetHeight() * GetFontScale()); characterClipRect.SetWidth(characterClipRect.GetWidth() * GetFontScale()); pGlyphImage->Draw(Vector2(x, y), characterClipRect, false, false, scale, scale, color); } } double deltaX = pGlyphImage->width; if (it < s.end()) { uint32_t c2 = 0; if (PeekNextFromStringIterator(it, s.end(), &c2)) { deltaX = GetKernedWidth(c, c2); } } x += deltaX / GetFontScale(); } }
Image *MLIFont::RenderGlyph(uint32_t c) { EnsureUIThread(); CheckScale(); // render char SDL_Color whiteColor = {255, 255, 255, 255}; if (invertedColors) { whiteColor.b = 255 - whiteColor.b; whiteColor.g = 255 - whiteColor.g; whiteColor.a = 255 - whiteColor.a; } string utf8string; utf8::unchecked::append(c, back_inserter(utf8string)); SDL_Surface *pSurface = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), whiteColor); if (pSurface == NULL) { return NULL; } int scaledStrokeWidth = strokeWidth * GetFontScale() + 0.5; // render outlines if (strokeWidth > 0) { SDL_Color blackColor = {0, 0, 0, 255}; if (invertedColors) { blackColor.b = 255 - blackColor.b; blackColor.g = 255 - blackColor.g; blackColor.a = 255 - blackColor.a; } #ifndef MLI_SDL_FONT_OUTLINING SDL_Surface *pSurfaceOutline = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor); SDL_Surface *pSurfaceOutlinedText = SDL_CreateRGBSurface( 0, pSurface->w + scaledStrokeWidth * 2, pSurface->h + scaledStrokeWidth * 2, pSurface->format->BitsPerPixel, pSurface->format->Rmask, pSurface->format->Gmask, pSurface->format->Bmask, pSurface->format->Amask); SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND); SDL_Rect dstRect = {0, 0, pSurface->w, pSurface->h}; for (dstRect.x = 0; dstRect.x <= scaledStrokeWidth * 2; dstRect.x++) { for (dstRect.y = 0; dstRect.y <= scaledStrokeWidth * 2; dstRect.y++) { SDL_BlitSurface(pSurfaceOutline, NULL, pSurfaceOutlinedText, &dstRect); } } dstRect.x = scaledStrokeWidth; dstRect.y = scaledStrokeWidth; SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND); SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect); SDL_FreeSurface(pSurface); SDL_FreeSurface(pSurfaceOutline); pSurface = pSurfaceOutlinedText; #else TTF_SetFontOutline(pTtfFont, scaledStrokeWidth); SDL_Surface *pSurfaceOutlinedText = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor); SDL_SetSurfaceBlendMode(pSurfaceOutlinedText, SDL_BLENDMODE_BLEND); SDL_Rect dstRect = {scaledStrokeWidth, scaledStrokeWidth, pSurface->w, pSurface->h}; SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect); SDL_FreeSurface(pSurface); pSurface = pSurfaceOutlinedText; TTF_SetFontOutline(pTtfFont, 0); #endif } // create image Image *pImage = Image::Load(pSurface, true); pImage->FlagFontSource(this); pImage->SetUseScreenScaling(false); return pImage; }