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
ConvertTxtTextDirection(TextDirection textDirection)272 txt::TextDirection ConvertTxtTextDirection(TextDirection textDirection)
273 #else
274 Rosen::TextDirection ConvertTxtTextDirection(TextDirection textDirection)
275 #endif
276 {
277 #ifndef USE_GRAPHIC_TEXT_GINE
278 txt::TextDirection convertValue;
279 #else
280 Rosen::TextDirection convertValue;
281 #endif
282 switch (textDirection) {
283 case TextDirection::RTL:
284 #ifndef USE_GRAPHIC_TEXT_GINE
285 convertValue = txt::TextDirection::rtl;
286 #else
287 convertValue = Rosen::TextDirection::RTL;
288 #endif
289 break;
290 case TextDirection::LTR:
291 #ifndef USE_GRAPHIC_TEXT_GINE
292 convertValue = txt::TextDirection::ltr;
293 #else
294 convertValue = Rosen::TextDirection::LTR;
295 #endif
296 break;
297 default:
298 TAG_LOGW(AceLogTag::ACE_FONT, "TextDirection setting error! Now using default TextDirection");
299 #ifndef USE_GRAPHIC_TEXT_GINE
300 convertValue = txt::TextDirection::ltr;
301 #else
302 convertValue = Rosen::TextDirection::LTR;
303 #endif
304 break;
305 }
306 return convertValue;
307 }
308
ConvertSkColor(Color color)309 SkColor ConvertSkColor(Color color)
310 {
311 return color.GetValue();
312 }
313
314 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtTextDecoration(TextDecoration textDecoration)315 txt::TextDecoration ConvertTxtTextDecoration(TextDecoration textDecoration)
316 {
317 txt::TextDecoration convertValue = txt::TextDecoration::kNone;
318 switch (textDecoration) {
319 case TextDecoration::NONE:
320 convertValue = txt::TextDecoration::kNone;
321 break;
322 case TextDecoration::UNDERLINE:
323 convertValue = txt::TextDecoration::kUnderline;
324 break;
325 case TextDecoration::OVERLINE:
326 convertValue = txt::TextDecoration::kOverline;
327 break;
328 case TextDecoration::LINE_THROUGH:
329 convertValue = txt::TextDecoration::kLineThrough;
330 break;
331 default:
332 TAG_LOGW(AceLogTag::ACE_FONT, "TextDecoration set error! use default TextDecoration");
333 break;
334 }
335 return convertValue;
336 }
337 #else
ConvertTxtTextDecoration(TextDecoration textDecoration)338 Rosen::TextDecoration ConvertTxtTextDecoration(TextDecoration textDecoration)
339 {
340 Rosen::TextDecoration convertValue = Rosen::TextDecoration::NONE;
341 switch (textDecoration) {
342 case TextDecoration::NONE:
343 convertValue = Rosen::TextDecoration::NONE;
344 break;
345 case TextDecoration::UNDERLINE:
346 convertValue = Rosen::TextDecoration::UNDERLINE;
347 break;
348 case TextDecoration::OVERLINE:
349 convertValue = Rosen::TextDecoration::OVERLINE;
350 break;
351 case TextDecoration::LINE_THROUGH:
352 convertValue = Rosen::TextDecoration::LINE_THROUGH;
353 break;
354 default:
355 TAG_LOGW(AceLogTag::ACE_FONT, "TextDecoration setting error! Now using default TextDecoration");
356 break;
357 }
358 return convertValue;
359 }
360 #endif
361 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)362 txt::TextDecorationStyle ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)
363 {
364 txt::TextDecorationStyle convertValue = txt::TextDecorationStyle::kSolid;
365 switch (textDecorationStyle) {
366 case TextDecorationStyle::SOLID:
367 convertValue = txt::TextDecorationStyle::kSolid;
368 break;
369 case TextDecorationStyle::DOUBLE:
370 convertValue = txt::TextDecorationStyle::kDouble;
371 break;
372 case TextDecorationStyle::DOTTED:
373 convertValue = txt::TextDecorationStyle::kDotted;
374 break;
375 case TextDecorationStyle::DASHED:
376 convertValue = txt::TextDecorationStyle::kDashed;
377 break;
378 case TextDecorationStyle::WAVY:
379 convertValue = txt::TextDecorationStyle::kWavy;
380 break;
381 default:
382 TAG_LOGW(AceLogTag::ACE_FONT, "TextDecorationStyle set error! use default TextDecorationStyle");
383 break;
384 }
385 return convertValue;
386 }
387 #else
ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)388 Rosen::TextDecorationStyle ConvertTxtTextDecorationStyle(TextDecorationStyle textDecorationStyle)
389 {
390 Rosen::TextDecorationStyle convertValue = Rosen::TextDecorationStyle::SOLID;
391 switch (textDecorationStyle) {
392 case TextDecorationStyle::SOLID:
393 convertValue = Rosen::TextDecorationStyle::SOLID;
394 break;
395 case TextDecorationStyle::DOUBLE:
396 convertValue = Rosen::TextDecorationStyle::DOUBLE;
397 break;
398 case TextDecorationStyle::DOTTED:
399 convertValue = Rosen::TextDecorationStyle::DOTTED;
400 break;
401 case TextDecorationStyle::DASHED:
402 convertValue = Rosen::TextDecorationStyle::DASHED;
403 break;
404 case TextDecorationStyle::WAVY:
405 convertValue = Rosen::TextDecorationStyle::WAVY;
406 break;
407 default:
408 TAG_LOGW(AceLogTag::ACE_FONT, "TextDecorationStyle setting error! Now using default TextDecorationStyle");
409 break;
410 }
411 return convertValue;
412 }
413 #endif
414
415 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertTxtStyle(const TextStyle & textStyle,const WeakPtr<PipelineBase> & context,txt::TextStyle & txtStyle)416 void ConvertTxtStyle(const TextStyle& textStyle, const WeakPtr<PipelineBase>& context, txt::TextStyle& txtStyle)
417 {
418 txtStyle.color = ConvertSkColor(textStyle.GetTextColor());
419 txtStyle.font_weight = ConvertTxtFontWeight(textStyle.GetFontWeight());
420 auto fontWeightValue = (static_cast<int32_t>(
421 ConvertTxtFontWeight(textStyle.GetFontWeight())) + 1) * DEFAULT_MULTIPLE;
422 auto pipelineContext = context.Upgrade();
423 if (pipelineContext) {
424 fontWeightValue = fontWeightValue * pipelineContext->GetFontWeightScale();
425 }
426 if (textStyle.GetEnableVariableFontWeight()) {
427 fontWeightValue = textStyle.GetVariableFontWeight();
428 if (LessNotEqual(fontWeightValue, MIN_FONT_WEIGHT) || GreatNotEqual(fontWeightValue, MAX_FONT_WEIGHT)) {
429 fontWeightValue = DEFAULT_FONT_WEIGHT;
430 }
431 }
432 txtStyle.fontVariations.SetAxisValue(FONTWEIGHT, fontWeightValue);
433 // Font size must be px when transferring to txt::TextStyle
434 if (pipelineContext) {
435 txtStyle.font_size = pipelineContext->NormalizeToPx(textStyle.GetFontSize());
436 if (textStyle.IsAllowScale() && textStyle.GetFontSize().Unit() == DimensionUnit::FP) {
437 txtStyle.font_size =
438 pipelineContext->NormalizeToPx(textStyle.GetFontSize() * pipelineContext->GetFontScale());
439 }
440 } else {
441 txtStyle.font_size = textStyle.GetFontSize().Value();
442 }
443 txtStyle.font_style = ConvertTxtFontStyle(textStyle.GetFontStyle());
444
445 if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
446 txtStyle.word_spacing = textStyle.GetWordSpacing().Value() * txtStyle.font_size;
447 } else {
448 if (pipelineContext) {
449 txtStyle.word_spacing = pipelineContext->NormalizeToPx(textStyle.GetWordSpacing());
450 } else {
451 txtStyle.word_spacing = textStyle.GetWordSpacing().Value();
452 }
453 }
454 if (pipelineContext) {
455 txtStyle.letter_spacing = pipelineContext->NormalizeToPx(textStyle.GetLetterSpacing());
456 }
457 txtStyle.text_baseline = ConvertTxtTextBaseline(textStyle.GetTextBaseline());
458 txtStyle.decoration = ConvertTxtTextDecoration(textStyle.GetTextDecoration());
459 txtStyle.decoration_style = ConvertTxtTextDecorationStyle(textStyle.GetTextDecorationStyle());
460 txtStyle.decoration_color = ConvertSkColor(textStyle.GetTextDecorationColor());
461 txtStyle.font_families = textStyle.GetFontFamilies();
462 txtStyle.locale = Localization::GetInstance()->GetFontLocale();
463 txtStyle.half_leading = textStyle.GetHalfLeading();
464
465 for (auto& spanShadow : textStyle.GetTextShadows()) {
466 txt::TextShadow txtShadow;
467 txtShadow.color = spanShadow.GetColor().GetValue();
468 #ifndef USE_ROSEN_DRAWING
469 txtShadow.offset.fX = static_cast<SkScalar>(spanShadow.GetOffset().GetX());
470 txtShadow.offset.fY = static_cast<SkScalar>(spanShadow.GetOffset().GetY());
471 #else
472 txtShadow.offset.SetX(static_cast<SkScalar>(spanShadow.GetOffset().GetX()));
473 txtShadow.offset.SetY(static_cast<SkScalar>(spanShadow.GetOffset().GetY()));
474 #endif
475 txtShadow.blur_sigma = spanShadow.GetBlurRadius();
476
477 txtStyle.text_shadows.emplace_back(txtShadow);
478 }
479
480 if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
481 txtStyle.has_height_override = true;
482 txtStyle.height = textStyle.GetLineHeight().Value();
483 } else {
484 double fontSize = txtStyle.font_size;
485 double lineHeight = textStyle.GetLineHeight().Value();
486 if (pipelineContext) {
487 lineHeight = pipelineContext->NormalizeToPx(textStyle.GetLineHeight());
488 }
489 txtStyle.has_height_override = textStyle.HasHeightOverride();
490 if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
491 txtStyle.height = lineHeight / fontSize;
492 } else {
493 txtStyle.height = 1;
494 static const int32_t BEGIN_VERSION = 6;
495 auto isBeginVersion = pipelineContext && pipelineContext->GetMinPlatformVersion() >= BEGIN_VERSION;
496 if (NearZero(lineHeight) || (!isBeginVersion && NearEqual(lineHeight, fontSize))) {
497 txtStyle.has_height_override = false;
498 }
499 }
500 }
501
502 // set font variant
503 auto fontFeatures = textStyle.GetFontFeatures();
504 if (!fontFeatures.empty()) {
505 txt::FontFeatures features;
506 for (auto iter = fontFeatures.begin(); iter != fontFeatures.end(); ++iter) {
507 features.SetFeature(iter->first, iter->second);
508 }
509 txtStyle.font_features = features;
510 }
511 }
512
ConvertTxtStyle(const TextStyle & textStyle,txt::TextStyle & txtStyle)513 void ConvertTxtStyle(const TextStyle& textStyle, txt::TextStyle& txtStyle) {}
514
ConvertSymbolTxtStyle(const TextStyle & textStyle,txt::TextStyle & txtStyle)515 void ConvertSymbolTxtStyle(const TextStyle& textStyle, txt::TextStyle& txtStyle)
516 {
517 if (!textStyle.isSymbolGlyph_) {
518 return;
519 }
520
521 txtStyle.isSymbolGlyph = true;
522 const std::vector<Color>& symbolColor = textStyle.GetSymbolColorList();
523 std::vector<Rosen::Drawing::Color> symbolColors;
524 for (size_t i = 0; i < symbolColor.size(); i++) {
525 symbolColors.emplace_back(ConvertSkColor(symbolColor[i]));
526 }
527 txtStyle.symbol.SetRenderColor(symbolColors);
528 txtStyle.symbol.SetRenderMode(textStyle.GetRenderStrategy());
529 if (textStyle.GetSymbolEffectOptions().has_value()) {
530 auto options = textStyle.GetSymbolEffectOptions().value();
531 auto effectType = options.GetEffectType();
532 txtStyle.symbol.SetSymbolEffect(static_cast<uint32_t>(effectType));
533 if (effectType == SymbolEffectType::HIERARCHICAL && options.GetFillStyle().has_value()) {
534 txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetFillStyle().value()));
535 } else {
536 if (options.GetScopeType().has_value()) {
537 txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetScopeType().value()));
538 }
539 }
540 if (options.GetCommonSubType().has_value()) {
541 auto commonType = static_cast<uint16_t>(options.GetCommonSubType().value());
542 txtStyle.symbol.SetCommonSubType(commonType == 1 ? Rosen::Drawing::DrawingCommonSubType::UP
543 : Rosen::Drawing::DrawingCommonSubType::DOWN);
544 }
545 txtStyle.symbol.SetAnimationStart(options.GetIsTxtActive());
546 } else {
547 auto effectStrategy = textStyle.GetEffectStrategy();
548 if (effectStrategy < NONE_EFFECT || effectStrategy > SCALE_EFFECT) {
549 effectStrategy = NONE_EFFECT;
550 }
551 txtStyle.symbol.SetSymbolEffect(effectStrategy);
552 txtStyle.symbol.SetAnimationStart(true);
553 }
554 txtStyle.fontFamilies.push_back("HM Symbol");
555 }
556 #else
NormalizeToPx(const Dimension & dimension)557 double NormalizeToPx(const Dimension& dimension)
558 {
559 if ((dimension.Unit() == DimensionUnit::VP) || (dimension.Unit() == DimensionUnit::FP)) {
560 return (dimension.Value() * SystemProperties::GetResolution());
561 }
562 return dimension.Value();
563 }
564
ConvertTxtStyle(const TextStyle & textStyle,Rosen::TextStyle & txtStyle)565 void ConvertTxtStyle(const TextStyle& textStyle, Rosen::TextStyle& txtStyle)
566 {
567 txtStyle.color = ConvertSkColor(textStyle.GetTextColor());
568 txtStyle.fontWeight = ConvertTxtFontWeight(textStyle.GetFontWeight());
569
570 txtStyle.fontSize = NormalizeToPx(textStyle.GetFontSize());
571
572 txtStyle.fontStyle = ConvertTxtFontStyle(textStyle.GetFontStyle());
573
574 if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
575 txtStyle.wordSpacing = textStyle.GetWordSpacing().Value() * txtStyle.fontSize;
576 } else {
577 txtStyle.wordSpacing = NormalizeToPx(textStyle.GetWordSpacing());
578 }
579
580 txtStyle.letterSpacing = NormalizeToPx(textStyle.GetLetterSpacing());
581 txtStyle.baseLineShift = -NormalizeToPx(textStyle.GetBaselineOffset());
582 txtStyle.fontFamilies = textStyle.GetFontFamilies();
583 ConvertSymbolTxtStyle(textStyle, txtStyle);
584 txtStyle.baseline = ConvertTxtTextBaseline(textStyle.GetTextBaseline());
585 txtStyle.decoration = ConvertTxtTextDecoration(textStyle.GetTextDecoration());
586 txtStyle.decorationColor = ConvertSkColor(textStyle.GetTextDecorationColor());
587 txtStyle.decorationStyle = ConvertTxtTextDecorationStyle(textStyle.GetTextDecorationStyle());
588 txtStyle.locale = Localization::GetInstance()->GetFontLocale();
589 txtStyle.halfLeading = textStyle.GetHalfLeading();
590
591 for (auto& spanShadow : textStyle.GetTextShadows()) {
592 Rosen::TextShadow txtShadow;
593 txtShadow.color = spanShadow.GetColor().GetValue();
594 txtShadow.offset.SetX(spanShadow.GetOffset().GetX());
595 txtShadow.offset.SetY(spanShadow.GetOffset().GetY());
596 txtShadow.blurRadius = spanShadow.GetBlurRadius();
597 txtStyle.shadows.emplace_back(txtShadow);
598 }
599
600 if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
601 txtStyle.heightOnly = true;
602 txtStyle.heightScale = textStyle.GetLineHeight().Value();
603 } else {
604 double fontSize = txtStyle.fontSize;
605 double lineHeight = textStyle.GetLineHeight().Value();
606
607 lineHeight = NormalizeToPx(textStyle.GetLineHeight());
608
609 txtStyle.heightOnly = textStyle.HasHeightOverride();
610 if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
611 txtStyle.heightScale = lineHeight / fontSize;
612 } else {
613 txtStyle.heightScale = 1;
614 if (NearZero(lineHeight) || NearEqual(lineHeight, fontSize)) {
615 txtStyle.heightOnly = false;
616 }
617 }
618 }
619
620 // set font variant
621 auto fontFeatures = textStyle.GetFontFeatures();
622 if (!fontFeatures.empty()) {
623 Rosen::FontFeatures features;
624 for (auto iter = fontFeatures.begin(); iter != fontFeatures.end(); ++iter) {
625 features.SetFeature(iter->first, iter->second);
626 }
627 txtStyle.fontFeatures = features;
628 }
629 auto textBackgroundStyle = textStyle.GetTextBackgroundStyle();
630 CHECK_NULL_VOID(textBackgroundStyle.has_value());
631 txtStyle.styleId = textBackgroundStyle->groupId;
632 if (textBackgroundStyle->backgroundColor.has_value()) {
633 txtStyle.backgroundRect.color = textBackgroundStyle->backgroundColor.value().GetValue();
634 }
635 auto radius = textBackgroundStyle->backgroundRadius;
636 CHECK_NULL_VOID(radius.has_value());
637 auto radiusConverter = [](const std::optional<Dimension>& radius) -> double {
638 CHECK_NULL_RETURN(radius.has_value(), 0);
639 return NormalizeToPx(radius.value());
640 };
641 txtStyle.backgroundRect.leftTopRadius = radiusConverter(radius->radiusTopLeft);
642 txtStyle.backgroundRect.rightTopRadius = radiusConverter(radius->radiusTopRight);
643 txtStyle.backgroundRect.leftBottomRadius = radiusConverter(radius->radiusBottomLeft);
644 txtStyle.backgroundRect.rightBottomRadius = radiusConverter(radius->radiusBottomRight);
645 }
646
ConvertTxtStyle(const TextStyle & textStyle,const WeakPtr<PipelineBase> & context,Rosen::TextStyle & txtStyle)647 void ConvertTxtStyle(const TextStyle& textStyle, const WeakPtr<PipelineBase>& context, Rosen::TextStyle& txtStyle)
648 {
649 txtStyle.color = ConvertSkColor(textStyle.GetTextColor());
650 txtStyle.fontWeight = ConvertTxtFontWeight(textStyle.GetFontWeight());
651 auto fontWeightValue = (static_cast<int32_t>(
652 ConvertTxtFontWeight(textStyle.GetFontWeight())) + 1) * DEFAULT_MULTIPLE;
653 auto pipelineContext = context.Upgrade();
654 if (pipelineContext) {
655 fontWeightValue = fontWeightValue * pipelineContext->GetFontWeightScale();
656 }
657 if (textStyle.GetEnableVariableFontWeight()) {
658 fontWeightValue = textStyle.GetVariableFontWeight();
659 if (LessNotEqual(fontWeightValue, MIN_FONT_WEIGHT) || GreatNotEqual(fontWeightValue, MAX_FONT_WEIGHT)) {
660 fontWeightValue = DEFAULT_FONT_WEIGHT;
661 }
662 }
663 txtStyle.fontVariations.SetAxisValue(FONTWEIGHT, fontWeightValue);
664 // Font size must be px when transferring to Rosen::TextStyle
665 txtStyle.fontSize = textStyle.GetFontSize().ConvertToPxDistribute(
666 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
667 txtStyle.fontStyle = ConvertTxtFontStyle(textStyle.GetFontStyle());
668
669 if (textStyle.GetWordSpacing().Unit() == DimensionUnit::PERCENT) {
670 txtStyle.wordSpacing = textStyle.GetWordSpacing().Value() * txtStyle.fontSize;
671 } else {
672 if (pipelineContext) {
673 txtStyle.wordSpacing = textStyle.GetWordSpacing().ConvertToPxDistribute(
674 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
675 } else {
676 txtStyle.wordSpacing = textStyle.GetWordSpacing().Value();
677 }
678 }
679 if (pipelineContext) {
680 txtStyle.letterSpacing = textStyle.GetLetterSpacing().ConvertToPxDistribute(
681 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
682 txtStyle.baseLineShift = -textStyle.GetBaselineOffset().ConvertToPxDistribute(
683 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
684 }
685
686 txtStyle.fontFamilies = textStyle.GetFontFamilies();
687 ConvertSymbolTxtStyle(textStyle, txtStyle);
688 txtStyle.baseline = ConvertTxtTextBaseline(textStyle.GetTextBaseline());
689 txtStyle.decoration = ConvertTxtTextDecoration(textStyle.GetTextDecoration());
690 txtStyle.decorationColor = ConvertSkColor(textStyle.GetTextDecorationColor());
691 txtStyle.decorationStyle = ConvertTxtTextDecorationStyle(textStyle.GetTextDecorationStyle());
692 txtStyle.locale = Localization::GetInstance()->GetFontLocale();
693 txtStyle.halfLeading = textStyle.GetHalfLeading();
694
695 for (auto& spanShadow : textStyle.GetTextShadows()) {
696 Rosen::TextShadow txtShadow;
697 txtShadow.color = spanShadow.GetColor().GetValue();
698 txtShadow.offset.SetX(spanShadow.GetOffset().GetX());
699 txtShadow.offset.SetY(spanShadow.GetOffset().GetY());
700 txtShadow.blurRadius = spanShadow.GetBlurRadius();
701 txtStyle.shadows.emplace_back(txtShadow);
702 }
703
704 double lineHeightScale = 0.0;
705 double lineSpacingScale = 0.0;
706 bool lineHeightOnly = false;
707 bool lineSpacingOnly = false;
708 if (textStyle.GetLineHeight().Unit() == DimensionUnit::PERCENT) {
709 lineHeightOnly = true;
710 lineHeightScale = textStyle.GetLineHeight().Value();
711 } else {
712 double fontSize = txtStyle.fontSize;
713 double lineHeight = textStyle.GetLineHeight().Value();
714 if (pipelineContext) {
715 lineHeight = textStyle.GetLineHeight().ConvertToPxDistribute(
716 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
717 }
718 lineHeightOnly = textStyle.HasHeightOverride();
719 if (!NearEqual(lineHeight, fontSize) && (lineHeight > 0.0) && (!NearZero(fontSize))) {
720 lineHeightScale = lineHeight / fontSize;
721 } else {
722 lineHeightScale = 1;
723 static const int32_t BEGIN_VERSION = 6;
724 auto isBeginVersion = pipelineContext && pipelineContext->GetMinPlatformVersion() >= BEGIN_VERSION;
725 if (NearZero(lineHeight) || (!isBeginVersion && NearEqual(lineHeight, fontSize))) {
726 lineHeightOnly = false;
727 }
728 }
729 }
730 if (textStyle.GetLineSpacing().Unit() == DimensionUnit::PERCENT) {
731 lineSpacingOnly = true;
732 lineSpacingScale = textStyle.GetLineSpacing().Value();
733 } else {
734 double fontSize = txtStyle.fontSize;
735 double lineSpacing = textStyle.GetLineSpacing().Value();
736 if (pipelineContext) {
737 lineSpacing = textStyle.GetLineSpacing().ConvertToPxDistribute(
738 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
739 }
740 lineSpacingOnly = true;
741 if (!NearEqual(lineSpacing, fontSize) && (lineSpacing > 0.0) && (!NearZero(fontSize))) {
742 lineSpacingScale = lineSpacing / fontSize;
743 } else {
744 lineSpacingScale = 1;
745 if (NearZero(lineSpacing)) {
746 lineSpacingOnly = false;
747 }
748 }
749 }
750
751 txtStyle.heightOnly = lineHeightOnly || lineSpacingOnly;
752 if (lineHeightOnly && lineSpacingOnly) {
753 txtStyle.heightScale = lineHeightScale + lineSpacingScale;
754 } else if (lineHeightOnly && !lineSpacingOnly) {
755 txtStyle.heightScale = lineHeightScale;
756 } else if (!lineHeightOnly && lineSpacingOnly) {
757 txtStyle.heightScale = ORIGINAL_LINE_HEIGHT_SCALE + lineSpacingScale;
758 } else {
759 txtStyle.heightScale = 1;
760 }
761
762 // set font variant
763 auto fontFeatures = textStyle.GetFontFeatures();
764 if (!fontFeatures.empty()) {
765 Rosen::FontFeatures features;
766 for (auto iter = fontFeatures.begin(); iter != fontFeatures.end(); ++iter) {
767 features.SetFeature(iter->first, iter->second);
768 }
769 txtStyle.fontFeatures = features;
770 }
771 auto textBackgroundStyle = textStyle.GetTextBackgroundStyle();
772 CHECK_NULL_VOID(textBackgroundStyle.has_value());
773 txtStyle.styleId = textBackgroundStyle->groupId;
774 if (textBackgroundStyle->backgroundColor.has_value()) {
775 txtStyle.backgroundRect.color = textBackgroundStyle->backgroundColor.value().GetValue();
776 }
777 auto radius = textBackgroundStyle->backgroundRadius;
778 CHECK_NULL_VOID(radius.has_value());
779 auto radiusConverter = [context = pipelineContext, textStyle](const std::optional<Dimension>& radius) -> double {
780 CHECK_NULL_RETURN(radius.has_value(), 0);
781 CHECK_NULL_RETURN(context, radius->Value());
782 return radius.value().ConvertToPxDistribute(
783 textStyle.GetMinFontScale(), textStyle.GetMaxFontScale(), textStyle.IsAllowScale());
784 };
785 txtStyle.backgroundRect.leftTopRadius = radiusConverter(radius->radiusTopLeft);
786 txtStyle.backgroundRect.rightTopRadius = radiusConverter(radius->radiusTopRight);
787 txtStyle.backgroundRect.leftBottomRadius = radiusConverter(radius->radiusBottomLeft);
788 txtStyle.backgroundRect.rightBottomRadius = radiusConverter(radius->radiusBottomRight);
789 }
790
ConvertSymbolTxtStyle(const TextStyle & textStyle,Rosen::TextStyle & txtStyle)791 void ConvertSymbolTxtStyle(const TextStyle& textStyle, Rosen::TextStyle& txtStyle)
792 {
793 if (!textStyle.isSymbolGlyph_) {
794 return;
795 }
796
797 txtStyle.isSymbolGlyph = true;
798 txtStyle.symbol.SetRenderMode(textStyle.GetRenderStrategy());
799 const std::vector<Color>& symbolColor = textStyle.GetSymbolColorList();
800 std::vector<Rosen::Drawing::Color> symbolColors;
801 for (size_t i = 0; i < symbolColor.size(); i++) {
802 symbolColors.emplace_back(ConvertSkColor(symbolColor[i]));
803 }
804 txtStyle.symbol.SetRenderColor(symbolColors);
805 if (textStyle.GetSymbolEffectOptions().has_value()) {
806 auto options = textStyle.GetSymbolEffectOptions().value();
807 auto effectType = options.GetEffectType();
808 txtStyle.symbol.SetSymbolEffect(static_cast<uint32_t>(effectType));
809 txtStyle.symbol.SetAnimationStart(options.GetIsTxtActive());
810 if (options.GetCommonSubType().has_value()) {
811 auto commonType = static_cast<uint16_t>(options.GetCommonSubType().value());
812 txtStyle.symbol.SetCommonSubType(commonType == 1 ? Rosen::Drawing::DrawingCommonSubType::UP
813 : Rosen::Drawing::DrawingCommonSubType::DOWN);
814 }
815 if (effectType == SymbolEffectType::HIERARCHICAL && options.GetFillStyle().has_value()) {
816 txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetFillStyle().value()));
817 } else {
818 if (options.GetScopeType().has_value()) {
819 txtStyle.symbol.SetAnimationMode(static_cast<uint16_t>(options.GetScopeType().value()));
820 }
821 }
822 } else {
823 auto effectStrategyValue = textStyle.GetEffectStrategy();
824 if (effectStrategyValue < NONE_EFFECT || effectStrategyValue > SCALE_EFFECT) {
825 effectStrategyValue = NONE_EFFECT;
826 }
827 txtStyle.symbol.SetSymbolEffect(effectStrategyValue);
828 txtStyle.symbol.SetAnimationStart(true);
829 }
830 txtStyle.fontFamilies.push_back("HM Symbol");
831 }
832 #endif
833
834 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertSkRect(SkRect skRect)835 Rect ConvertSkRect(SkRect skRect)
836 {
837 Rect result;
838 result.SetLeft(skRect.fLeft);
839 result.SetTop(skRect.fTop);
840 result.SetWidth(skRect.width());
841 result.SetHeight(skRect.height());
842 return result;
843 }
844 #else
ConvertSkRect(const Rosen::Drawing::RectF & skRect)845 Rect ConvertSkRect(const Rosen::Drawing::RectF& skRect)
846 {
847 Rect result;
848 result.SetLeft(skRect.GetLeft());
849 result.SetTop(skRect.GetTop());
850 result.SetWidth(skRect.GetWidth());
851 result.SetHeight(skRect.GetHeight());
852 return result;
853 }
854 #endif
855
856 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)857 txt::PlaceholderAlignment ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)
858 {
859 txt::PlaceholderAlignment convertValue = txt::PlaceholderAlignment::kBaseline;
860 switch (textDecoration) {
861 case PlaceholderAlignment::BASELINE:
862 convertValue = txt::PlaceholderAlignment::kBaseline;
863 break;
864 case PlaceholderAlignment::ABOVEBASELINE:
865 convertValue = txt::PlaceholderAlignment::kAboveBaseline;
866 break;
867 case PlaceholderAlignment::BELOWBASELINE:
868 convertValue = txt::PlaceholderAlignment::kBelowBaseline;
869 break;
870 case PlaceholderAlignment::TOP:
871 convertValue = txt::PlaceholderAlignment::kTop;
872 break;
873 case PlaceholderAlignment::BOTTOM:
874 convertValue = txt::PlaceholderAlignment::kBottom;
875 break;
876 case PlaceholderAlignment::MIDDLE:
877 convertValue = txt::PlaceholderAlignment::kMiddle;
878 break;
879 default:
880 TAG_LOGW(AceLogTag::ACE_FONT, "PlaceholderAlignment set error! use default PlaceholderAlignment");
881 break;
882 }
883 return convertValue;
884 }
885 #else
ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)886 Rosen::PlaceholderVerticalAlignment ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)
887 {
888 Rosen::PlaceholderVerticalAlignment convertValue = Rosen::PlaceholderVerticalAlignment::OFFSET_AT_BASELINE;
889 switch (textDecoration) {
890 case PlaceholderAlignment::BASELINE:
891 convertValue = Rosen::PlaceholderVerticalAlignment::OFFSET_AT_BASELINE;
892 break;
893 case PlaceholderAlignment::ABOVEBASELINE:
894 convertValue = Rosen::PlaceholderVerticalAlignment::ABOVE_BASELINE;
895 break;
896 case PlaceholderAlignment::BELOWBASELINE:
897 convertValue = Rosen::PlaceholderVerticalAlignment::BELOW_BASELINE;
898 break;
899 case PlaceholderAlignment::TOP:
900 convertValue = Rosen::PlaceholderVerticalAlignment::TOP_OF_ROW_BOX;
901 break;
902 case PlaceholderAlignment::BOTTOM:
903 convertValue = Rosen::PlaceholderVerticalAlignment::BOTTOM_OF_ROW_BOX;
904 break;
905 case PlaceholderAlignment::MIDDLE:
906 convertValue = Rosen::PlaceholderVerticalAlignment::CENTER_OF_ROW_BOX;
907 break;
908 default:
909 TAG_LOGW(AceLogTag::ACE_FONT, "PlaceholderAlignment setting error! Now using default PlaceholderAlignment");
910 break;
911 }
912 return convertValue;
913 }
914 #endif
915
916 #ifndef USE_GRAPHIC_TEXT_GINE
ConvertPlaceholderRun(const PlaceholderRun & span,txt::PlaceholderRun & txtSpan)917 void ConvertPlaceholderRun(const PlaceholderRun& span, txt::PlaceholderRun& txtSpan)
918 #else
919 void ConvertPlaceholderRun(const PlaceholderRun& span, Rosen::PlaceholderSpan& txtSpan)
920 #endif
921 {
922 txtSpan.width = span.width;
923 txtSpan.height = span.height;
924 txtSpan.alignment = ConvertPlaceholderAlignment(span.alignment);
925 txtSpan.baseline = ConvertTxtTextBaseline(span.baseline);
926 #ifndef USE_GRAPHIC_TEXT_GINE
927 txtSpan.baseline_offset = span.baseline_offset;
928 #else
929 txtSpan.baselineOffset = span.baseline_offset;
930 #endif
931 }
932
933 } // namespace OHOS::Ace::Constants
934