1 /*
2  * Copyright (c) 2022-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 "core/components_ng/pattern/text/text_styles.h"
17 
18 #include "core/components/common/properties/text_style.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/components_ng/pattern/symbol/constants.h"
21 
22 namespace {
23 constexpr uint32_t RENDERINGSTRATEGY_MULTIPLE_COLOR = 1;
24 constexpr uint32_t RENDERINGSTRATEGY_MULTIPLE_OPACITY = 2;
25 };
26 
27 namespace OHOS::Ace::NG {
28 #define UPDATE_TEXT_STYLE(group, name, func)             \
29     do {                                                 \
30         if ((group)->prop##name.has_value()) {           \
31             textStyle.func((group)->prop##name.value()); \
32         }                                                \
33     } while (false)
34 
CreateTextStyleUsingTheme(const std::unique_ptr<FontStyle> & fontStyle,const std::unique_ptr<TextLineStyle> & textLineStyle,const RefPtr<TextTheme> & textTheme)35 TextStyle CreateTextStyleUsingTheme(const std::unique_ptr<FontStyle>& fontStyle,
36     const std::unique_ptr<TextLineStyle>& textLineStyle, const RefPtr<TextTheme>& textTheme)
37 {
38     TextStyle textStyle = textTheme ? textTheme->GetTextStyle() : TextStyle();
39     if (fontStyle) {
40         UPDATE_TEXT_STYLE(fontStyle, FontSize, SetFontSize);
41         UPDATE_TEXT_STYLE(fontStyle, TextColor, SetTextColor);
42         UPDATE_TEXT_STYLE(fontStyle, TextShadow, SetTextShadows);
43         UPDATE_TEXT_STYLE(fontStyle, ItalicFontStyle, SetFontStyle);
44         UPDATE_TEXT_STYLE(fontStyle, FontWeight, SetFontWeight);
45         UPDATE_TEXT_STYLE(fontStyle, FontFamily, SetFontFamilies);
46         UPDATE_TEXT_STYLE(fontStyle, FontFeature, SetFontFeatures);
47         UPDATE_TEXT_STYLE(fontStyle, TextDecoration, SetTextDecoration);
48         UPDATE_TEXT_STYLE(fontStyle, TextDecorationColor, SetTextDecorationColor);
49         UPDATE_TEXT_STYLE(fontStyle, TextDecorationStyle, SetTextDecorationStyle);
50         UPDATE_TEXT_STYLE(fontStyle, TextCase, SetTextCase);
51         UPDATE_TEXT_STYLE(fontStyle, AdaptMinFontSize, SetAdaptMinFontSize);
52         UPDATE_TEXT_STYLE(fontStyle, AdaptMaxFontSize, SetAdaptMaxFontSize);
53         UPDATE_TEXT_STYLE(fontStyle, LetterSpacing, SetLetterSpacing);
54         UPDATE_TEXT_STYLE(fontStyle, SymbolColorList, SetSymbolColorList);
55         UPDATE_TEXT_STYLE(fontStyle, SymbolRenderingStrategy, SetRenderStrategy);
56         UPDATE_TEXT_STYLE(fontStyle, SymbolEffectStrategy, SetEffectStrategy);
57         UPDATE_TEXT_STYLE(fontStyle, SymbolEffectOptions, SetSymbolEffectOptions);
58         UPDATE_TEXT_STYLE(fontStyle, MinFontScale, SetMinFontScale);
59         UPDATE_TEXT_STYLE(fontStyle, MaxFontScale, SetMaxFontScale);
60         UPDATE_TEXT_STYLE(fontStyle, VariableFontWeight, SetVariableFontWeight);
61         UPDATE_TEXT_STYLE(fontStyle, EnableVariableFontWeight, SetEnableVariableFontWeight);
62     }
63     if (textLineStyle) {
64         UPDATE_TEXT_STYLE(textLineStyle, LineHeight, SetLineHeight);
65         UPDATE_TEXT_STYLE(textLineStyle, TextBaseline, SetTextBaseline);
66         UPDATE_TEXT_STYLE(textLineStyle, BaselineOffset, SetBaselineOffset);
67         UPDATE_TEXT_STYLE(textLineStyle, TextOverflow, SetTextOverflow);
68         UPDATE_TEXT_STYLE(textLineStyle, TextAlign, SetTextAlign);
69         UPDATE_TEXT_STYLE(textLineStyle, MaxLines, SetMaxLines);
70         UPDATE_TEXT_STYLE(textLineStyle, TextIndent, SetTextIndent);
71         UPDATE_TEXT_STYLE(textLineStyle, WordBreak, SetWordBreak);
72         UPDATE_TEXT_STYLE(textLineStyle, EllipsisMode, SetEllipsisMode);
73         UPDATE_TEXT_STYLE(textLineStyle, LineSpacing, SetLineSpacing);
74         UPDATE_TEXT_STYLE(textLineStyle, LineBreakStrategy, SetLineBreakStrategy);
75         UPDATE_TEXT_STYLE(textLineStyle, AllowScale, SetAllowScale);
76     }
77     return textStyle;
78 }
79 
UseSelfStyle(const std::unique_ptr<FontStyle> & fontStyle,const std::unique_ptr<TextLineStyle> & textLineStyle,TextStyle & textStyle)80 void UseSelfStyle(const std::unique_ptr<FontStyle>& fontStyle,
81     const std::unique_ptr<TextLineStyle>& textLineStyle, TextStyle& textStyle)
82 {
83     if (fontStyle) {
84         UPDATE_TEXT_STYLE(fontStyle, FontSize, SetFontSize);
85         UPDATE_TEXT_STYLE(fontStyle, TextColor, SetTextColor);
86         UPDATE_TEXT_STYLE(fontStyle, TextShadow, SetTextShadows);
87         UPDATE_TEXT_STYLE(fontStyle, ItalicFontStyle, SetFontStyle);
88         UPDATE_TEXT_STYLE(fontStyle, FontWeight, SetFontWeight);
89         UPDATE_TEXT_STYLE(fontStyle, FontFamily, SetFontFamilies);
90         UPDATE_TEXT_STYLE(fontStyle, FontFeature, SetFontFeatures);
91         UPDATE_TEXT_STYLE(fontStyle, TextDecoration, SetTextDecoration);
92         UPDATE_TEXT_STYLE(fontStyle, TextDecorationColor, SetTextDecorationColor);
93         UPDATE_TEXT_STYLE(fontStyle, TextDecorationStyle, SetTextDecorationStyle);
94         UPDATE_TEXT_STYLE(fontStyle, TextCase, SetTextCase);
95         UPDATE_TEXT_STYLE(fontStyle, AdaptMinFontSize, SetAdaptMinFontSize);
96         UPDATE_TEXT_STYLE(fontStyle, AdaptMaxFontSize, SetAdaptMaxFontSize);
97         UPDATE_TEXT_STYLE(fontStyle, LetterSpacing, SetLetterSpacing);
98         UPDATE_TEXT_STYLE(fontStyle, SymbolColorList, SetSymbolColorList);
99         UPDATE_TEXT_STYLE(fontStyle, SymbolRenderingStrategy, SetRenderStrategy);
100         UPDATE_TEXT_STYLE(fontStyle, SymbolEffectStrategy, SetEffectStrategy);
101         UPDATE_TEXT_STYLE(fontStyle, SymbolEffectOptions, SetSymbolEffectOptions);
102         UPDATE_TEXT_STYLE(fontStyle, MinFontScale, SetMinFontScale);
103         UPDATE_TEXT_STYLE(fontStyle, MaxFontScale, SetMaxFontScale);
104         UPDATE_TEXT_STYLE(fontStyle, VariableFontWeight, SetVariableFontWeight);
105         UPDATE_TEXT_STYLE(fontStyle, EnableVariableFontWeight, SetEnableVariableFontWeight);
106     }
107     if (textLineStyle) {
108         UPDATE_TEXT_STYLE(textLineStyle, LineHeight, SetLineHeight);
109         UPDATE_TEXT_STYLE(textLineStyle, TextBaseline, SetTextBaseline);
110         UPDATE_TEXT_STYLE(textLineStyle, BaselineOffset, SetBaselineOffset);
111         UPDATE_TEXT_STYLE(textLineStyle, TextOverflow, SetTextOverflow);
112         UPDATE_TEXT_STYLE(textLineStyle, TextAlign, SetTextAlign);
113         UPDATE_TEXT_STYLE(textLineStyle, MaxLines, SetMaxLines);
114         UPDATE_TEXT_STYLE(textLineStyle, TextIndent, SetTextIndent);
115         UPDATE_TEXT_STYLE(textLineStyle, WordBreak, SetWordBreak);
116         UPDATE_TEXT_STYLE(textLineStyle, EllipsisMode, SetEllipsisMode);
117         UPDATE_TEXT_STYLE(textLineStyle, LineSpacing, SetLineSpacing);
118     }
119 }
120 
CreateTextStyleUsingThemeWithText(const RefPtr<FrameNode> frameNode,const std::unique_ptr<FontStyle> & fontStyle,const std::unique_ptr<TextLineStyle> & textLineStyle,const RefPtr<TextTheme> & textTheme)121 TextStyle CreateTextStyleUsingThemeWithText(const RefPtr<FrameNode> frameNode,
122     const std::unique_ptr<FontStyle>& fontStyle, const std::unique_ptr<TextLineStyle>& textLineStyle,
123     const RefPtr<TextTheme>& textTheme)
124 {
125     TextStyle textStyle = CreateTextStyleUsingTheme(fontStyle, textLineStyle, textTheme);
126     auto renderContext = frameNode->GetRenderContext();
127     if (renderContext->HasForegroundColor() || renderContext->HasForegroundColorStrategy()) {
128         textStyle.SetTextColor(Color::FOREGROUND);
129     }
130     return textStyle;
131 }
GetFontSizeInJson(const std::optional<Dimension> & value)132 std::string GetFontSizeInJson(const std::optional<Dimension>& value)
133 {
134     return value.value_or(TEXT_DEFAULT_FONT_SIZE).ToString();
135 }
GetFontStyleInJson(const std::optional<Ace::FontStyle> & value)136 std::string GetFontStyleInJson(const std::optional<Ace::FontStyle>& value)
137 {
138     return value.value_or(Ace::FontStyle::NORMAL) == Ace::FontStyle::NORMAL ? "FontStyle.Normal" : "FontStyle.Italic";
139 }
GetFontWeightInJson(const std::optional<FontWeight> & value)140 std::string GetFontWeightInJson(const std::optional<FontWeight>& value)
141 {
142     return V2::ConvertWrapFontWeightToStirng(value.value_or(FontWeight::NORMAL));
143 }
GetFontFamilyInJson(const std::optional<std::vector<std::string>> & value)144 std::string GetFontFamilyInJson(const std::optional<std::vector<std::string>>& value)
145 {
146     std::vector<std::string> fontFamilyVector = value.value_or<std::vector<std::string>>({ "HarmonyOS Sans" });
147     if (fontFamilyVector.empty()) {
148         fontFamilyVector = std::vector<std::string>({ "HarmonyOS Sans" });
149     }
150     std::string fontFamily = fontFamilyVector.at(0);
151     for (uint32_t i = 1; i < fontFamilyVector.size(); ++i) {
152         fontFamily += ',' + fontFamilyVector.at(i);
153     }
154     return fontFamily;
155 }
GetSymbolRenderingStrategyInJson(const std::optional<uint32_t> & value)156 std::string GetSymbolRenderingStrategyInJson(const std::optional<uint32_t>& value)
157 {
158     std::string text;
159     if (value == RENDERINGSTRATEGY_MULTIPLE_COLOR) {
160         text = "SymbolRenderingStrategy.MULTIPLE_COLOR";
161     } else if (value == RENDERINGSTRATEGY_MULTIPLE_OPACITY) {
162         text = "SymbolRenderingStrategy.MULTIPLE_OPACITY";
163     } else {
164         text = "SymbolRenderingStrategy.SINGLE";
165     }
166     return text;
167 }
GetSymbolEffectStrategyInJson(const std::optional<uint32_t> & value)168 std::string GetSymbolEffectStrategyInJson(const std::optional<uint32_t>& value)
169 {
170     std::string text;
171     SymbolEffectType type = static_cast<SymbolEffectType>(value.value_or(0));
172     if (type == SymbolEffectType::SCALE) {
173         text = "SymbolEffectStrategy.SCALE";
174     } else if (type == SymbolEffectType::HIERARCHICAL) {
175         text = "SymbolEffectStrategy.HIERARCHICAL";
176     } else {
177         text = "SymbolEffectStrategy.NONE";
178     }
179     return text;
180 }
181 
GetLineBreakStrategyInJson(const std::optional<Ace::LineBreakStrategy> & value)182 std::string GetLineBreakStrategyInJson(const std::optional<Ace::LineBreakStrategy>& value)
183 {
184     std::string text;
185     if (value == LineBreakStrategy::HIGH_QUALITY) {
186         text = "HIGH_QUALITY";
187     } else if (value == LineBreakStrategy::BALANCED) {
188         text = "BALANCED";
189     } else {
190         text = "GREEDY";
191     }
192     return text;
193 }
194 
GetSymbolEffectOptionsInJson(const std::optional<SymbolEffectOptions> & value)195 std::string GetSymbolEffectOptionsInJson(const std::optional<SymbolEffectOptions>& value)
196 {
197     std::string text = "";
198     if (value.has_value()) {
199         text = value.value().ToString();
200     }
201     return text;
202 }
203 
UpdateColorByResourceId()204 void FontStyle::UpdateColorByResourceId()
205 {
206     if (propTextColor) {
207         propTextColor->UpdateColorByResourceId();
208     }
209     if (propTextDecorationColor) {
210         propTextDecorationColor->UpdateColorByResourceId();
211     }
212     if (propTextShadow) {
213         auto& shadows = propTextShadow.value();
214         std::for_each(shadows.begin(), shadows.end(), [](Shadow& sd) { sd.UpdateColorByResourceId(); });
215     }
216     if (propSymbolColorList) {
217         auto& colors = propSymbolColorList.value();
218         std::for_each(colors.begin(), colors.end(), [](Color& cl) { cl.UpdateColorByResourceId(); });
219     }
220 }
221 } // namespace OHOS::Ace::NG
222