1 /*
2  * Copyright (c) 2021-2023 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 "constants_converter.h"
17 
18 #ifndef USE_GRAPHIC_TEXT_GINE
19 #include "txt/font_style.h"
20 #include "txt/font_weight.h"
21 #include "txt/paragraph_style.h"
22 #include "txt/text_decoration.h"
23 #else
24 #include "rosen_text/hm_symbol_txt.h"
25 #include "rosen_text/typography_create.h"
26 #include "rosen_text/typography_style.h"
27 #endif
28 
29 #include "base/i18n/localization.h"
30 
31 namespace OHOS::Ace::Constants {
32 namespace {
33 const std::string FONTWEIGHT = "wght";
34 constexpr float DEFAULT_MULTIPLE = 100.0f;
35 constexpr float MIN_FONT_WEIGHT = 100.0f;
36 constexpr float DEFAULT_FONT_WEIGHT = 400.0f;
37 constexpr float MAX_FONT_WEIGHT = 900.0f;
38 constexpr int32_t SCALE_EFFECT = 2;
39 constexpr int32_t NONE_EFFECT = 0;
40 constexpr float ORIGINAL_LINE_HEIGHT_SCALE = 1.0f;
41 } // namespace
42 
43 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtFontWeight(FontWeight fontWeight)44 txt::FontWeight ConvertTxtFontWeight(FontWeight fontWeight)
45 {
46     txt::FontWeight convertValue;
47     switch (fontWeight) {
48         case FontWeight::W100:
49         case FontWeight::LIGHTER:
50             convertValue = txt::FontWeight::w100;
51             break;
52         case FontWeight::W200:
53             convertValue = txt::FontWeight::w200;
54             break;
55         case FontWeight::W300:
56             convertValue = txt::FontWeight::w300;
57             break;
58         case FontWeight::W400:
59         case FontWeight::NORMAL:
60         case FontWeight::REGULAR:
61             convertValue = txt::FontWeight::w400;
62             break;
63         case FontWeight::W500:
64         case FontWeight::MEDIUM:
65             convertValue = txt::FontWeight::w500;
66             break;
67         case FontWeight::W600:
68             convertValue = txt::FontWeight::w600;
69             break;
70         case FontWeight::W700:
71         case FontWeight::BOLD:
72             convertValue = txt::FontWeight::w700;
73             break;
74         case FontWeight::W800:
75             convertValue = txt::FontWeight::w800;
76             break;
77         case FontWeight::W900:
78         case FontWeight::BOLDER:
79             convertValue = txt::FontWeight::w900;
80             break;
81         default:
82             TAG_LOGW(AceLogTag::ACE_FONT, "FontWeight set error! use default FontWeight.");
83             convertValue = txt::FontWeight::w400;
84             break;
85     }
86     return convertValue;
87 }
88 #else
ConvertTxtFontWeight(FontWeight fontWeight)89 Rosen::FontWeight ConvertTxtFontWeight(FontWeight fontWeight)
90 {
91     Rosen::FontWeight convertValue;
92     switch (fontWeight) {
93         case FontWeight::W100:
94         case FontWeight::LIGHTER:
95             convertValue = Rosen::FontWeight::W100;
96             break;
97         case FontWeight::W200:
98             convertValue = Rosen::FontWeight::W200;
99             break;
100         case FontWeight::W300:
101             convertValue = Rosen::FontWeight::W300;
102             break;
103         case FontWeight::W400:
104         case FontWeight::NORMAL:
105         case FontWeight::REGULAR:
106             convertValue = Rosen::FontWeight::W400;
107             break;
108         case FontWeight::W500:
109         case FontWeight::MEDIUM:
110             convertValue = Rosen::FontWeight::W500;
111             break;
112         case FontWeight::W600:
113             convertValue = Rosen::FontWeight::W600;
114             break;
115         case FontWeight::W700:
116         case FontWeight::BOLD:
117             convertValue = Rosen::FontWeight::W700;
118             break;
119         case FontWeight::W800:
120             convertValue = Rosen::FontWeight::W800;
121             break;
122         case FontWeight::W900:
123         case FontWeight::BOLDER:
124             convertValue = Rosen::FontWeight::W900;
125             break;
126         default:
127             TAG_LOGW(AceLogTag::ACE_FONT, "FontWeight setting error! Now using default FontWeight.");
128             convertValue = Rosen::FontWeight::W400;
129             break;
130     }
131     return convertValue;
132 }
133 #endif
134 
135 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtFontStyle(FontStyle fontStyle)136 txt::FontStyle ConvertTxtFontStyle(FontStyle fontStyle)
137 {
138     txt::FontStyle convertValue;
139     switch (fontStyle) {
140         case FontStyle::NORMAL:
141             convertValue = txt::FontStyle::normal;
142             break;
143         case FontStyle::ITALIC:
144             convertValue = txt::FontStyle::italic;
145             break;
146         default:
147             TAG_LOGW(AceLogTag::ACE_FONT, "FontStyle set error! use default FontStyle");
148             convertValue = txt::FontStyle::normal;
149             break;
150     }
151     return convertValue;
152 }
153 #else
ConvertTxtFontStyle(FontStyle fontStyle)154 Rosen::FontStyle ConvertTxtFontStyle(FontStyle fontStyle)
155 {
156     Rosen::FontStyle convertValue;
157     switch (fontStyle) {
158         case FontStyle::NORMAL:
159             convertValue = Rosen::FontStyle::NORMAL;
160             break;
161         case FontStyle::ITALIC:
162             convertValue = Rosen::FontStyle::ITALIC;
163             break;
164         default:
165             TAG_LOGW(AceLogTag::ACE_FONT, "FontStyle setting error! Now using default FontStyle");
166             convertValue = Rosen::FontStyle::NORMAL;
167             break;
168     }
169     return convertValue;
170 }
171 #endif
172 
173 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtTextBaseline(TextBaseline textBaseline)174 txt::TextBaseline ConvertTxtTextBaseline(TextBaseline textBaseline)
175 {
176     txt::TextBaseline convertValue;
177     switch (textBaseline) {
178         case TextBaseline::ALPHABETIC:
179             convertValue = txt::TextBaseline::kAlphabetic;
180             break;
181         case TextBaseline::IDEOGRAPHIC:
182             convertValue = txt::TextBaseline::kIdeographic;
183             break;
184         default:
185             convertValue = txt::TextBaseline::kAlphabetic;
186             break;
187     }
188     return convertValue;
189 }
190 #else
ConvertTxtTextBaseline(TextBaseline textBaseline)191 Rosen::TextBaseline ConvertTxtTextBaseline(TextBaseline textBaseline)
192 {
193     Rosen::TextBaseline convertValue;
194     switch (textBaseline) {
195         case TextBaseline::ALPHABETIC:
196             convertValue = Rosen::TextBaseline::ALPHABETIC;
197             break;
198         case TextBaseline::IDEOGRAPHIC:
199             convertValue = Rosen::TextBaseline::IDEOGRAPHIC;
200             break;
201         default:
202             convertValue = Rosen::TextBaseline::ALPHABETIC;
203             break;
204     }
205     return convertValue;
206 }
207 #endif
208 
209 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtTextAlign(TextAlign textAlign)210 txt::TextAlign ConvertTxtTextAlign(TextAlign textAlign)
211 {
212     txt::TextAlign convertValue;
213     switch (textAlign) {
214         case TextAlign::LEFT:
215             convertValue = txt::TextAlign::left;
216             break;
217         case TextAlign::RIGHT:
218             convertValue = txt::TextAlign::right;
219             break;
220         case TextAlign::CENTER:
221             convertValue = txt::TextAlign::center;
222             break;
223         case TextAlign::JUSTIFY:
224             convertValue = txt::TextAlign::justify;
225             break;
226         case TextAlign::START:
227             convertValue = txt::TextAlign::start;
228             break;
229         case TextAlign::END:
230             convertValue = txt::TextAlign::end;
231             break;
232         default:
233             TAG_LOGW(AceLogTag::ACE_FONT, "TextAlign set error! use default TextAlign");
234             convertValue = txt::TextAlign::start;
235             break;
236     }
237     return convertValue;
238 }
239 #else
ConvertTxtTextAlign(TextAlign textAlign)240 Rosen::TextAlign ConvertTxtTextAlign(TextAlign textAlign)
241 {
242     Rosen::TextAlign convertValue;
243     switch (textAlign) {
244         case TextAlign::LEFT:
245             convertValue = Rosen::TextAlign::LEFT;
246             break;
247         case TextAlign::RIGHT:
248             convertValue = Rosen::TextAlign::RIGHT;
249             break;
250         case TextAlign::CENTER:
251             convertValue = Rosen::TextAlign::CENTER;
252             break;
253         case TextAlign::JUSTIFY:
254             convertValue = Rosen::TextAlign::JUSTIFY;
255             break;
256         case TextAlign::START:
257             convertValue = Rosen::TextAlign::START;
258             break;
259         case TextAlign::END:
260             convertValue = Rosen::TextAlign::END;
261             break;
262         default:
263             TAG_LOGW(AceLogTag::ACE_FONT, "TextAlign setting error! Now using default TextAlign");
264             convertValue = Rosen::TextAlign::START;
265             break;
266     }
267     return convertValue;
268 }
269 #endif
270 
271 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtRectHeightStyle(RectHeightStyle heightStyle)272 txt::Paragraph::RectHeightStyle ConvertTxtRectHeightStyle(RectHeightStyle heightStyle)
273 {
274     switch (heightStyle) {
275         case RectHeightStyle::TIGHT:
276             return txt::Paragraph::RectHeightStyle::kTight;
277         case RectHeightStyle::MAX:
278             return txt::Paragraph::RectHeightStyle::kMax;
279         case RectHeightStyle::INCLUDE_LINE_SPACE_MIDDLE:
280             return txt::Paragraph::RectHeightStyle::kIncludeLineSpacingMiddle;
281         case RectHeightStyle::INCLUDE_LINE_SPACE_TOP:
282             return txt::Paragraph::RectHeightStyle::kIncludeLineSpacingTop;
283         case RectHeightStyle::INCLUDE_LINE_SPACE_BOTTOM:
284             return txt::Paragraph::RectHeightStyle::kIncludeLineSpacingBottom;
285         case RectHeightStyle::STRUT:
286             return txt::Paragraph::RectHeightStyle::kStrut;
287         default:
288             return txt::Paragraph::RectHeightStyle::kTight;
289     }
290 }
291 #else
ConvertTxtRectHeightStyle(RectHeightStyle heightStyle)292 Rosen::TextRectHeightStyle ConvertTxtRectHeightStyle(RectHeightStyle heightStyle)
293 {
294     switch (heightStyle) {
295         case RectHeightStyle::TIGHT:
296             return Rosen::TextRectHeightStyle::TIGHT;
297         case RectHeightStyle::MAX:
298             return Rosen::TextRectHeightStyle::COVER_TOP_AND_BOTTOM;
299         case RectHeightStyle::INCLUDE_LINE_SPACE_MIDDLE:
300             return Rosen::TextRectHeightStyle::COVER_HALF_TOP_AND_BOTTOM;
301         case RectHeightStyle::INCLUDE_LINE_SPACE_TOP:
302             return Rosen::TextRectHeightStyle::COVER_TOP;
303         case RectHeightStyle::INCLUDE_LINE_SPACE_BOTTOM:
304             return Rosen::TextRectHeightStyle::COVER_BOTTOM;
305         case RectHeightStyle::STRUT:
306             return Rosen::TextRectHeightStyle::FOLLOW_BY_STRUT;
307         default:
308             return Rosen::TextRectHeightStyle::TIGHT;
309     }
310 }
311 #endif
312 
313 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtRectWidthStyle(RectWidthStyle widthStyle)314 txt::Paragraph::RectWidthStyle ConvertTxtRectWidthStyle(RectWidthStyle widthStyle)
315 {
316     switch (widthStyle) {
317         case RectWidthStyle::TIGHT:
318             return txt::Paragraph::RectWidthStyle::kTight;
319         case RectWidthStyle::MAX:
320             return txt::Paragraph::RectWidthStyle::kMax;
321         default:
322             return txt::Paragraph::RectWidthStyle::kTight;
323     }
324 }
325 #else
ConvertTxtRectWidthStyle(RectWidthStyle widthStyle)326 Rosen::TextRectWidthStyle ConvertTxtRectWidthStyle(RectWidthStyle widthStyle)
327 {
328     switch (widthStyle) {
329         case RectWidthStyle::TIGHT:
330             return Rosen::TextRectWidthStyle::TIGHT;
331         case RectWidthStyle::MAX:
332             return Rosen::TextRectWidthStyle::MAX;
333         default:
334             return Rosen::TextRectWidthStyle::TIGHT;
335     }
336 }
337 #endif
338 
339 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtTextDirection(TextDirection textDirection)340 txt::TextDirection ConvertTxtTextDirection(TextDirection textDirection)
341 #else
342 Rosen::TextDirection ConvertTxtTextDirection(TextDirection textDirection)
343 #endif
344 {
345 #ifndef USE_GRAPHIC_TEXT_GINE
346     txt::TextDirection convertValue;
347 #else
348     Rosen::TextDirection convertValue;
349 #endif
350     switch (textDirection) {
351         case TextDirection::RTL:
352 #ifndef USE_GRAPHIC_TEXT_GINE
353             convertValue = txt::TextDirection::rtl;
354 #else
355             convertValue = Rosen::TextDirection::RTL;
356 #endif
357             break;
358         case TextDirection::LTR:
359 #ifndef USE_GRAPHIC_TEXT_GINE
360             convertValue = txt::TextDirection::ltr;
361 #else
362             convertValue = Rosen::TextDirection::LTR;
363 #endif
364             break;
365         default:
366             TAG_LOGW(AceLogTag::ACE_FONT, "TextDirection setting error! Now using default TextDirection");
367 #ifndef USE_GRAPHIC_TEXT_GINE
368             convertValue = txt::TextDirection::ltr;
369 #else
370             convertValue = Rosen::TextDirection::LTR;
371 #endif
372             break;
373     }
374     return convertValue;
375 }
376 
ConvertSkColor(Color color)377 SkColor ConvertSkColor(Color color)
378 {
379     return color.GetValue();
380 }
381 
382 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtTextDecoration(TextDecoration textDecoration)383 txt::TextDecoration ConvertTxtTextDecoration(TextDecoration textDecoration)
384 {
385     txt::TextDecoration convertValue = txt::TextDecoration::kNone;
386     switch (textDecoration) {
387         case TextDecoration::NONE:
388             convertValue = txt::TextDecoration::kNone;
389             break;
390         case TextDecoration::UNDERLINE:
391             convertValue = txt::TextDecoration::kUnderline;
392             break;
393         case TextDecoration::OVERLINE:
394             convertValue = txt::TextDecoration::kOverline;
395             break;
396         case TextDecoration::LINE_THROUGH:
397             convertValue = txt::TextDecoration::kLineThrough;
398             break;
399         default:
400             TAG_LOGW(AceLogTag::ACE_FONT, "TextDecoration set error! use default TextDecoration");
401             break;
402     }
403     return convertValue;
404 }
405 #else
ConvertTxtTextDecoration(TextDecoration textDecoration)406 Rosen::TextDecoration ConvertTxtTextDecoration(TextDecoration textDecoration)
407 {
408     Rosen::TextDecoration convertValue = Rosen::TextDecoration::NONE;
409     switch (textDecoration) {
410         case TextDecoration::NONE:
411             convertValue = Rosen::TextDecoration::NONE;
412             break;
413         case TextDecoration::UNDERLINE:
414             convertValue = Rosen::TextDecoration::UNDERLINE;
415             break;
416         case TextDecoration::OVERLINE:
417             convertValue = Rosen::TextDecoration::OVERLINE;
418             break;
419         case TextDecoration::LINE_THROUGH:
420             convertValue = Rosen::TextDecoration::LINE_THROUGH;
421             break;
422         default:
423             TAG_LOGW(AceLogTag::ACE_FONT, "TextDecoration setting error! Now using default TextDecoration");
424             break;
425     }
426     return convertValue;
427 }
428 #endif
429 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)430 txt::TextDecorationStyle ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)
431 {
432     txt::TextDecorationStyle convertValue = txt::TextDecorationStyle::kSolid;
433     switch (textDecorationStyle) {
434         case TextDecorationStyle::SOLID:
435             convertValue = txt::TextDecorationStyle::kSolid;
436             break;
437         case TextDecorationStyle::DOUBLE:
438             convertValue = txt::TextDecorationStyle::kDouble;
439             break;
440         case TextDecorationStyle::DOTTED:
441             convertValue = txt::TextDecorationStyle::kDotted;
442             break;
443         case TextDecorationStyle::DASHED:
444             convertValue = txt::TextDecorationStyle::kDashed;
445             break;
446         case TextDecorationStyle::WAVY:
447             convertValue = txt::TextDecorationStyle::kWavy;
448             break;
449         default:
450             TAG_LOGW(AceLogTag::ACE_FONT, "TextDecorationStyle set error! use default TextDecorationStyle");
451             break;
452     }
453     return convertValue;
454 }
455 #else
ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)456 Rosen::TextDecorationStyle ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)
457 {
458     Rosen::TextDecorationStyle convertValue = Rosen::TextDecorationStyle::SOLID;
459     switch (textDecorationStyle) {
460         case TextDecorationStyle::SOLID:
461             convertValue = Rosen::TextDecorationStyle::SOLID;
462             break;
463         case TextDecorationStyle::DOUBLE:
464             convertValue = Rosen::TextDecorationStyle::DOUBLE;
465             break;
466         case TextDecorationStyle::DOTTED:
467             convertValue = Rosen::TextDecorationStyle::DOTTED;
468             break;
469         case TextDecorationStyle::DASHED:
470             convertValue = Rosen::TextDecorationStyle::DASHED;
471             break;
472         case TextDecorationStyle::WAVY:
473             convertValue = Rosen::TextDecorationStyle::WAVY;
474             break;
475         default:
476             TAG_LOGW(AceLogTag::ACE_FONT, "TextDecorationStyle setting error! Now using default TextDecorationStyle");
477             break;
478     }
479     return convertValue;
480 }
481 #endif
482 
483 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtStyle(const TextStyle & textStyle,const WeakPtr<PipelineBase> & context,txt::TextStyle & txtStyle)484 void ConvertTxtStyle(const TextStyle& textStyle, const WeakPtr<PipelineBase>& context, txt::TextStyle& txtStyle)
485 {
486     txtStyle.color = ConvertSkColor(textStyle.GetTextColor());
487     txtStyle.font_weight = ConvertTxtFontWeight(textStyle.GetFontWeight());
488     auto fontWeightValue = (static_cast<int32_t>(
489             ConvertTxtFontWeight(textStyle.GetFontWeight())) + 1) * DEFAULT_MULTIPLE;
490     auto pipelineContext = context.Upgrade();
491     if (pipelineContext) {
492         fontWeightValue = fontWeightValue * pipelineContext->GetFontWeightScale();
493     }
494     if (textStyle.GetEnableVariableFontWeight()) {
495         fontWeightValue = textStyle.GetVariableFontWeight();
496         if (LessNotEqual(fontWeightValue, MIN_FONT_WEIGHT) || GreatNotEqual(fontWeightValue, MAX_FONT_WEIGHT)) {
497             fontWeightValue = DEFAULT_FONT_WEIGHT;
498         }
499     }
500     txtStyle.fontVariations.SetAxisValue(FONTWEIGHT, fontWeightValue);
501     // Font size must be px when transferring to txt::TextStyle
502     if (pipelineContext) {
503         txtStyle.font_size = pipelineContext->NormalizeToPx(textStyle.GetFontSize());
504         if (textStyle.IsAllowScale() && textStyle.GetFontSize().Unit() == DimensionUnit::FP) {
505             txtStyle.font_size =
506                 pipelineContext->NormalizeToPx(textStyle.GetFontSize() * pipelineContext->GetFontScale());
507         }
508     } else {
509         txtStyle.font_size = textStyle.GetFontSize().Value();
510     }
511     txtStyle.font_style = ConvertTxtFontStyle(textStyle.GetFontStyle());
512 
513     if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
514         txtStyle.word_spacing = textStyle.GetWordSpacing().Value() * txtStyle.font_size;
515     } else {
516         if (pipelineContext) {
517             txtStyle.word_spacing = pipelineContext->NormalizeToPx(textStyle.GetWordSpacing());
518         } else {
519             txtStyle.word_spacing = textStyle.GetWordSpacing().Value();
520         }
521     }
522     if (pipelineContext) {
523         txtStyle.letter_spacing = pipelineContext->NormalizeToPx(textStyle.GetLetterSpacing());
524     }
525     txtStyle.text_baseline = ConvertTxtTextBaseline(textStyle.GetTextBaseline());
526     txtStyle.decoration = ConvertTxtTextDecoration(textStyle.GetTextDecoration());
527     txtStyle.decoration_style = ConvertTxtTextDecorationStyle(textStyle.GetTextDecorationStyle());
528     txtStyle.decoration_color = ConvertSkColor(textStyle.GetTextDecorationColor());
529     txtStyle.font_families = textStyle.GetFontFamilies();
530     txtStyle.locale = Localization::GetInstance()->GetFontLocale();
531     txtStyle.half_leading = textStyle.GetHalfLeading();
532 
533     for (auto& spanShadow : textStyle.GetTextShadows()) {
534         txt::TextShadow txtShadow;
535         txtShadow.color = spanShadow.GetColor().GetValue();
536 #ifndef USE_ROSEN_DRAWING
537         txtShadow.offset.fX = static_cast<SkScalar>(spanShadow.GetOffset().GetX());
538         txtShadow.offset.fY = static_cast<SkScalar>(spanShadow.GetOffset().GetY());
539 #else
540         txtShadow.offset.SetX(static_cast<SkScalar>(spanShadow.GetOffset().GetX()));
541         txtShadow.offset.SetY(static_cast<SkScalar>(spanShadow.GetOffset().GetY()));
542 #endif
543         txtShadow.blur_sigma = spanShadow.GetBlurRadius();
544 
545         txtStyle.text_shadows.emplace_back(txtShadow);
546     }
547 
548     if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
549         txtStyle.has_height_override = true;
550         txtStyle.height = textStyle.GetLineHeight().Value();
551     } else {
552         double fontSize = txtStyle.font_size;
553         double lineHeight = textStyle.GetLineHeight().Value();
554         if (pipelineContext) {
555             lineHeight = pipelineContext->NormalizeToPx(textStyle.GetLineHeight());
556         }
557         txtStyle.has_height_override = textStyle.HasHeightOverride();
558         if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
559             txtStyle.height = lineHeight / fontSize;
560         } else {
561             txtStyle.height = 1;
562             static const int32_t BEGIN_VERSION = 6;
563             auto isBeginVersion = pipelineContext && pipelineContext->GetMinPlatformVersion() >= BEGIN_VERSION;
564             if (NearZero(lineHeight) || (!isBeginVersion && NearEqual(lineHeight, fontSize))) {
565                 txtStyle.has_height_override = false;
566             }
567         }
568     }
569 
570     // set font variant
571     auto fontFeatures = textStyle.GetFontFeatures();
572     if (!fontFeatures.empty()) {
573         txt::FontFeatures features;
574         for (auto iter = fontFeatures.begin(); iter != fontFeatures.end(); ++iter) {
575             features.SetFeature(iter->first, iter->second);
576         }
577         txtStyle.font_features = features;
578     }
579 }
580 
ConvertTxtStyle(const TextStyle & textStyle,txt::TextStyle & txtStyle)581 void ConvertTxtStyle(const TextStyle& textStyle, txt::TextStyle& txtStyle) {}
582 
ConvertSymbolTxtStyle(const TextStyle & textStyle,txt::TextStyle & txtStyle)583 void ConvertSymbolTxtStyle(const TextStyle& textStyle, txt::TextStyle& txtStyle)
584 {
585     if (!textStyle.isSymbolGlyph_) {
586         return;
587     }
588 
589     txtStyle.isSymbolGlyph = true;
590     const std::vector<Color>& symbolColor = textStyle.GetSymbolColorList();
591     std::vector<Rosen::Drawing::Color> symbolColors;
592     for (size_t i = 0; i < symbolColor.size(); i++) {
593         symbolColors.emplace_back(ConvertSkColor(symbolColor[i]));
594     }
595     txtStyle.symbol.SetRenderColor(symbolColors);
596     txtStyle.symbol.SetRenderMode(textStyle.GetRenderStrategy());
597     if (textStyle.GetSymbolEffectOptions().has_value()) {
598         auto options = textStyle.GetSymbolEffectOptions().value();
599         auto effectType = options.GetEffectType();
600         txtStyle.symbol.SetSymbolEffect(static_cast<uint32_t>(effectType));
601         if (effectType == SymbolEffectType::HIERARCHICAL && options.GetFillStyle().has_value()) {
602             txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetFillStyle().value()));
603         } else {
604             if (options.GetScopeType().has_value()) {
605                 txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetScopeType().value()));
606             }
607         }
608         if (options.GetCommonSubType().has_value()) {
609             auto commonType = static_cast<uint16_t>(options.GetCommonSubType().value());
610             txtStyle.symbol.SetCommonSubType(commonType == 1 ? Rosen::Drawing::DrawingCommonSubType::UP
611                                                              : Rosen::Drawing::DrawingCommonSubType::DOWN);
612         }
613         txtStyle.symbol.SetAnimationStart(options.GetIsTxtActive());
614     } else {
615         auto effectStrategy = textStyle.GetEffectStrategy();
616         if (effectStrategy < NONE_EFFECT || effectStrategy > SCALE_EFFECT) {
617             effectStrategy = NONE_EFFECT;
618         }
619         txtStyle.symbol.SetSymbolEffect(effectStrategy);
620         txtStyle.symbol.SetAnimationStart(true);
621     }
622     txtStyle.fontFamilies.push_back("HM Symbol");
623 }
624 #else
NormalizeToPx(const Dimension & dimension)625 double NormalizeToPx(const Dimension& dimension)
626 {
627     if ((dimension.Unit() == DimensionUnit::VP) || (dimension.Unit() == DimensionUnit::FP)) {
628         return (dimension.Value() * SystemProperties::GetResolution());
629     }
630     return dimension.Value();
631 }
632 
ConvertTxtStyle(const TextStyle & textStyle,Rosen::TextStyle & txtStyle)633 void ConvertTxtStyle(const TextStyle& textStyle, Rosen::TextStyle& txtStyle)
634 {
635     txtStyle.color = ConvertSkColor(textStyle.GetTextColor());
636     txtStyle.fontWeight = ConvertTxtFontWeight(textStyle.GetFontWeight());
637 
638     txtStyle.fontSize = NormalizeToPx(textStyle.GetFontSize());
639 
640     txtStyle.fontStyle = ConvertTxtFontStyle(textStyle.GetFontStyle());
641 
642     if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
643         txtStyle.wordSpacing = textStyle.GetWordSpacing().Value() * txtStyle.fontSize;
644     } else {
645         txtStyle.wordSpacing = NormalizeToPx(textStyle.GetWordSpacing());
646     }
647 
648     txtStyle.letterSpacing = NormalizeToPx(textStyle.GetLetterSpacing());
649     txtStyle.baseLineShift = -NormalizeToPx(textStyle.GetBaselineOffset());
650     txtStyle.fontFamilies = textStyle.GetFontFamilies();
651     ConvertSymbolTxtStyle(textStyle, txtStyle);
652     txtStyle.baseline = ConvertTxtTextBaseline(textStyle.GetTextBaseline());
653     txtStyle.decoration = ConvertTxtTextDecoration(textStyle.GetTextDecoration());
654     txtStyle.decorationColor = ConvertSkColor(textStyle.GetTextDecorationColor());
655     txtStyle.decorationStyle = ConvertTxtTextDecorationStyle(textStyle.GetTextDecorationStyle());
656     txtStyle.locale = Localization::GetInstance()->GetFontLocale();
657     txtStyle.halfLeading = textStyle.GetHalfLeading();
658 
659     for (auto& spanShadow : textStyle.GetTextShadows()) {
660         Rosen::TextShadow txtShadow;
661         txtShadow.color = spanShadow.GetColor().GetValue();
662         txtShadow.offset.SetX(spanShadow.GetOffset().GetX());
663         txtShadow.offset.SetY(spanShadow.GetOffset().GetY());
664         txtShadow.blurRadius = spanShadow.GetBlurRadius();
665         txtStyle.shadows.emplace_back(txtShadow);
666     }
667 
668     if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
669         txtStyle.heightOnly = true;
670         txtStyle.heightScale = textStyle.GetLineHeight().Value();
671     } else {
672         double fontSize = txtStyle.fontSize;
673         double lineHeight = textStyle.GetLineHeight().Value();
674 
675         lineHeight = NormalizeToPx(textStyle.GetLineHeight());
676 
677         txtStyle.heightOnly = textStyle.HasHeightOverride();
678         if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
679             txtStyle.heightScale = lineHeight / fontSize;
680         } else {
681             txtStyle.heightScale = 1;
682             if (NearZero(lineHeight) || NearEqual(lineHeight, fontSize)) {
683                 txtStyle.heightOnly = false;
684             }
685         }
686     }
687 
688     // set font variant
689     auto fontFeatures = textStyle.GetFontFeatures();
690     if (!fontFeatures.empty()) {
691         Rosen::FontFeatures features;
692         for (auto iter = fontFeatures.begin(); iter != fontFeatures.end(); ++iter) {
693             features.SetFeature(iter->first, iter->second);
694         }
695         txtStyle.fontFeatures = features;
696     }
697     auto textBackgroundStyle = textStyle.GetTextBackgroundStyle();
698     CHECK_NULL_VOID(textBackgroundStyle.has_value());
699     txtStyle.styleId = textBackgroundStyle->groupId;
700     if (textBackgroundStyle->backgroundColor.has_value()) {
701         txtStyle.backgroundRect.color = textBackgroundStyle->backgroundColor.value().GetValue();
702     }
703     auto radius = textBackgroundStyle->backgroundRadius;
704     CHECK_NULL_VOID(radius.has_value());
705     auto radiusConverter = [](const std::optional<Dimension>& radius) -> double {
706         CHECK_NULL_RETURN(radius.has_value(), 0);
707         return NormalizeToPx(radius.value());
708     };
709     txtStyle.backgroundRect.leftTopRadius = radiusConverter(radius->radiusTopLeft);
710     txtStyle.backgroundRect.rightTopRadius = radiusConverter(radius->radiusTopRight);
711     txtStyle.backgroundRect.leftBottomRadius = radiusConverter(radius->radiusBottomLeft);
712     txtStyle.backgroundRect.rightBottomRadius = radiusConverter(radius->radiusBottomRight);
713 }
714 
ConvertTxtStyle(const TextStyle & textStyle,const WeakPtr<PipelineBase> & context,Rosen::TextStyle & txtStyle)715 void ConvertTxtStyle(const TextStyle& textStyle, const WeakPtr<PipelineBase>& context, Rosen::TextStyle& txtStyle)
716 {
717     txtStyle.color = ConvertSkColor(textStyle.GetTextColor());
718     txtStyle.fontWeight = ConvertTxtFontWeight(textStyle.GetFontWeight());
719     auto fontWeightValue = (static_cast<int32_t>(
720             ConvertTxtFontWeight(textStyle.GetFontWeight())) + 1) * DEFAULT_MULTIPLE;
721     auto pipelineContext = context.Upgrade();
722     if (pipelineContext) {
723         fontWeightValue = fontWeightValue * pipelineContext->GetFontWeightScale();
724     }
725     if (textStyle.GetEnableVariableFontWeight()) {
726         fontWeightValue = textStyle.GetVariableFontWeight();
727         if (LessNotEqual(fontWeightValue, MIN_FONT_WEIGHT) || GreatNotEqual(fontWeightValue, MAX_FONT_WEIGHT)) {
728             fontWeightValue = DEFAULT_FONT_WEIGHT;
729         }
730     }
731     txtStyle.fontVariations.SetAxisValue(FONTWEIGHT, fontWeightValue);
732     // Font size must be px when transferring to Rosen::TextStyle
733     txtStyle.fontSize = textStyle.GetFontSize().ConvertToPxDistribute(
734         textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
735     txtStyle.fontStyle = ConvertTxtFontStyle(textStyle.GetFontStyle());
736 
737     if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
738         txtStyle.wordSpacing = textStyle.GetWordSpacing().Value() * txtStyle.fontSize;
739     } else {
740         if (pipelineContext) {
741             txtStyle.wordSpacing = textStyle.GetWordSpacing().ConvertToPxDistribute(
742                 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
743         } else {
744             txtStyle.wordSpacing = textStyle.GetWordSpacing().Value();
745         }
746     }
747     if (pipelineContext) {
748         txtStyle.letterSpacing = textStyle.GetLetterSpacing().ConvertToPxDistribute(
749             textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
750         txtStyle.baseLineShift = -textStyle.GetBaselineOffset().ConvertToPxDistribute(
751             textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
752     }
753 
754     txtStyle.fontFamilies = textStyle.GetFontFamilies();
755     ConvertSymbolTxtStyle(textStyle, txtStyle);
756     txtStyle.baseline = ConvertTxtTextBaseline(textStyle.GetTextBaseline());
757     txtStyle.decoration = ConvertTxtTextDecoration(textStyle.GetTextDecoration());
758     txtStyle.decorationColor = ConvertSkColor(textStyle.GetTextDecorationColor());
759     txtStyle.decorationStyle = ConvertTxtTextDecorationStyle(textStyle.GetTextDecorationStyle());
760     txtStyle.locale = Localization::GetInstance()->GetFontLocale();
761     txtStyle.halfLeading = textStyle.GetHalfLeading();
762 
763     for (auto& spanShadow : textStyle.GetTextShadows()) {
764         Rosen::TextShadow txtShadow;
765         txtShadow.color = spanShadow.GetColor().GetValue();
766         txtShadow.offset.SetX(spanShadow.GetOffset().GetX());
767         txtShadow.offset.SetY(spanShadow.GetOffset().GetY());
768         txtShadow.blurRadius = spanShadow.GetBlurRadius();
769         txtStyle.shadows.emplace_back(txtShadow);
770     }
771 
772     double lineHeightScale = 0.0;
773     double lineSpacingScale = 0.0;
774     bool lineHeightOnly = false;
775     bool lineSpacingOnly = false;
776     if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
777         lineHeightOnly = true;
778         lineHeightScale = textStyle.GetLineHeight().Value();
779     } else {
780         double fontSize = txtStyle.fontSize;
781         double lineHeight = textStyle.GetLineHeight().Value();
782         if (pipelineContext) {
783             lineHeight = textStyle.GetLineHeight().ConvertToPxDistribute(
784                 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
785         }
786         lineHeightOnly = textStyle.HasHeightOverride();
787         if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
788             lineHeightScale = lineHeight / fontSize;
789         } else {
790             lineHeightScale = 1;
791             static const int32_t BEGIN_VERSION = 6;
792             auto isBeginVersion = pipelineContext && pipelineContext->GetMinPlatformVersion() >= BEGIN_VERSION;
793             if (NearZero(lineHeight) || (!isBeginVersion && NearEqual(lineHeight, fontSize))) {
794                 lineHeightOnly = false;
795             }
796         }
797     }
798     if (textStyle.GetLineSpacing().Unit() == DimensionUnit::PERCENT) {
799         lineSpacingOnly = true;
800         lineSpacingScale = textStyle.GetLineSpacing().Value();
801     } else {
802         double fontSize = txtStyle.fontSize;
803         double lineSpacing = textStyle.GetLineSpacing().Value();
804         if (pipelineContext) {
805             lineSpacing = textStyle.GetLineSpacing().ConvertToPxDistribute(
806                 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
807         }
808         lineSpacingOnly = true;
809         if (!NearEqual(lineSpacing, fontSize) && (lineSpacing > 0.0) && (!NearZero(fontSize))) {
810             lineSpacingScale = lineSpacing / fontSize;
811         } else {
812             lineSpacingScale = 1;
813             if (NearZero(lineSpacing)) {
814                 lineSpacingOnly = false;
815             }
816         }
817     }
818 
819     txtStyle.heightOnly = lineHeightOnly || lineSpacingOnly;
820     if (lineHeightOnly && lineSpacingOnly) {
821         txtStyle.heightScale = lineHeightScale + lineSpacingScale;
822     } else if (lineHeightOnly && !lineSpacingOnly) {
823         txtStyle.heightScale = lineHeightScale;
824     } else if (!lineHeightOnly && lineSpacingOnly) {
825         txtStyle.heightScale = ORIGINAL_LINE_HEIGHT_SCALE + lineSpacingScale;
826     } else {
827         txtStyle.heightScale = 1;
828     }
829 
830     // set font variant
831     auto fontFeatures = textStyle.GetFontFeatures();
832     if (!fontFeatures.empty()) {
833         Rosen::FontFeatures features;
834         for (auto iter = fontFeatures.begin(); iter != fontFeatures.end(); ++iter) {
835             features.SetFeature(iter->first, iter->second);
836         }
837         txtStyle.fontFeatures = features;
838     }
839     auto textBackgroundStyle = textStyle.GetTextBackgroundStyle();
840     CHECK_NULL_VOID(textBackgroundStyle.has_value());
841     txtStyle.styleId = textBackgroundStyle->groupId;
842     if (textBackgroundStyle->backgroundColor.has_value()) {
843         txtStyle.backgroundRect.color = textBackgroundStyle->backgroundColor.value().GetValue();
844     }
845     auto radius = textBackgroundStyle->backgroundRadius;
846     CHECK_NULL_VOID(radius.has_value());
847     auto radiusConverter = [context = pipelineContext, textStyle](const std::optional<Dimension>& radius) -> double {
848         CHECK_NULL_RETURN(radius.has_value(), 0);
849         CHECK_NULL_RETURN(context, radius->Value());
850         return radius.value().ConvertToPxDistribute(
851             textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
852     };
853     txtStyle.backgroundRect.leftTopRadius = radiusConverter(radius->radiusTopLeft);
854     txtStyle.backgroundRect.rightTopRadius = radiusConverter(radius->radiusTopRight);
855     txtStyle.backgroundRect.leftBottomRadius = radiusConverter(radius->radiusBottomLeft);
856     txtStyle.backgroundRect.rightBottomRadius = radiusConverter(radius->radiusBottomRight);
857 }
858 
ConvertSymbolTxtStyle(const TextStyle & textStyle,Rosen::TextStyle & txtStyle)859 void ConvertSymbolTxtStyle(const TextStyle& textStyle, Rosen::TextStyle& txtStyle)
860 {
861     if (!textStyle.isSymbolGlyph_) {
862         return;
863     }
864 
865     txtStyle.isSymbolGlyph = true;
866     txtStyle.symbol.SetRenderMode(textStyle.GetRenderStrategy());
867     const std::vector<Color>& symbolColor = textStyle.GetSymbolColorList();
868     std::vector<Rosen::Drawing::Color> symbolColors;
869     for (size_t i = 0; i < symbolColor.size(); i++) {
870         symbolColors.emplace_back(ConvertSkColor(symbolColor[i]));
871     }
872     txtStyle.symbol.SetRenderColor(symbolColors);
873     if (textStyle.GetSymbolEffectOptions().has_value()) {
874         auto options = textStyle.GetSymbolEffectOptions().value();
875         auto effectType = options.GetEffectType();
876         txtStyle.symbol.SetSymbolEffect(static_cast<uint32_t>(effectType));
877         txtStyle.symbol.SetAnimationStart(options.GetIsTxtActive());
878         if (options.GetCommonSubType().has_value()) {
879             auto commonType = static_cast<uint16_t>(options.GetCommonSubType().value());
880             txtStyle.symbol.SetCommonSubType(commonType == 1 ? Rosen::Drawing::DrawingCommonSubType::UP
881                                                              : Rosen::Drawing::DrawingCommonSubType::DOWN);
882         }
883         if (effectType == SymbolEffectType::HIERARCHICAL && options.GetFillStyle().has_value()) {
884             txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetFillStyle().value()));
885         } else {
886             if (options.GetScopeType().has_value()) {
887                 txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetScopeType().value()));
888             }
889         }
890     } else {
891         auto effectStrategyValue = textStyle.GetEffectStrategy();
892         if (effectStrategyValue < NONE_EFFECT || effectStrategyValue > SCALE_EFFECT) {
893             effectStrategyValue = NONE_EFFECT;
894         }
895         txtStyle.symbol.SetSymbolEffect(effectStrategyValue);
896         txtStyle.symbol.SetAnimationStart(true);
897     }
898     txtStyle.fontFamilies.push_back("HM Symbol");
899 }
900 #endif
901 
902 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertSkRect(SkRect skRect)903 Rect ConvertSkRect(SkRect skRect)
904 {
905     Rect result;
906     result.SetLeft(skRect.fLeft);
907     result.SetTop(skRect.fTop);
908     result.SetWidth(skRect.width());
909     result.SetHeight(skRect.height());
910     return result;
911 }
912 #else
ConvertSkRect(const Rosen::Drawing::RectF & skRect)913 Rect ConvertSkRect(const Rosen::Drawing::RectF& skRect)
914 {
915     Rect result;
916     result.SetLeft(skRect.GetLeft());
917     result.SetTop(skRect.GetTop());
918     result.SetWidth(skRect.GetWidth());
919     result.SetHeight(skRect.GetHeight());
920     return result;
921 }
922 #endif
923 
924 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)925 txt::PlaceholderAlignment ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)
926 {
927     txt::PlaceholderAlignment convertValue = txt::PlaceholderAlignment::kBaseline;
928     switch (textDecoration) {
929         case PlaceholderAlignment::BASELINE:
930             convertValue = txt::PlaceholderAlignment::kBaseline;
931             break;
932         case PlaceholderAlignment::ABOVEBASELINE:
933             convertValue = txt::PlaceholderAlignment::kAboveBaseline;
934             break;
935         case PlaceholderAlignment::BELOWBASELINE:
936             convertValue = txt::PlaceholderAlignment::kBelowBaseline;
937             break;
938         case PlaceholderAlignment::TOP:
939             convertValue = txt::PlaceholderAlignment::kTop;
940             break;
941         case PlaceholderAlignment::BOTTOM:
942             convertValue = txt::PlaceholderAlignment::kBottom;
943             break;
944         case PlaceholderAlignment::MIDDLE:
945             convertValue = txt::PlaceholderAlignment::kMiddle;
946             break;
947         default:
948             TAG_LOGW(AceLogTag::ACE_FONT, "PlaceholderAlignment set error! use default PlaceholderAlignment");
949             break;
950     }
951     return convertValue;
952 }
953 #else
ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)954 Rosen::PlaceholderVerticalAlignment ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)
955 {
956     Rosen::PlaceholderVerticalAlignment convertValue = Rosen::PlaceholderVerticalAlignment::OFFSET_AT_BASELINE;
957     switch (textDecoration) {
958         case PlaceholderAlignment::BASELINE:
959             convertValue = Rosen::PlaceholderVerticalAlignment::OFFSET_AT_BASELINE;
960             break;
961         case PlaceholderAlignment::ABOVEBASELINE:
962             convertValue = Rosen::PlaceholderVerticalAlignment::ABOVE_BASELINE;
963             break;
964         case PlaceholderAlignment::BELOWBASELINE:
965             convertValue = Rosen::PlaceholderVerticalAlignment::BELOW_BASELINE;
966             break;
967         case PlaceholderAlignment::TOP:
968             convertValue = Rosen::PlaceholderVerticalAlignment::TOP_OF_ROW_BOX;
969             break;
970         case PlaceholderAlignment::BOTTOM:
971             convertValue = Rosen::PlaceholderVerticalAlignment::BOTTOM_OF_ROW_BOX;
972             break;
973         case PlaceholderAlignment::MIDDLE:
974             convertValue = Rosen::PlaceholderVerticalAlignment::CENTER_OF_ROW_BOX;
975             break;
976         default:
977             TAG_LOGW(AceLogTag::ACE_FONT, "PlaceholderAlignment setting error! Now using default PlaceholderAlignment");
978             break;
979     }
980     return convertValue;
981 }
982 #endif
983 
984 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertPlaceholderRun(const PlaceholderRun & span,txt::PlaceholderRun & txtSpan)985 void ConvertPlaceholderRun(const PlaceholderRun& span, txt::PlaceholderRun& txtSpan)
986 #else
987 void ConvertPlaceholderRun(const PlaceholderRun& span, Rosen::PlaceholderSpan& txtSpan)
988 #endif
989 {
990     txtSpan.width = span.width;
991     txtSpan.height = span.height;
992     txtSpan.alignment = ConvertPlaceholderAlignment(span.alignment);
993     txtSpan.baseline = ConvertTxtTextBaseline(span.baseline);
994 #ifndef USE_GRAPHIC_TEXT_GINE
995     txtSpan.baseline_offset = span.baseline_offset;
996 #else
997     txtSpan.baselineOffset = span.baseline_offset;
998 #endif
999 }
1000 
1001 } // namespace OHOS::Ace::Constants
1002