From 034e3653d8559277b83879027d124efdefbc8961 Mon Sep 17 00:00:00 2001 From: pssea Date: Fri, 10 Jun 2022 17:07:53 +0800 Subject: [PATCH] Description: optimize font render performance IssueNo: https://gitee.com/openharmony/graphic_ui/issues/I5BQNP Feature or Bugfix: Feature Binary Source:No Signed-off-by: lizhiqi --- frameworks/common/text.cpp | 28 +++++++++++++++++------- frameworks/common/typed_text.cpp | 28 +++++++++++++++++++++++- frameworks/draw/draw_label.cpp | 35 +++++++++++++++++------------- frameworks/draw/draw_utils.cpp | 26 +++++++++------------- frameworks/draw/draw_utils.h | 11 ++++++++-- frameworks/font/glyphs_manager.cpp | 5 ----- frameworks/font/ui_font_bitmap.cpp | 15 +++++-------- frameworks/font/ui_line_break.cpp | 7 +----- 8 files changed, 92 insertions(+), 63 deletions(-) diff --git a/frameworks/common/text.cpp b/frameworks/common/text.cpp index 9de9faf..f653bb9 100644 --- a/frameworks/common/text.cpp +++ b/frameworks/common/text.cpp @@ -288,11 +288,18 @@ void Text::Draw(BufferInfo& gfxDstBuffer, uint32_t maxLineBytes = 0; uint16_t lineCount = GetLine(lineMaxWidth, style.letterSpace_, ellipsisIndex, maxLineBytes); int16_t lineHeight = style.lineHeight_; + int16_t curLineHeight; if (lineHeight == 0) { + lineHeight = UIFont::GetInstance()->GetHeight(fontId_, fontSize_); + lineHeight += style.lineSpace_; + } + if ((style.lineSpace_ == 0) && (sizeSpans_ != nullptr)) { uint16_t letterIndex = 0; - int16_t lineMaxHeight = UIFont::GetInstance()->GetLineMaxHeight(text_, textLine_[0].lineBytes, fontId_, - fontSize_, letterIndex, sizeSpans_); - lineHeight = lineMaxHeight + style.lineSpace_; + curLineHeight = UIFont::GetInstance()->GetLineMaxHeight(text_, textLine_[0].lineBytes, fontId_, fontSize_, + letterIndex, sizeSpans_); + curLineHeight += style.lineSpace_; + } else { + curLineHeight = lineHeight; } Point pos; if (lineHeight == style.lineHeight_) { @@ -306,14 +313,14 @@ void Text::Draw(BufferInfo& gfxDstBuffer, if (pos.y > mask.GetBottom()) { return; } - int16_t nextLine = pos.y + lineHeight; + int16_t nextLine = pos.y + curLineHeight; if (lineHeight != style.lineHeight_) { nextLine -= style.lineSpace_; } int16_t tempLetterIndex = letterIndex; if (nextLine >= mask.GetTop()) { pos.x = LineStartPos(coords, textLine_[i].linePixelWidth); - LabelLineInfo labelLine{pos, offset, mask, lineHeight, textLine_[i].lineBytes, + LabelLineInfo labelLine{pos, offset, mask, curLineHeight, textLine_[i].lineBytes, 0, opa, style, &text_[lineBegin], textLine_[i].lineBytes, lineBegin, fontId_, fontSize_, 0, static_cast(direct_), nullptr, baseLine_, @@ -330,10 +337,15 @@ void Text::Draw(BufferInfo& gfxDstBuffer, } else { letterIndex = TypedText::GetUTF8CharacterSize(text_, lineBegin + textLine_[i].lineBytes); } - lineHeight = UIFont::GetInstance()->GetLineMaxHeight(&text_[lineBegin], textLine_[i].lineBytes, fontId_, - fontSize_, tempLetterIndex, sizeSpans_); + if ((style.lineSpace_ == 0) && (sizeSpans_ != nullptr)) { + curLineHeight = UIFont::GetInstance()->GetLineMaxHeight(&text_[lineBegin], textLine_[i].lineBytes, fontId_, + fontSize_, tempLetterIndex, sizeSpans_); + curLineHeight += style.lineSpace_; + } else { + curLineHeight = lineHeight; + } lineBegin += textLine_[i].lineBytes; - pos.y += lineHeight + style.lineSpace_; + pos.y += curLineHeight; } } diff --git a/frameworks/common/typed_text.cpp b/frameworks/common/typed_text.cpp index dcd38c6..809d165 100644 --- a/frameworks/common/typed_text.cpp +++ b/frameworks/common/typed_text.cpp @@ -19,6 +19,9 @@ #include "gfx_utils/graphic_log.h" #include "gfx_utils/mem_api.h" #include "gfx_utils/transform.h" +#if ENABLE_MULTI_FONT +#include "font/ui_multi_font_manager.h" +#endif namespace OHOS { #ifndef _FONT_TOOL @@ -457,6 +460,29 @@ bool TypedText::IsEmojiBase(uint32_t codePoint) bool TypedText::IsColourWord(uint32_t codePoint, uint8_t fontId, uint8_t fontSize) { + bool hasColor = false; + uint8_t weight = UIFont::GetInstance()->GetFontWeight(fontId); + if (weight >= 16) { // 16: rgb565->16 rgba8888->32 font with rgba + hasColor = true; + } else { +#if ENABLE_MULTI_FONT + uint8_t* searchLists = nullptr; + int8_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists); + int8_t currentIndex = 0; + if ((listSize > 0) && (searchLists != nullptr)) { + do { + weight = UIFont::GetInstance()->GetFontWeight(glyphNode.fontId); + if (weight >= 16) { // 16: rgb565->16 rgba8888->32 font with rgba + hasColor = true; + } + currentIndex++; + } while ((currentIndex < listSize) && (searchLists != nullptr)); + } +#endif + } + if (!hasColor) { + return false; + } GlyphNode glyphNode; int8_t ret = UIFont::GetInstance()->GetGlyphNode(codePoint, glyphNode, fontId, fontSize); if (ret != RET_VALUE_OK) { @@ -464,7 +490,7 @@ bool TypedText::IsColourWord(uint32_t codePoint, uint8_t fontId, uint8_t fontSiz return false; } - uint8_t weight = UIFont::GetInstance()->GetFontWeight(glyphNode.fontId); + weight = UIFont::GetInstance()->GetFontWeight(glyphNode.fontId); return (weight >= 16); // 16: rgb565->16 rgba8888->32 font with rgba } } // namespace OHOS diff --git a/frameworks/draw/draw_label.cpp b/frameworks/draw/draw_label.cpp index 1944759..ddee445 100644 --- a/frameworks/draw/draw_label.cpp +++ b/frameworks/draw/draw_label.cpp @@ -38,15 +38,14 @@ uint16_t DrawLabel::DrawTextOneLine(BufferInfo& gfxDstBuffer, const LabelLineInf uint32_t i = 0; uint32_t letter; - uint16_t letterWidth; uint16_t retOffsetY = 0; // ret value elipse offsetY - bool isEmoijLerge = true; uint16_t offsetPosY = 0; - offsetPosY = fontEngine->GetOffsetPosY(labelLine.text, labelLine.lineLength, isEmoijLerge, labelLine.fontId, - labelLine.fontSize); uint8_t maxLetterSize = GetLineMaxLetterSize(labelLine.text, labelLine.lineLength, labelLine.fontId, labelLine.fontSize, letterIndex, labelLine.sizeSpans); DrawLineBackgroundColor(gfxDstBuffer, letterIndex, labelLine); + GlyphNode glyphNode; + uint8_t* fontMap; + uint8_t weight; while (i < labelLine.lineLength) { letter = TypedText::GetUTF8Next(labelLine.text, i, i); uint8_t fontId = labelLine.fontId; @@ -86,23 +85,26 @@ uint16_t DrawLabel::DrawTextOneLine(BufferInfo& gfxDstBuffer, const LabelLineInf labelLine.style.lineSpace_, havebackgroundColor, backgroundColor}; - if (TypedText::IsColourWord(letter, fontId, fontSize)) { - if (!isEmoijLerge) { - letterInfo.offsetY = offsetPosY; - } - DrawUtils::GetInstance()->DrawColorLetter(gfxDstBuffer, letterInfo); - } else { - if (isEmoijLerge) { +#if ENABLE_VECTOR_FONT + glyphNode.textStyle = letterInfo.textStyle; +#endif + glyphNode.advance = 0; + fontMap = fontEngine->GetBitmap(letterInfo.letter, glyphNode, letterInfo.fontId, letterInfo.fontSize, + letterInfo.shapingId); + if (fontMap != nullptr) { + weight = UIFont::GetInstance()->GetFontWeight(glyphNode.fontId); + if (weight >= 16) { // 16: rgb565->16 rgba8888->32 font with rgba + DrawUtils::GetInstance()->DrawColorLetter(gfxDstBuffer, letterInfo, fontMap, glyphNode); + } else { letterInfo.offsetY = labelLine.ellipsisOssetY == 0 ? offsetPosY : labelLine.ellipsisOssetY; retOffsetY = offsetPosY; + DrawUtils::GetInstance()->DrawNormalLetter(gfxDstBuffer, letterInfo, fontMap, glyphNode, maxLetterSize); } - DrawUtils::GetInstance()->DrawNormalLetter(gfxDstBuffer, letterInfo, maxLetterSize); } - letterWidth = fontEngine->GetWidth(letter, letterInfo.fontId, letterInfo.fontSize, letterInfo.shapingId); if (labelLine.direct == TEXT_DIRECT_RTL) { - labelLine.pos.x -= (letterWidth + labelLine.style.letterSpace_); + labelLine.pos.x -= (glyphNode.advance + labelLine.style.letterSpace_); } else { - labelLine.pos.x += (letterWidth + labelLine.style.letterSpace_); + labelLine.pos.x += (glyphNode.advance + labelLine.style.letterSpace_); } letterIndex++; @@ -113,6 +115,9 @@ uint16_t DrawLabel::DrawTextOneLine(BufferInfo& gfxDstBuffer, const LabelLineInf uint8_t DrawLabel::GetLineMaxLetterSize(const char* text, uint16_t lineLength, uint8_t fontId, uint8_t fontSize, uint16_t letterIndex, SizeSpan* sizeSpans) { + if (sizeSpans == nullptr) { + return fontSize; + } uint32_t i = 0; uint32_t unicode; uint8_t maxLetterSize = fontSize; diff --git a/frameworks/draw/draw_utils.cpp b/frameworks/draw/draw_utils.cpp index 9944bcc..54dfa10 100644 --- a/frameworks/draw/draw_utils.cpp +++ b/frameworks/draw/draw_utils.cpp @@ -268,18 +268,15 @@ void DrawUtils::DrawPixel(BufferInfo& gfxDstBuffer, COLOR_FILL_BLEND(screenBuffer, bufferMode, &fillColor, ARGB8888, opa); } -void DrawUtils::DrawColorLetter(BufferInfo &gfxDstBuffer, const LabelLetterInfo &letterInfo) const +void DrawUtils::DrawColorLetter(BufferInfo& gfxDstBuffer, + const LabelLetterInfo& letterInfo, + uint8_t* fontMap, + GlyphNode node) const { - UIFont* fontEngine = UIFont::GetInstance(); - GlyphNode node; -#if ENABLE_VECTOR_FONT - node.textStyle = letterInfo.textStyle; -#endif - const uint8_t* fontMap = - fontEngine->GetBitmap(letterInfo.letter, node, letterInfo.fontId, letterInfo.fontSize, letterInfo.shapingId); if (fontMap == nullptr) { return; } + UIFont* fontEngine = UIFont::GetInstance(); uint16_t letterW = node.cols; uint16_t letterH = node.rows; int16_t posX; @@ -315,20 +312,17 @@ void DrawUtils::DrawColorLetter(BufferInfo &gfxDstBuffer, const LabelLetterInfo DrawImage(gfxDstBuffer, srcRect, letterInfo.mask, fontMap, letterInfo.opa, pxSize, ARGB8888); } -void DrawUtils::DrawNormalLetter(BufferInfo &gfxDstBuffer, const LabelLetterInfo &letterInfo, +void DrawUtils::DrawNormalLetter(BufferInfo& gfxDstBuffer, + const LabelLetterInfo& letterInfo, + uint8_t* fontMap, + GlyphNode node, uint8_t maxLetterSize) const { - UIFont* fontEngine = UIFont::GetInstance(); - GlyphNode node; -#if ENABLE_VECTOR_FONT - node.textStyle = letterInfo.textStyle; -#endif - const uint8_t* fontMap = - fontEngine->GetBitmap(letterInfo.letter, node, letterInfo.fontId, letterInfo.fontSize, letterInfo.shapingId); if (fontMap == nullptr) { return; } + UIFont* fontEngine = UIFont::GetInstance(); uint16_t letterW = node.cols; uint16_t letterH = node.rows; int16_t posX; diff --git a/frameworks/draw/draw_utils.h b/frameworks/draw/draw_utils.h index c07968c..fdf015b 100644 --- a/frameworks/draw/draw_utils.h +++ b/frameworks/draw/draw_utils.h @@ -209,8 +209,15 @@ public: void DrawPixel(BufferInfo& gfxDstBuffer, int16_t x, int16_t y, const Rect& mask, const ColorType& color, OpacityType opa) const; - void DrawColorLetter(BufferInfo& gfxDstBuffer, const LabelLetterInfo& letterInfo) const; - void DrawNormalLetter(BufferInfo& gfxDstBuffer, const LabelLetterInfo& letterInfo, uint8_t maxLetterSize) const; + void DrawColorLetter(BufferInfo& gfxDstBuffer, + const LabelLetterInfo& letterInfo, + uint8_t* fontMap, + GlyphNode node) const; + void DrawNormalLetter(BufferInfo& gfxDstBuffer, + const LabelLetterInfo& letterInfo, + uint8_t* fontMap, + GlyphNode node, + uint8_t maxLetterSize) const; void DrawLetter(BufferInfo& gfxDstBuffer, const uint8_t* fontMap, diff --git a/frameworks/font/glyphs_manager.cpp b/frameworks/font/glyphs_manager.cpp index 91909fd..5bcd247 100644 --- a/frameworks/font/glyphs_manager.cpp +++ b/frameworks/font/glyphs_manager.cpp @@ -308,11 +308,6 @@ const FontHeader* GlyphsManager::GetFontHeader(uint8_t fontId) const GlyphNode* GlyphsManager::GetGlyphNode(uint32_t unicode, uint8_t fontId) { - GlyphInfo glyphInfo; - int8_t ret = GetGlyphInfo(fontId, glyphInfo); - if (ret != RET_VALUE_OK) { - return nullptr; - } GlyphNode* node = GetNodeFromCache(unicode, fontId); if (node == nullptr) { node = GetNodeFromFile(unicode, fontId); diff --git a/frameworks/font/ui_font_bitmap.cpp b/frameworks/font/ui_font_bitmap.cpp index df61c1b..3f26b61 100644 --- a/frameworks/font/ui_font_bitmap.cpp +++ b/frameworks/font/ui_font_bitmap.cpp @@ -367,9 +367,13 @@ uint16_t UIFontBitmap::GetOffsetPosY(const char *text, uint16_t lineLength, uint16_t UIFontBitmap::GetLineMaxHeight(const char *text, uint16_t lineLength, uint8_t fontId, uint8_t fontSize, uint16_t& letterIndex, SizeSpan* sizeSpans) { + uint16_t maxHeight = GetHeight(fontId, fontSize); + if (sizeSpans == nullptr) { + return maxHeight; + } + uint32_t i = 0; uint32_t unicode; - uint16_t maxHeight = GetHeight(fontId, fontSize); GlyphNode glyphNode; while (i < lineLength) { unicode = TypedText::GetUTF8Next(text, i, i); @@ -382,15 +386,6 @@ uint16_t UIFontBitmap::GetLineMaxHeight(const char *text, uint16_t lineLength, u spannableHeight = sizeSpans[letterIndex].height; } maxHeight = spannableHeight > maxHeight ? spannableHeight : maxHeight; - } else { -#if ENABLE_MULTI_FONT - uint8_t ret = GetMultiGlyphNode(unicode, glyphNode, fontId); -#else - uint8_t ret = GetGlyphNode(unicode, glyphNode, fontId, fontSize); -#endif - if (ret == RET_VALUE_OK) { - maxHeight = glyphNode.rows > maxHeight ? glyphNode.rows : maxHeight; - } } letterIndex++; diff --git a/frameworks/font/ui_line_break.cpp b/frameworks/font/ui_line_break.cpp index a65b704..e39826e 100644 --- a/frameworks/font/ui_line_break.cpp +++ b/frameworks/font/ui_line_break.cpp @@ -138,9 +138,7 @@ uint32_t UILineBreakEngine::GetNextLineAndWidth(const char* text, continue; } if (isAllCanBreak || IsBreakPos(unicode, fontId, fontSize, state)) { - if (!TypedText::IsColourWord(unicode, fontId, fontSize)) { - state = LINE_BREAK_STATE_START; - } + state = LINE_BREAK_STATE_START; // Accumulates the status value from the current character. IsBreakPos(unicode, fontId, fontSize, state); lastIndex = preIndex; @@ -193,9 +191,6 @@ int16_t UILineBreakEngine::GetLetterWidth(uint32_t unicode, uint16_t& letterInde bool UILineBreakEngine::IsBreakPos(uint32_t unicode, uint8_t fontId, uint8_t fontSize, int32_t& state) { - if (TypedText::IsColourWord(unicode, fontId, fontSize)) { - return true; - } if ((unicode > TypedText::MAX_UINT16_HIGH_SCOPE) || (stateTbl_ == nullptr) || (lineBreakTrie_ == nullptr)) { return true; } -- GitLab