• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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