• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <limits>
17 #include "draw/draw_label.h"
18 #include "engines/gfx/gfx_engine_manager.h"
19 #include "gfx_utils/graphic_log.h"
20 #include "common/typed_text.h"
21 #include "draw/draw_utils.h"
22 #include "font/ui_font.h"
23 #include "font/ui_font_header.h"
24 
25 namespace OHOS {
DrawTextOneLine(BufferInfo & gfxDstBuffer,const LabelLineInfo & labelLine,uint16_t & letterIndex)26 uint16_t DrawLabel::DrawTextOneLine(BufferInfo& gfxDstBuffer, const LabelLineInfo& labelLine, uint16_t& letterIndex)
27 {
28     if (labelLine.text == nullptr) {
29         return 0;
30     }
31     UIFont* fontEngine = UIFont::GetInstance();
32     if (labelLine.direct == TEXT_DIRECT_RTL) {
33         labelLine.pos.x -= labelLine.offset.x;
34     } else {
35         labelLine.pos.x += labelLine.offset.x;
36     }
37 
38     uint32_t i = 0;
39     uint16_t retOffsetY = 0; // ret value elipse offsetY
40     uint16_t offsetPosY = 0;
41     uint8_t maxLetterSize = GetLineMaxLetterSize(labelLine.text, labelLine.lineLength, labelLine.fontId,
42                                                  labelLine.fontSize, letterIndex, labelLine.spannableString);
43     GlyphNode glyphNode;
44     while (i < labelLine.lineLength) {
45         uint32_t letter = TypedText::GetUTF8Next(labelLine.text, i, i);
46         uint16_t fontId = labelLine.fontId;
47         uint8_t fontSize = labelLine.fontSize;
48 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
49         TextStyle textStyle = TEXT_STYLE_NORMAL;
50         if (labelLine.textStyles) {
51             textStyle = labelLine.textStyles[letterIndex];
52         }
53 #endif
54         bool haveLineBackgroundColor = false;
55         ColorType lineBackgroundColor;
56         bool havebackgroundColor = false;
57         ColorType backgroundColor;
58         ColorType foregroundColor = labelLine.style.textColor_;
59 
60         if (labelLine.spannableString != nullptr && labelLine.spannableString->GetSpannable(letterIndex)) {
61             labelLine.spannableString->GetFontId(letterIndex, fontId);
62             labelLine.spannableString->GetFontSize(letterIndex, fontSize);
63             havebackgroundColor = labelLine.spannableString->GetBackgroundColor(letterIndex, backgroundColor);
64             labelLine.spannableString->GetForegroundColor(letterIndex, foregroundColor);
65 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
66             labelLine.spannableString->GetTextStyle(letterIndex, textStyle);
67 #endif
68             haveLineBackgroundColor =
69                 labelLine.spannableString->GetLineBackgroundColor(letterIndex, lineBackgroundColor);
70         }
71         LabelLetterInfo letterInfo{labelLine.pos,
72                                    labelLine.mask,
73                                    foregroundColor,
74                                    labelLine.opaScale,
75                                    0,
76                                    0,
77                                    letter,
78                                    labelLine.direct,
79                                    fontId,
80                                    0,
81                                    fontSize,
82 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
83                                    textStyle,
84 #endif
85                                    labelLine.baseLine,
86                                    labelLine.style.letterSpace_,
87                                    labelLine.style.lineSpace_,
88                                    havebackgroundColor,
89                                    backgroundColor,
90                                    haveLineBackgroundColor,
91                                    lineBackgroundColor
92                                    };
93 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
94         glyphNode.textStyle = letterInfo.textStyle;
95 #endif
96         glyphNode.advance = 0;
97         uint8_t* fontMap = fontEngine->GetBitmap(letterInfo.letter, glyphNode, letterInfo.fontId, letterInfo.fontSize,
98                                                  letterInfo.shapingId);
99         if (fontMap != nullptr) {
100             uint8_t weight = fontEngine->GetFontWeight(glyphNode.fontId);
101             // 16: rgb565->16 rgba8888->32 font with rgba
102             if (weight >= 16) {
103                 DrawUtils::GetInstance()->DrawColorLetter(gfxDstBuffer, letterInfo, fontMap,
104                                                           glyphNode, labelLine.lineHeight);
105             } else {
106                 letterInfo.offsetY = labelLine.ellipsisOssetY == 0 ? offsetPosY : labelLine.ellipsisOssetY;
107                 retOffsetY = offsetPosY;
108                 DrawUtils::GetInstance()->DrawNormalLetter(gfxDstBuffer, letterInfo, fontMap, glyphNode, maxLetterSize);
109             }
110         }
111         if (labelLine.direct == TEXT_DIRECT_RTL) {
112             labelLine.pos.x -= (glyphNode.advance + labelLine.style.letterSpace_);
113         } else {
114             labelLine.pos.x += (glyphNode.advance + labelLine.style.letterSpace_);
115         }
116         letterIndex++;
117     }
118     return retOffsetY;
119 }
120 
GetLineMaxLetterSize(const char * text,uint16_t lineLength,uint16_t fontId,uint8_t fontSize,uint16_t letterIndex,SpannableString * spannableString)121 uint8_t DrawLabel::GetLineMaxLetterSize(const char* text, uint16_t lineLength, uint16_t fontId, uint8_t fontSize,
122                                         uint16_t letterIndex, SpannableString* spannableString)
123 {
124     if (spannableString == nullptr) {
125         return fontSize;
126     }
127     uint32_t i = 0;
128     uint8_t maxLetterSize = fontSize;
129     while (i < lineLength) {
130         uint32_t unicode = TypedText::GetUTF8Next(text, i, i);
131         if (TypedText::IsColourWord(unicode, fontId, fontSize)) {
132             letterIndex++;
133             continue;
134         }
135         if (spannableString != nullptr && spannableString->GetSpannable(letterIndex)) {
136             uint8_t tempSize = fontSize;
137             spannableString->GetFontSize(letterIndex, tempSize);
138             if (tempSize > maxLetterSize) {
139                 maxLetterSize = tempSize;
140             }
141         }
142         letterIndex++;
143     }
144     return maxLetterSize;
145 }
146 
DrawArcText(BufferInfo & gfxDstBuffer,const Rect & mask,const char * text,const Point & arcCenter,uint16_t fontId,uint8_t fontSize,const ArcTextInfo arcTextInfo,const float changeAngle,TextOrientation orientation,const Style & style,OpacityType opaScale,bool compatibilityMode)147 void DrawLabel::DrawArcText(BufferInfo& gfxDstBuffer,
148                             const Rect& mask,
149                             const char* text,
150                             const Point& arcCenter,
151                             uint16_t fontId,
152                             uint8_t fontSize,
153                             const ArcTextInfo arcTextInfo,
154                             const float changeAngle,
155                             TextOrientation orientation,
156                             const Style& style,
157                             OpacityType opaScale,
158                             bool compatibilityMode)
159 {
160     if ((text == nullptr) || (arcTextInfo.lineStart == arcTextInfo.lineEnd) || (arcTextInfo.radius == 0)) {
161         GRAPHIC_LOGE("DrawLabel::DrawArcText invalid parameter\n");
162         return;
163     }
164     OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.textOpa_);
165     if (opa == OPA_TRANSPARENT) {
166         return;
167     }
168     uint16_t letterWidth;
169     UIFont* fontEngine = UIFont::GetInstance();
170 
171     uint16_t letterHeight = fontEngine->GetHeight(fontId, fontSize);
172     uint32_t i = arcTextInfo.lineStart;
173     bool orientationFlag = (orientation == TextOrientation::INSIDE);
174     bool directFlag = (arcTextInfo.direct == TEXT_DIRECT_LTR);
175     bool xorFlag = !directFlag;
176     if (compatibilityMode) {
177         xorFlag = !((orientationFlag && directFlag) || (!orientationFlag && !directFlag));
178     }
179     float angle = directFlag ? (arcTextInfo.startAngle + changeAngle) : (arcTextInfo.startAngle - changeAngle);
180 
181     float posX;
182     float posY;
183     float rotateAngle;
184     while (i < arcTextInfo.lineEnd) {
185         uint32_t tmp = i;
186         uint32_t letter = TypedText::GetUTF8Next(text, tmp, i);
187         if (letter == 0) {
188             continue;
189         }
190         if ((letter == '\r') || (letter == '\n')) {
191             break;
192         }
193         letterWidth = fontEngine->GetWidth(letter, fontId, fontSize, 0);
194         if (!DrawLabel::CalculateAngle(letterWidth, letterHeight, style.letterSpace_,
195                                        arcTextInfo, xorFlag, tmp, orientation,
196                                        posX, posY, rotateAngle, angle,
197                                        arcCenter, compatibilityMode)) {
198             continue;
199         }
200 
201         ArcLetterInfo letterInfo;
202         letterInfo.InitData(fontId, fontSize, letter, { MATH_ROUND(posX), MATH_ROUND(posY) },
203             static_cast<int16_t>(rotateAngle), style.textColor_, opaScale, arcTextInfo.startAngle,
204             arcTextInfo.endAngle, angle, arcTextInfo.radius, compatibilityMode,
205             directFlag, orientationFlag, arcTextInfo.hasAnimator);
206 
207         DrawLetterWithRotate(gfxDstBuffer, mask, letterInfo, posX, posY);
208     }
209 }
210 
CalculateAngle(uint16_t letterWidth,uint16_t letterHeight,int16_t letterSpace,const ArcTextInfo arcTextInfo,bool xorFlag,uint32_t index,TextOrientation orientation,float & posX,float & posY,float & rotateAngle,float & angle,const Point & arcCenter,bool compatibilityMode)211 bool DrawLabel::CalculateAngle(uint16_t letterWidth,
212                                uint16_t letterHeight,
213                                int16_t letterSpace,
214                                const ArcTextInfo arcTextInfo,
215                                bool xorFlag,
216                                uint32_t index,
217                                TextOrientation orientation,
218                                float& posX,
219                                float& posY,
220                                float& rotateAngle,
221                                float& angle,
222                                const Point& arcCenter,
223                                bool compatibilityMode)
224 {
225     const int DIVIDER_BY_TWO = 2;
226     if (compatibilityMode) {
227         if ((index == arcTextInfo.lineStart) && xorFlag) {
228             angle += TypedText::GetAngleForArcLen(static_cast<float>(letterWidth), letterHeight, arcTextInfo.radius,
229                                                   arcTextInfo.direct, orientation);
230         }
231         uint16_t arcLen = letterWidth + letterSpace;
232         if (arcLen == 0) {
233             return false;
234         }
235         float incrementAngle = TypedText::GetAngleForArcLen(static_cast<float>(arcLen), letterHeight,
236                                                             arcTextInfo.radius, arcTextInfo.direct, orientation);
237 
238         rotateAngle = (orientation == TextOrientation::INSIDE) ? angle : (angle - SEMICIRCLE_IN_DEGREE);
239 
240         // 2: half
241         float fineTuningAngle = incrementAngle * (static_cast<float>(letterWidth) / (DIVIDER_BY_TWO * arcLen));
242         rotateAngle += (xorFlag ? -fineTuningAngle : fineTuningAngle);
243         TypedText::GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY);
244         angle += incrementAngle;
245     } else {
246         float incrementAngle = TypedText::GetAngleForArcLen(letterWidth, letterSpace, arcTextInfo.radius);
247         if (incrementAngle >= -EPSINON && incrementAngle <= EPSINON) {
248             return false;
249         }
250 
251         float fineTuningAngle = incrementAngle / DIVIDER_BY_TWO;
252         rotateAngle = xorFlag ? (angle - SEMICIRCLE_IN_DEGREE - fineTuningAngle) : (angle + fineTuningAngle);
253         TypedText::GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY);
254         angle = xorFlag ? (angle - incrementAngle) : (angle + incrementAngle);
255     }
256 
257     return true;
258 }
259 
DrawLetterWithRotate(BufferInfo & gfxDstBuffer,const Rect & mask,const ArcLetterInfo & letterInfo,float posX,float posY)260 void DrawLabel::DrawLetterWithRotate(BufferInfo& gfxDstBuffer,
261                                      const Rect& mask,
262                                      const ArcLetterInfo& letterInfo,
263                                      float posX,
264                                      float posY)
265 {
266     UIFont* fontEngine = UIFont::GetInstance();
267     FontHeader head;
268     GlyphNode node;
269 #if defined(ENABLE_TEXT_STYLE) && ENABLE_TEXT_STYLE
270     node.textStyle = TEXT_STYLE_NORMAL;
271 #endif
272     if (fontEngine->GetFontHeader(head, letterInfo.fontId, letterInfo.fontSize) != 0) {
273         return;
274     }
275 
276     const uint8_t* fontMap = fontEngine->GetBitmap(letterInfo.letter, node,
277         letterInfo.fontId, letterInfo.fontSize, 0);
278     if (fontMap == nullptr) {
279         return;
280     }
281     uint8_t fontWeight = fontEngine->GetFontWeight(letterInfo.fontId);
282     ColorMode colorMode = fontEngine->GetColorType(letterInfo.fontId);
283 
284     int16_t offset = letterInfo.compatibilityMode ? head.ascender : 0;
285     Rect rectLetter;
286     rectLetter.Resize(node.cols, node.rows);
287     TransformMap transMap(rectLetter);
288     // Avoiding errors caused by rounding calculations
289     transMap.Translate(Vector2<float>(posX + node.left, posY + offset - node.top));
290     transMap.Rotate(letterInfo.rotateAngle, Vector2<float>(posX, posY));
291 
292     TransformDataInfo letterTranDataInfo = {ImageHeader{colorMode, 0, 0, 0, node.cols, node.rows}, fontMap, fontWeight,
293                                             BlurLevel::LEVEL0, TransformAlgorithm::BILINEAR};
294 
295     uint8_t* buffer = nullptr;
296     if (letterInfo.hasAnimator) {
297         bool inRange = DrawLabel::CalculatedTransformDataInfo(&buffer, letterTranDataInfo, letterInfo);
298         if (inRange == false) {
299             if (buffer != nullptr) {
300                 UIFree(buffer);
301                 buffer = nullptr;
302             }
303             return;
304         }
305     }
306 
307     BaseGfxEngine::GetInstance()->DrawTransform(gfxDstBuffer, mask, Point { 0, 0 }, letterInfo.color,
308         letterInfo.opaScale, transMap, letterTranDataInfo);
309     if (buffer != nullptr) {
310         UIFree(buffer);
311         buffer = nullptr;
312     }
313 }
314 
CalculatedClipAngle(const ArcLetterInfo & letterInfo,float & angle)315 bool DrawLabel::CalculatedClipAngle(const ArcLetterInfo& letterInfo, float& angle)
316 {
317     if (letterInfo.directFlag) {
318         if ((letterInfo.compatibilityMode && letterInfo.orientationFlag) || !letterInfo.compatibilityMode) {
319             if (letterInfo.currentAngle > letterInfo.endAngle) {
320                 angle = letterInfo.currentAngle - letterInfo.endAngle;
321             } else if (letterInfo.currentAngle > letterInfo.startAngle) {
322                 angle = letterInfo.currentAngle - letterInfo.startAngle;
323             } else {
324                 return false;
325             }
326         } else {
327             if (letterInfo.currentAngle > letterInfo.endAngle) {
328                 angle = letterInfo.currentAngle - letterInfo.endAngle;
329             } else if (letterInfo.currentAngle > letterInfo.startAngle) {
330                 angle = letterInfo.currentAngle - letterInfo.startAngle;
331             } else {
332                 return false;
333             }
334         }
335     } else {
336         if (letterInfo.compatibilityMode && letterInfo.orientationFlag) {
337             if (letterInfo.currentAngle < letterInfo.endAngle) {
338                 angle = letterInfo.endAngle - letterInfo.currentAngle;
339             } else if (letterInfo.currentAngle < letterInfo.startAngle) {
340                 angle = letterInfo.startAngle - letterInfo.currentAngle;
341             } else {
342                 return false;
343             }
344         } else if ((letterInfo.compatibilityMode && !letterInfo.orientationFlag) || !letterInfo.compatibilityMode) {
345             if (letterInfo.currentAngle < letterInfo.endAngle) {
346                 angle = letterInfo.endAngle - letterInfo.currentAngle;
347             } else if (letterInfo.currentAngle < letterInfo.startAngle) {
348                 angle = letterInfo.startAngle - letterInfo.currentAngle;
349             } else {
350                 return false;
351             }
352         }
353     }
354 
355     return true;
356 }
357 
OnCalculatedClockwise(const ArcLetterInfo & letterInfo,const uint16_t sizePerPx,const uint16_t cols,const int16_t offsetX,uint16_t & begin,uint16_t & copyCols,TextInRange & range)358 void DrawLabel::OnCalculatedClockwise(const ArcLetterInfo& letterInfo, const uint16_t sizePerPx,
359                                       const uint16_t cols, const int16_t offsetX, uint16_t& begin,
360                                       uint16_t& copyCols, TextInRange& range)
361 {
362     if (!letterInfo.directFlag) {
363         return;
364     }
365     if ((letterInfo.compatibilityMode && letterInfo.orientationFlag) || !letterInfo.compatibilityMode) {
366         if (letterInfo.currentAngle > letterInfo.endAngle) {
367             if (offsetX >= cols) {
368                 range = TextInRange::OUT_RANGE;
369             }
370             copyCols = cols - offsetX;
371         } else if (letterInfo.currentAngle > letterInfo.startAngle) {
372             if (offsetX >= cols) {
373                 range = TextInRange::IN_RANGE;
374             }
375             copyCols = offsetX;
376             begin = (cols - offsetX) * sizePerPx;
377         }
378     } else {
379         if (letterInfo.currentAngle > letterInfo.endAngle) {
380             if (offsetX >= cols) {
381                 range = TextInRange::OUT_RANGE;
382             }
383             copyCols = cols - offsetX;
384             begin = offsetX * sizePerPx;
385         } else if (letterInfo.currentAngle > letterInfo.startAngle) {
386             if (offsetX >= cols) {
387                 range = TextInRange::IN_RANGE;
388             }
389             copyCols = offsetX;
390         }
391     }
392 }
393 
OnCalculatedAnticlockwise(const ArcLetterInfo & letterInfo,const uint16_t sizePerPx,const uint16_t cols,const int16_t offsetX,uint16_t & begin,uint16_t & copyCols,TextInRange & range)394 void DrawLabel::OnCalculatedAnticlockwise(const ArcLetterInfo& letterInfo, const uint16_t sizePerPx,
395                                           const uint16_t cols, const int16_t offsetX, uint16_t& begin,
396                                           uint16_t& copyCols, TextInRange& range)
397 {
398     if (letterInfo.directFlag) {
399         return;
400     }
401     if (letterInfo.compatibilityMode && letterInfo.orientationFlag) {
402         if (letterInfo.currentAngle < letterInfo.endAngle) {
403             if (offsetX >= cols) {
404                 range = TextInRange::OUT_RANGE;
405             }
406             copyCols = cols - offsetX;
407             begin = offsetX * sizePerPx;
408         } else if (letterInfo.currentAngle < letterInfo.startAngle) {
409             if (offsetX >= cols) {
410                 range = TextInRange::IN_RANGE;
411             }
412             copyCols = offsetX;
413         }
414     } else if ((letterInfo.compatibilityMode && !letterInfo.orientationFlag) || !letterInfo.compatibilityMode) {
415         if (letterInfo.currentAngle < letterInfo.endAngle) {
416             if (offsetX >= cols) {
417                 range = TextInRange::OUT_RANGE;
418             }
419             copyCols = cols - offsetX;
420         } else if (letterInfo.currentAngle < letterInfo.startAngle) {
421             if (offsetX >= cols) {
422                 range = TextInRange::IN_RANGE;
423             }
424             copyCols = offsetX;
425             begin = (cols - offsetX) * sizePerPx;
426         }
427     }
428 }
429 
CalculatedBeginAndCopySize(const ArcLetterInfo & letterInfo,const uint16_t sizePerPx,const uint16_t cols,const int16_t offsetX,uint16_t & begin,uint16_t & copyCols,TextInRange & range)430 void DrawLabel::CalculatedBeginAndCopySize(const ArcLetterInfo& letterInfo, const uint16_t sizePerPx,
431                                            const uint16_t cols, const int16_t offsetX, uint16_t& begin,
432                                            uint16_t& copyCols, TextInRange& range)
433 {
434     if (letterInfo.directFlag) {
435         OnCalculatedClockwise(letterInfo, sizePerPx, cols, offsetX, begin, copyCols, range);
436     } else {
437         OnCalculatedAnticlockwise(letterInfo, sizePerPx, cols, offsetX, begin, copyCols, range);
438     }
439 }
440 
CalculatedTransformDataInfo(uint8_t ** buffer,TransformDataInfo & letterTranDataInfo,const ArcLetterInfo & letterInfo)441 bool DrawLabel::CalculatedTransformDataInfo(uint8_t** buffer, TransformDataInfo& letterTranDataInfo,
442     const ArcLetterInfo& letterInfo)
443 {
444     float angle = 0.0f;
445     if (DrawLabel::CalculatedClipAngle(letterInfo, angle) == false) {
446         return false;
447     }
448     if (angle >= -EPSINON && angle <= EPSINON) {
449         return true;
450     }
451 
452     int32_t rawOffset = static_cast<int32_t>(static_cast<double>(angle * letterInfo.radius) *
453         UI_PI / SEMICIRCLE_IN_DEGREE);
454     if (rawOffset < std::numeric_limits<int16_t>::min() || rawOffset > std::numeric_limits<int16_t>::max()) {
455         // 处理溢出错误
456         return false;
457     }
458     int16_t offsetX = static_cast<int16_t>(rawOffset);
459     uint16_t copyCols = 0;
460     uint16_t begin = 0;
461     uint16_t sizePerPx = letterTranDataInfo.pxSize / 8; // 8 bit
462     TextInRange range = TextInRange::NEED_CLIP;
463     uint16_t cols = letterTranDataInfo.header.width;
464     uint16_t rows = letterTranDataInfo.header.height;
465     DrawLabel::CalculatedBeginAndCopySize(letterInfo, sizePerPx, cols, offsetX, begin, copyCols, range);
466     if (range == TextInRange::IN_RANGE) {
467         return true;
468     } else if (range == TextInRange::OUT_RANGE) {
469         return false;
470     }
471 
472     const uint8_t* fontMap = letterTranDataInfo.data;
473 
474     uint32_t size = cols * rows * sizePerPx;
475     *buffer = static_cast<uint8_t*>(UIMalloc(size));
476     if (*buffer == nullptr) {
477         return false;
478     }
479 
480     if (memset_s(*buffer, size, 0, size) != EOK) {
481         UIFree(*buffer);
482         return false;
483     }
484 
485     for (uint16_t i = 0; i < rows; i++) {
486         uint16_t beginSize = i * cols * sizePerPx + begin;
487         uint16_t copySize = copyCols * sizePerPx;
488         if (memcpy_s(*buffer + beginSize, copySize, fontMap + beginSize, copySize) != EOK) {
489             UIFree(*buffer);
490             return false;
491         }
492     }
493     letterTranDataInfo.data = *buffer;
494     return true;
495 }
496 
GetLineBackgroundColor(uint16_t letterIndex,List<LineBackgroundColor> * linebackgroundColor,bool & havelinebackground,ColorType & linebgColor)497 void DrawLabel::GetLineBackgroundColor(uint16_t letterIndex, List<LineBackgroundColor>* linebackgroundColor,
498                                        bool& havelinebackground, ColorType& linebgColor)
499 {
500     if (linebackgroundColor->Size() > 0) {
501         ListNode<LineBackgroundColor>* lbColor = linebackgroundColor->Begin();
502         for (; lbColor != linebackgroundColor->End(); lbColor = lbColor->next_) {
503             uint32_t start = lbColor->data_.start;
504             uint32_t end = lbColor->data_.end;
505             if (letterIndex >= start && letterIndex <= end) {
506                 havelinebackground = true;
507                 linebgColor = lbColor->data_.linebackgroundColor ;
508             }
509         }
510     }
511 };
512 
GetBackgroundColor(uint16_t letterIndex,List<BackgroundColor> * backgroundColor,bool & havebackground,ColorType & bgColor)513 void DrawLabel::GetBackgroundColor(uint16_t letterIndex, List<BackgroundColor>* backgroundColor,
514                                    bool& havebackground, ColorType& bgColor)
515 {
516     if (backgroundColor->Size() > 0) {
517         ListNode<BackgroundColor>* bColor = backgroundColor->Begin();
518         for (; bColor != backgroundColor->End(); bColor = bColor->next_) {
519             uint16_t start = bColor->data_.start;
520             uint16_t end = bColor->data_.end;
521             if (letterIndex >= start && letterIndex <= end) {
522                 havebackground = true;
523                 bgColor = bColor->data_.backgroundColor ;
524             }
525         }
526     }
527 };
528 
GetForegroundColor(uint16_t letterIndex,List<ForegroundColor> * foregroundColor,ColorType & fgColor)529 void DrawLabel::GetForegroundColor(uint16_t letterIndex, List<ForegroundColor>* foregroundColor, ColorType& fgColor)
530 {
531     if (foregroundColor->Size() > 0) {
532         ListNode<ForegroundColor>* fColor = foregroundColor->Begin();
533         for (; fColor != foregroundColor->End(); fColor = fColor->next_) {
534             uint32_t start = fColor->data_.start;
535             uint32_t end = fColor->data_.end;
536             if (letterIndex >= start && letterIndex <= end) {
537                 fgColor = fColor->data_.fontColor;
538             }
539         }
540     }
541 };
542 
DrawLineBackgroundColor(BufferInfo & gfxDstBuffer,uint16_t letterIndex,const LabelLineInfo & labelLine)543 void DrawLabel::DrawLineBackgroundColor(BufferInfo& gfxDstBuffer, uint16_t letterIndex, const LabelLineInfo& labelLine)
544 {
545     uint32_t i = 0;
546     while (i < labelLine.lineLength) {
547         TypedText::GetUTF8Next(labelLine.text, i, i);
548         bool havelinebackground = false;
549         ColorType linebackgroundColor;
550         if (labelLine.spannableString != nullptr &&
551             labelLine.spannableString->GetSpannable(letterIndex)) {
552             havelinebackground =
553                 labelLine.spannableString->GetLineBackgroundColor(
554                     letterIndex, linebackgroundColor);
555         }
556         if (havelinebackground) {
557             Style style;
558             style.bgColor_ = linebackgroundColor;
559             Rect linebackground(labelLine.mask.GetLeft(), labelLine.pos.y,
560                                 labelLine.mask.GetRight(),
561                                 labelLine.pos.y + labelLine.lineHeight);
562             BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, labelLine.mask,
563                                                    linebackground, style,
564                                                    linebackgroundColor.alpha);
565         }
566         letterIndex++;
567     }
568 };
569 } // namespace OHOS
570