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