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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TEXT_STYLE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TEXT_STYLE_H
18
19 #include <string>
20 #include <unordered_map>
21 #include <vector>
22
23 #include "base/geometry/dimension.h"
24 #include "base/utils/linear_map.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/common/properties/color.h"
27 #include "core/components/common/properties/shadow.h"
28 #include "core/components_ng/property/border_property.h"
29 #include "core/pipeline/base/render_component.h"
30
31 namespace OHOS::Ace {
32
33 // The normal weight is W400, the larger the number after W, the thicker the font will be.
34 // BOLD is equal to W700 and NORMAL is equal to W400, lighter is W100, BOLDER is W900.
35 enum class FontWeight {
36 W100 = 0,
37 W200,
38 W300,
39 W400,
40 W500,
41 W600,
42 W700,
43 W800,
44 W900,
45 BOLD,
46 NORMAL,
47 BOLDER,
48 LIGHTER,
49 MEDIUM,
50 REGULAR,
51 };
52
53 enum class FontStyle {
54 NORMAL = 0,
55 ITALIC,
56 };
57
58 enum class TextBaseline {
59 ALPHABETIC,
60 IDEOGRAPHIC,
61 TOP,
62 BOTTOM,
63 MIDDLE,
64 HANGING,
65 };
66
67 enum class TextCase {
68 NORMAL = 0,
69 LOWERCASE,
70 UPPERCASE,
71 };
72
73 enum class EllipsisMode {
74 HEAD,
75 MIDDLE,
76 TAIL,
77 };
78
79 enum class WordBreak { NORMAL = 0, BREAK_ALL, BREAK_WORD };
80
81 /// Where to vertically align the placeholder relative to the surrounding text.
82 enum class PlaceholderAlignment {
83 /// Match the baseline of the placeholder with the baseline.
84 BASELINE,
85
86 /// Align the bottom edge of the placeholder with the baseline such that the
87 /// placeholder sits on top of the baseline.
88 ABOVEBASELINE,
89
90 /// Align the top edge of the placeholder with the baseline specified in
91 /// such that the placeholder hangs below the baseline.
92 BELOWBASELINE,
93
94 /// Align the top edge of the placeholder with the top edge of the font.
95 /// When the placeholder is very tall, the extra space will hang from
96 /// the top and extend through the bottom of the line.
97 TOP,
98
99 /// Align the bottom edge of the placeholder with the top edge of the font.
100 /// When the placeholder is very tall, the extra space will rise from
101 /// the bottom and extend through the top of the line.
102 BOTTOM,
103
104 /// Align the middle of the placeholder with the middle of the text. When the
105 /// placeholder is very tall, the extra space will grow equally from
106 /// the top and bottom of the line.
107 MIDDLE,
108 };
109
110 struct TextSizeGroup {
111 Dimension fontSize = 14.0_px;
112 uint32_t maxLines = INT32_MAX;
113 TextOverflow textOverflow = TextOverflow::CLIP;
114 };
115
116 /// Placeholder properties
117 struct PlaceholderRun {
118 /// Placeholder's width
119 float width = 0.0f;
120
121 /// Placeholder's height
122 float height = 0.0f;
123
124 /// Vertically alignment the placeholder relative to the surrounding text.
125 PlaceholderAlignment alignment = PlaceholderAlignment::BOTTOM;
126
127 /// The placeholder with the baseline styles
128 TextBaseline baseline = TextBaseline::ALPHABETIC;
129
130 /// The baseline offset
131 float baseline_offset = 0.0f;
132 };
133
134 struct TextBackgroundStyle {
135 std::optional<Color> backgroundColor;
136 std::optional<NG::BorderRadiusProperty> backgroundRadius;
137 int32_t groupId = 0;
138
139 static void ToJsonValue(std::unique_ptr<JsonValue>& json, const std::optional<TextBackgroundStyle>& style);
140
141 bool operator==(const TextBackgroundStyle& value) const
142 {
143 return backgroundColor == value.backgroundColor && backgroundRadius == value.backgroundRadius &&
144 groupId == value.groupId;
145 }
146 };
147
148 class ACE_EXPORT TextStyle final {
149 public:
150 TextStyle() = default;
151 TextStyle(const std::vector<std::string>& fontFamilies, double fontSize, FontWeight fontWeight, FontStyle fontStyle,
152 const Color& textColor);
153 ~TextStyle() = default;
154
155 bool operator==(const TextStyle& rhs) const;
156 bool operator!=(const TextStyle& rhs) const;
157
GetTextBaseline()158 TextBaseline GetTextBaseline() const
159 {
160 return textBaseline_;
161 }
162
GetBaselineOffset()163 const Dimension& GetBaselineOffset() const
164 {
165 return baselineOffset_;
166 }
167
SetBaselineOffset(const Dimension & baselineOffset)168 void SetBaselineOffset(const Dimension& baselineOffset)
169 {
170 baselineOffset_ = baselineOffset;
171 }
172
SetTextBaseline(TextBaseline baseline)173 void SetTextBaseline(TextBaseline baseline)
174 {
175 textBaseline_ = baseline;
176 }
177
SetTextDecoration(TextDecoration textDecoration)178 void SetTextDecoration(TextDecoration textDecoration)
179 {
180 textDecoration_ = textDecoration;
181 }
182
SetTextDecorationStyle(TextDecorationStyle textDecorationStyle)183 void SetTextDecorationStyle(TextDecorationStyle textDecorationStyle)
184 {
185 textDecorationStyle_ = textDecorationStyle;
186 }
187
GetFontStyle()188 FontStyle GetFontStyle() const
189 {
190 return fontStyle_;
191 }
192
SetFontStyle(FontStyle fontStyle)193 void SetFontStyle(FontStyle fontStyle)
194 {
195 fontStyle_ = fontStyle;
196 }
197
GetFontSize()198 const Dimension& GetFontSize() const
199 {
200 return fontSize_;
201 }
202
GetWhiteSpace()203 WhiteSpace GetWhiteSpace() const
204 {
205 return whiteSpace_;
206 }
207
SetWhiteSpace(WhiteSpace whiteSpace)208 void SetWhiteSpace(WhiteSpace whiteSpace)
209 {
210 whiteSpace_ = whiteSpace;
211 }
212
SetFontSize(const Dimension & fontSize)213 void SetFontSize(const Dimension& fontSize)
214 {
215 fontSize_ = fontSize;
216 }
217
GetFontWeight()218 FontWeight GetFontWeight() const
219 {
220 return fontWeight_;
221 }
222
SetFontWeight(FontWeight fontWeight)223 void SetFontWeight(FontWeight fontWeight)
224 {
225 fontWeight_ = fontWeight;
226 }
227
GetTextColor()228 const Color& GetTextColor() const
229 {
230 return textColor_;
231 }
232
SetTextColor(const Color & textColor)233 void SetTextColor(const Color& textColor)
234 {
235 textColor_ = textColor;
236 }
237
GetTextDecoration()238 TextDecoration GetTextDecoration() const
239 {
240 return textDecoration_;
241 }
242
GetTextDecorationStyle()243 TextDecorationStyle GetTextDecorationStyle() const
244 {
245 return textDecorationStyle_;
246 }
247
GetWordSpacing()248 const Dimension& GetWordSpacing() const
249 {
250 return wordSpacing_;
251 }
252
SetWordSpacing(const Dimension & wordSpacing)253 void SetWordSpacing(const Dimension& wordSpacing)
254 {
255 wordSpacing_ = wordSpacing;
256 }
257
GetTextDecorationColor()258 const Color& GetTextDecorationColor() const
259 {
260 return textDecorationColor_;
261 }
262
SetTextDecorationColor(const Color & textDecorationColor)263 void SetTextDecorationColor(const Color& textDecorationColor)
264 {
265 textDecorationColor_ = textDecorationColor;
266 }
267
GetFontFamilies()268 const std::vector<std::string>& GetFontFamilies() const
269 {
270 return fontFamilies_;
271 }
272
SetFontFamilies(const std::vector<std::string> & fontFamilies)273 void SetFontFamilies(const std::vector<std::string>& fontFamilies)
274 {
275 fontFamilies_ = fontFamilies;
276 }
277
GetTextIndent()278 Dimension GetTextIndent() const
279 {
280 return textIndent_;
281 }
282
SetTextIndent(const Dimension & textIndent)283 void SetTextIndent(const Dimension& textIndent)
284 {
285 textIndent_ = textIndent;
286 }
287
GetFontFeatures()288 const std::unordered_map<std::string, int32_t>& GetFontFeatures() const
289 {
290 return fontFeatures_;
291 }
292
SetFontFeatures(const std::unordered_map<std::string,int32_t> & fontFeatures)293 void SetFontFeatures(const std::unordered_map<std::string, int32_t>& fontFeatures)
294 {
295 fontFeatures_ = fontFeatures;
296 }
297
GetLineHeight()298 const Dimension& GetLineHeight() const
299 {
300 return lineHeight_;
301 }
302
303 void SetLineHeight(const Dimension& lineHeight, bool hasHeightOverride = true)
304 {
305 lineHeight_ = lineHeight;
306 hasHeightOverride_ = hasHeightOverride;
307 }
308
HasHeightOverride()309 bool HasHeightOverride() const
310 {
311 return hasHeightOverride_;
312 }
313
GetLetterSpacing()314 const Dimension& GetLetterSpacing() const
315 {
316 return letterSpacing_;
317 }
318
SetLetterSpacing(const Dimension & letterSpacing)319 void SetLetterSpacing(const Dimension& letterSpacing)
320 {
321 letterSpacing_ = letterSpacing;
322 }
323
GetAdaptTextSize()324 bool GetAdaptTextSize() const
325 {
326 return adaptTextSize_;
327 }
328
329 void SetAdaptTextSize(
330 const Dimension& maxFontSize, const Dimension& minFontSize, const Dimension& fontSizeStep = 1.0_px);
331
GetAdaptHeight()332 bool GetAdaptHeight() const
333 {
334 return adaptHeight_;
335 }
336
SetAdaptHeight(bool adaptHeight)337 void SetAdaptHeight(bool adaptHeight)
338 {
339 adaptHeight_ = adaptHeight;
340 }
341
DisableAdaptTextSize()342 void DisableAdaptTextSize()
343 {
344 adaptTextSize_ = false;
345 }
346
GetMaxLines()347 uint32_t GetMaxLines() const
348 {
349 return maxLines_;
350 }
351
SetMaxLines(uint32_t maxLines)352 void SetMaxLines(uint32_t maxLines)
353 {
354 maxLines_ = maxLines;
355 }
356
SetPreferFontSizes(const std::vector<Dimension> & preferFontSizes)357 void SetPreferFontSizes(const std::vector<Dimension>& preferFontSizes)
358 {
359 preferFontSizes_ = preferFontSizes;
360 adaptTextSize_ = true;
361 }
362
GetPreferFontSizes()363 const std::vector<Dimension>& GetPreferFontSizes() const
364 {
365 return preferFontSizes_;
366 }
367
368 // Must use with SetAdaptMinFontSize and SetAdaptMaxFontSize.
SetAdaptFontSizeStep(const Dimension & adaptTextSizeStep)369 void SetAdaptFontSizeStep(const Dimension& adaptTextSizeStep)
370 {
371 adaptFontSizeStep_ = adaptTextSizeStep;
372 }
373 // Must use with SetAdaptMaxFontSize.
SetAdaptMinFontSize(const Dimension & adaptMinFontSize)374 void SetAdaptMinFontSize(const Dimension& adaptMinFontSize)
375 {
376 adaptMinFontSize_ = adaptMinFontSize;
377 adaptTextSize_ = true;
378 }
379 // Must use with SetAdaptMinFontSize.
SetAdaptMaxFontSize(const Dimension & adaptMaxFontSize)380 void SetAdaptMaxFontSize(const Dimension& adaptMaxFontSize)
381 {
382 adaptMaxFontSize_ = adaptMaxFontSize;
383 adaptTextSize_ = true;
384 }
385
GetAdaptFontSizeStep()386 const Dimension& GetAdaptFontSizeStep() const
387 {
388 return adaptFontSizeStep_;
389 }
390
GetAdaptMinFontSize()391 const Dimension& GetAdaptMinFontSize() const
392 {
393 return adaptMinFontSize_;
394 }
395
GetAdaptMaxFontSize()396 const Dimension& GetAdaptMaxFontSize() const
397 {
398 return adaptMaxFontSize_;
399 }
400
GetPreferTextSizeGroups()401 const std::vector<TextSizeGroup>& GetPreferTextSizeGroups() const
402 {
403 return preferTextSizeGroups_;
404 }
SetPreferTextSizeGroups(const std::vector<TextSizeGroup> & preferTextSizeGroups)405 void SetPreferTextSizeGroups(const std::vector<TextSizeGroup>& preferTextSizeGroups)
406 {
407 preferTextSizeGroups_ = preferTextSizeGroups;
408 adaptTextSize_ = true;
409 }
410
IsAllowScale()411 bool IsAllowScale() const
412 {
413 return allowScale_;
414 }
415
SetAllowScale(bool allowScale)416 void SetAllowScale(bool allowScale)
417 {
418 allowScale_ = allowScale;
419 }
420
GetTextOverflow()421 TextOverflow GetTextOverflow() const
422 {
423 return textOverflow_;
424 }
SetTextOverflow(TextOverflow textOverflow)425 void SetTextOverflow(TextOverflow textOverflow)
426 {
427 textOverflow_ = textOverflow;
428 }
GetTextAlign()429 TextAlign GetTextAlign() const
430 {
431 return textAlign_;
432 }
SetTextAlign(TextAlign textAlign)433 void SetTextAlign(TextAlign textAlign)
434 {
435 textAlign_ = textAlign;
436 }
SetTextVerticalAlign(VerticalAlign verticalAlign)437 void SetTextVerticalAlign(VerticalAlign verticalAlign)
438 {
439 verticalAlign_ = verticalAlign;
440 }
441
GetTextVerticalAlign()442 VerticalAlign GetTextVerticalAlign() const
443 {
444 return verticalAlign_;
445 }
446
GetWordBreak()447 WordBreak GetWordBreak() const
448 {
449 return wordBreak_;
450 }
451
SetWordBreak(WordBreak wordBreak)452 void SetWordBreak(WordBreak wordBreak)
453 {
454 wordBreak_ = wordBreak;
455 }
456
GetTextCase()457 TextCase GetTextCase() const
458 {
459 return textCase_;
460 }
461
SetTextCase(TextCase textCase)462 void SetTextCase(TextCase textCase)
463 {
464 textCase_ = textCase;
465 }
466
GetTextShadows()467 const std::vector<Shadow>& GetTextShadows() const
468 {
469 return textShadows_;
470 }
471
SetTextShadows(const std::vector<Shadow> & textShadows)472 void SetTextShadows(const std::vector<Shadow>& textShadows)
473 {
474 textShadows_ = textShadows;
475 }
476
SetShadow(const Shadow & shadow)477 void SetShadow(const Shadow& shadow)
478 {
479 textShadows_.emplace_back(shadow);
480 }
481
GetHalfLeading()482 bool GetHalfLeading() const
483 {
484 return halfLeading_;
485 }
486
SetHalfLeading(bool halfLeading)487 void SetHalfLeading(bool halfLeading)
488 {
489 halfLeading_ = halfLeading;
490 }
491
SetEllipsisMode(EllipsisMode modal)492 void SetEllipsisMode(EllipsisMode modal)
493 {
494 ellipsisMode_ = modal;
495 }
496
GetEllipsisMode()497 EllipsisMode GetEllipsisMode() const
498 {
499 return ellipsisMode_;
500 }
501
502 bool isSymbolGlyph_ = false;
503
SetRenderColors(std::vector<Color> & renderColors)504 void SetRenderColors(std::vector<Color>& renderColors)
505 {
506 renderColors_ = renderColors ;
507 }
508
SetRenderStrategy(int32_t renderStrategy)509 void SetRenderStrategy(int32_t renderStrategy)
510 {
511 renderStrategy_ = renderStrategy;
512 }
513
SetEffectStrategy(int32_t effectStrategy)514 void SetEffectStrategy(int32_t effectStrategy)
515 {
516 effectStrategy_ = effectStrategy;
517 }
518
SetSymbolColorList(const std::vector<Color> & renderColors)519 void SetSymbolColorList(const std::vector<Color>& renderColors)
520 {
521 renderColors_ = renderColors;
522 }
523
GetRenderColors()524 std::vector<Color> GetRenderColors()
525 {
526 return renderColors_;
527 }
528
GetRenderStrategy()529 int32_t GetRenderStrategy() const
530 {
531 return renderStrategy_;
532 }
533
GetSymbolColorList()534 const std::vector<Color>& GetSymbolColorList() const
535 {
536 return renderColors_;
537 }
538
GetEffectStrategy()539 int32_t GetEffectStrategy() const
540 {
541 return effectStrategy_;
542 }
543
SetTextBackgroundStyle(const std::optional<TextBackgroundStyle> & style)544 void SetTextBackgroundStyle(const std::optional<TextBackgroundStyle>& style)
545 {
546 textBackgroundStyle_ = style;
547 }
548
GetTextBackgroundStyle()549 const std::optional<TextBackgroundStyle>& GetTextBackgroundStyle() const
550 {
551 return textBackgroundStyle_;
552 }
553 private:
554 std::vector<std::string> fontFamilies_;
555 std::unordered_map<std::string, int32_t> fontFeatures_;
556 std::vector<Dimension> preferFontSizes_;
557 std::vector<TextSizeGroup> preferTextSizeGroups_;
558 // use 14px for normal font size.
559 Dimension fontSize_ { 14, DimensionUnit::PX };
560 Dimension adaptMinFontSize_;
561 Dimension adaptMaxFontSize_;
562 Dimension adaptFontSizeStep_;
563 Dimension lineHeight_;
564 bool hasHeightOverride_ = false;
565 FontWeight fontWeight_ { FontWeight::NORMAL };
566 FontStyle fontStyle_ { FontStyle::NORMAL };
567 TextBaseline textBaseline_ { TextBaseline::ALPHABETIC };
568 Dimension baselineOffset_;
569 TextOverflow textOverflow_ { TextOverflow::CLIP };
570 VerticalAlign verticalAlign_ { VerticalAlign::NONE };
571 TextAlign textAlign_ { TextAlign::START };
572 Color textColor_ { Color::BLACK };
573 Color textDecorationColor_ { Color::BLACK };
574 TextDecorationStyle textDecorationStyle_ { TextDecorationStyle::SOLID };
575 TextDecoration textDecoration_ { TextDecoration::NONE };
576 std::vector<Shadow> textShadows_;
577 WhiteSpace whiteSpace_ { WhiteSpace::PRE };
578 Dimension wordSpacing_;
579 Dimension textIndent_ { 0.0f, DimensionUnit::PX };
580 Dimension letterSpacing_;
581 uint32_t maxLines_ = UINT32_MAX;
582 bool adaptTextSize_ = false;
583 bool adaptHeight_ = false; // whether adjust text size with height.
584 bool allowScale_ = true;
585 bool halfLeading_ = false;
586 WordBreak wordBreak_ { WordBreak::BREAK_WORD };
587 TextCase textCase_ { TextCase::NORMAL };
588 EllipsisMode ellipsisMode_ = EllipsisMode::TAIL;
589
590 // for Symbol
591 std::vector<Color> renderColors_;
592 int32_t renderStrategy_ = 0;
593 int32_t effectStrategy_ = 0;
594
595 std::optional<TextBackgroundStyle> textBackgroundStyle_;
596 };
597
598 namespace StringUtils {
599
600 inline std::pair<bool, FontWeight> ParseFontWeight(const std::string& weight,
601 FontWeight defaultFontWeight = FontWeight::NORMAL)
602 {
603 static const LinearMapNode<FontWeight> fontWeightTable[] = {
604 { "100", FontWeight::W100 },
605 { "200", FontWeight::W200 },
606 { "300", FontWeight::W300 },
607 { "400", FontWeight::W400 },
608 { "500", FontWeight::W500 },
609 { "600", FontWeight::W600 },
610 { "700", FontWeight::W700 },
611 { "800", FontWeight::W800 },
612 { "900", FontWeight::W900 },
613 { "bold", FontWeight::BOLD },
614 { "bolder", FontWeight::BOLDER },
615 { "lighter", FontWeight::LIGHTER },
616 { "medium", FontWeight::MEDIUM },
617 { "normal", FontWeight::NORMAL },
618 { "regular", FontWeight::REGULAR },
619 };
620 auto weightIter = BinarySearchFindIndex(fontWeightTable, ArraySize(fontWeightTable), weight.c_str());
621 return weightIter != -1 ? std::make_pair(true, fontWeightTable[weightIter].value)
622 : std::make_pair(false, defaultFontWeight);
623 }
624
625 inline FontWeight StringToFontWeight(const std::string& weight, FontWeight defaultFontWeight = FontWeight::NORMAL)
626 {
627 return ParseFontWeight(weight, defaultFontWeight).second;
628 }
629
StringToWordBreak(const std::string & wordBreak)630 inline WordBreak StringToWordBreak(const std::string& wordBreak)
631 {
632 static const LinearMapNode<WordBreak> wordBreakTable[] = {
633 { "break-all", WordBreak::BREAK_ALL },
634 { "break-word", WordBreak::BREAK_WORD },
635 { "normal", WordBreak::NORMAL },
636 };
637 auto wordBreakIter = BinarySearchFindIndex(wordBreakTable, ArraySize(wordBreakTable), wordBreak.c_str());
638 return wordBreakIter != -1 ? wordBreakTable[wordBreakIter].value : WordBreak::BREAK_WORD;
639 }
640
FontWeightToString(const FontWeight & fontWeight)641 inline std::string FontWeightToString(const FontWeight& fontWeight)
642 {
643 static const LinearEnumMapNode<FontWeight, std::string> fontWeightTable[] = {
644 { FontWeight::W100, "100" },
645 { FontWeight::W200, "200" },
646 { FontWeight::W300, "300" },
647 { FontWeight::W400, "400" },
648 { FontWeight::W500, "500" },
649 { FontWeight::W600, "600" },
650 { FontWeight::W700, "700" },
651 { FontWeight::W800, "800" },
652 { FontWeight::W900, "900" },
653 { FontWeight::BOLD, "bold" },
654 { FontWeight::BOLDER, "bolder" },
655 { FontWeight::LIGHTER, "lighter" },
656 { FontWeight::MEDIUM, "medium" },
657 { FontWeight::NORMAL, "normal" },
658 { FontWeight::REGULAR, "regular" },
659 };
660 auto weightIter = BinarySearchFindIndex(fontWeightTable, ArraySize(fontWeightTable), fontWeight);
661 return weightIter != -1 ? fontWeightTable[weightIter].value : "";
662 }
663 } // namespace StringUtils
664 } // namespace OHOS::Ace
665
666 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TEXT_STYLE_H
667