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