• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components_ng/pattern/text/text_layout_property.h"
18 
19 namespace {
20 constexpr uint32_t RENDERINGSTRATEGY_MULTIPLE_COLOR = 1;
21 constexpr uint32_t RENDERINGSTRATEGY_MULTIPLE_OPACITY = 2;
22 };  // namespace
23 
24 namespace OHOS::Ace::NG {
25 #define UPDATE_TEXT_STYLE(group, name, func)             \
26     do {                                                 \
27         if ((group)->prop##name.has_value()) {           \
28             textStyle.func((group)->prop##name.value()); \
29         }                                                \
30     } while (false)
31 
32 #define UPDATE_TEXT_STYLE_WITH_THEME(group, name, styleName)                      \
33     do {                                                                          \
34         if (group && (group)->prop##name.has_value()) {                           \
35             textStyle.Set##styleName((group)->prop##name.value());                \
36         } else if (textTheme) {                                                   \
37             textStyle.Set##styleName(textTheme->GetTextStyle().Get##styleName()); \
38         }                                                                         \
39     } while (false)
40 
CreateTextStyleUsingTheme(const std::unique_ptr<FontStyle> & fontStyle,const std::unique_ptr<TextLineStyle> & textLineStyle,const RefPtr<TextTheme> & textTheme,bool isSymbol)41 TextStyle CreateTextStyleUsingTheme(const std::unique_ptr<FontStyle>& fontStyle,
42     const std::unique_ptr<TextLineStyle>& textLineStyle, const RefPtr<TextTheme>& textTheme, bool isSymbol)
43 {
44     TextStyle textStyle = textTheme ? textTheme->GetTextStyle() : TextStyle();
45 #ifndef OHOS_STANDARD_SYSTEM
46     const std::vector<std::string> defaultFontFamily = { "sans-serif" };
47     textStyle.SetFontFamilies(defaultFontFamily);
48 #endif
49     UseSelfStyle(fontStyle, textLineStyle, textStyle, isSymbol);
50     return textStyle;
51 }
52 
CreateTextStyleUsingTheme(const RefPtr<TextLayoutProperty> & property,const RefPtr<TextTheme> & textTheme,TextStyle & textStyle,bool isSymbol)53 void CreateTextStyleUsingTheme(const RefPtr<TextLayoutProperty>& property, const RefPtr<TextTheme>& textTheme,
54     TextStyle& textStyle, bool isSymbol)
55 {
56     UseSelfStyleWithTheme(property, textStyle, textTheme, isSymbol);
57 }
58 
UseSelfStyleWithTheme(const RefPtr<TextLayoutProperty> & property,TextStyle & textStyle,const RefPtr<TextTheme> & textTheme,bool isSymbol)59 void UseSelfStyleWithTheme(const RefPtr<TextLayoutProperty>& property, TextStyle& textStyle,
60     const RefPtr<TextTheme>& textTheme, bool isSymbol)
61 {
62     CHECK_NULL_VOID(textTheme);
63     auto& fontStyle = property->GetFontStyle();
64     auto& textLineStyle = property->GetTextLineStyle();
65     // The setting of AllowScale, MinFontScale, MaxFontScale must be done before any Dimension-type properties that
66     // depend on its value.
67     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, AllowScale, AllowScale);
68     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, MinFontScale, MinFontScale);
69     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, MaxFontScale, MaxFontScale);
70 
71     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, FontSize, FontSize);
72     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, AdaptMinFontSize, AdaptMinFontSize);
73     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, AdaptMaxFontSize, AdaptMaxFontSize);
74     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, LetterSpacing, LetterSpacing);
75 
76     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, TextShadow, TextShadows);
77     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, ItalicFontStyle, FontStyle);
78     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, FontWeight, FontWeight);
79     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, FontFeature, FontFeatures);
80     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, TextDecoration, TextDecoration);
81     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, TextDecorationColor, TextDecorationColor);
82     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, TextDecorationStyle, TextDecorationStyle);
83     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, TextCase, TextCase);
84     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, VariableFontWeight, VariableFontWeight);
85     UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, EnableVariableFontWeight, EnableVariableFontWeight);
86 
87     if (isSymbol) {
88         UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, SymbolColorList, SymbolColorList);
89         UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, SymbolRenderingStrategy, RenderStrategy);
90         UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, SymbolEffectStrategy, EffectStrategy);
91         UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, SymbolEffectOptions, SymbolEffectOptions);
92         UPDATE_TEXT_STYLE_WITH_THEME(fontStyle, SymbolType, SymbolType);
93         textStyle.SetSymbolShadow(property->GetSymbolShadowValue(textTheme->GetTextStyle().GetSymbolShadow()));
94         textStyle.SetShaderStyle(property->GetShaderStyleValue(textTheme->GetTextStyle().GetShaderStyle()));
95     }
96 
97     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, LineHeight, LineHeight);
98     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, BaselineOffset, BaselineOffset);
99     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, TextIndent, TextIndent);
100     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, LineSpacing, LineSpacing);
101     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, TextBaseline, TextBaseline);
102     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, TextOverflow, TextOverflow);
103     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, TextAlign, TextAlign);
104     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, TextVerticalAlign, ParagraphVerticalAlign);
105     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, MaxLines, MaxLines);
106     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, WordBreak, WordBreak);
107     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, EllipsisMode, EllipsisMode);
108     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, LineBreakStrategy, LineBreakStrategy);
109     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, IsOnlyBetweenLines, IsOnlyBetweenLines);
110     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, ParagraphSpacing, ParagraphSpacing);
111     UPDATE_TEXT_STYLE_WITH_THEME(textLineStyle, OptimizeTrailingSpace, OptimizeTrailingSpace);
112 }
113 
UseSelfStyle(const std::unique_ptr<FontStyle> & fontStyle,const std::unique_ptr<TextLineStyle> & textLineStyle,TextStyle & textStyle,bool isSymbol)114 void UseSelfStyle(const std::unique_ptr<FontStyle>& fontStyle, const std::unique_ptr<TextLineStyle>& textLineStyle,
115     TextStyle& textStyle, bool isSymbol)
116 {
117     if (textLineStyle) {
118         UPDATE_TEXT_STYLE(textLineStyle, AllowScale, SetAllowScale);
119     }
120     if (fontStyle) {
121         UPDATE_TEXT_STYLE(fontStyle, MinFontScale, SetMinFontScale);
122         UPDATE_TEXT_STYLE(fontStyle, MaxFontScale, SetMaxFontScale);
123 
124         UPDATE_TEXT_STYLE(fontStyle, FontSize, SetFontSize);
125         UPDATE_TEXT_STYLE(fontStyle, AdaptMinFontSize, SetAdaptMinFontSize);
126         UPDATE_TEXT_STYLE(fontStyle, AdaptMaxFontSize, SetAdaptMaxFontSize);
127         UPDATE_TEXT_STYLE(fontStyle, LetterSpacing, SetLetterSpacing);
128 
129         UPDATE_TEXT_STYLE(fontStyle, TextColor, SetTextColor);
130         UPDATE_TEXT_STYLE(fontStyle, TextShadow, SetTextShadows);
131         UPDATE_TEXT_STYLE(fontStyle, ItalicFontStyle, SetFontStyle);
132         UPDATE_TEXT_STYLE(fontStyle, FontWeight, SetFontWeight);
133         UPDATE_TEXT_STYLE(fontStyle, FontFamily, SetFontFamilies);
134         UPDATE_TEXT_STYLE(fontStyle, FontFeature, SetFontFeatures);
135         UPDATE_TEXT_STYLE(fontStyle, StrokeWidth, SetStrokeWidth);
136         UPDATE_TEXT_STYLE(fontStyle, StrokeColor, SetStrokeColor);
137         UPDATE_TEXT_STYLE(fontStyle, Superscript, SetSuperscript);
138         UPDATE_TEXT_STYLE(fontStyle, TextDecoration, SetTextDecoration);
139         UPDATE_TEXT_STYLE(fontStyle, TextDecorationColor, SetTextDecorationColor);
140         UPDATE_TEXT_STYLE(fontStyle, TextDecorationStyle, SetTextDecorationStyle);
141         UPDATE_TEXT_STYLE(fontStyle, LineThicknessScale, SetLineThicknessScale);
142         UPDATE_TEXT_STYLE(fontStyle, TextCase, SetTextCase);
143 
144         UPDATE_TEXT_STYLE(fontStyle, VariableFontWeight, SetVariableFontWeight);
145         UPDATE_TEXT_STYLE(fontStyle, EnableVariableFontWeight, SetEnableVariableFontWeight);
146 
147         if (isSymbol) {
148             UPDATE_TEXT_STYLE(fontStyle, SymbolColorList, SetSymbolColorList);
149             UPDATE_TEXT_STYLE(fontStyle, SymbolRenderingStrategy, SetRenderStrategy);
150             UPDATE_TEXT_STYLE(fontStyle, SymbolEffectStrategy, SetEffectStrategy);
151             UPDATE_TEXT_STYLE(fontStyle, SymbolEffectOptions, SetSymbolEffectOptions);
152             UPDATE_TEXT_STYLE(fontStyle, SymbolType, SetSymbolType);
153         }
154     }
155     if (textLineStyle) {
156         UPDATE_TEXT_STYLE(textLineStyle, LineHeight, SetLineHeight);
157         UPDATE_TEXT_STYLE(textLineStyle, BaselineOffset, SetBaselineOffset);
158         UPDATE_TEXT_STYLE(textLineStyle, TextIndent, SetTextIndent);
159         UPDATE_TEXT_STYLE(textLineStyle, LineSpacing, SetLineSpacing);
160 
161         UPDATE_TEXT_STYLE(textLineStyle, HalfLeading, SetHalfLeading);
162         UPDATE_TEXT_STYLE(textLineStyle, TextBaseline, SetTextBaseline);
163         UPDATE_TEXT_STYLE(textLineStyle, TextOverflow, SetTextOverflow);
164         UPDATE_TEXT_STYLE(textLineStyle, TextAlign, SetTextAlign);
165         UPDATE_TEXT_STYLE(textLineStyle, TextVerticalAlign, SetParagraphVerticalAlign);
166         UPDATE_TEXT_STYLE(textLineStyle, MaxLines, SetMaxLines);
167         UPDATE_TEXT_STYLE(textLineStyle, WordBreak, SetWordBreak);
168         UPDATE_TEXT_STYLE(textLineStyle, EllipsisMode, SetEllipsisMode);
169         UPDATE_TEXT_STYLE(textLineStyle, LineBreakStrategy, SetLineBreakStrategy);
170         UPDATE_TEXT_STYLE(textLineStyle, IsOnlyBetweenLines, SetIsOnlyBetweenLines);
171         UPDATE_TEXT_STYLE(textLineStyle, ParagraphSpacing, SetParagraphSpacing);
172         UPDATE_TEXT_STYLE(textLineStyle, OptimizeTrailingSpace, SetOptimizeTrailingSpace);
173     }
174 }
175 
GetFontSizeInJson(const std::optional<Dimension> & value)176 std::string GetFontSizeInJson(const std::optional<Dimension>& value)
177 {
178     return value.value_or(TEXT_DEFAULT_FONT_SIZE).ToString();
179 }
GetFontStyleInJson(const std::optional<Ace::FontStyle> & value)180 std::string GetFontStyleInJson(const std::optional<Ace::FontStyle>& value)
181 {
182     return value.value_or(Ace::FontStyle::NORMAL) == Ace::FontStyle::NORMAL ? "FontStyle.Normal" : "FontStyle.Italic";
183 }
GetFontWeightInJson(const std::optional<FontWeight> & value)184 std::string GetFontWeightInJson(const std::optional<FontWeight>& value)
185 {
186     return V2::ConvertWrapFontWeightToStirng(value.value_or(FontWeight::NORMAL));
187 }
GetFontFamilyInJson(const std::optional<std::vector<std::string>> & value)188 std::string GetFontFamilyInJson(const std::optional<std::vector<std::string>>& value)
189 {
190     std::vector<std::string> fontFamilyVector = value.value_or<std::vector<std::string>>({ "HarmonyOS Sans" });
191     if (fontFamilyVector.empty()) {
192         fontFamilyVector = std::vector<std::string>({ "HarmonyOS Sans" });
193     }
194     std::string fontFamily = fontFamilyVector.at(0);
195     for (uint32_t i = 1; i < fontFamilyVector.size(); ++i) {
196         fontFamily += ',' + fontFamilyVector.at(i);
197     }
198     return fontFamily;
199 }
GetFontFamilyInJson(const std::vector<std::string> & fontFamilyVector)200 std::string GetFontFamilyInJson(const std::vector<std::string>& fontFamilyVector)
201 {
202     std::string fontFamily;
203     if (fontFamilyVector.empty()) {
204         return fontFamily;
205     }
206     fontFamily = fontFamilyVector.at(0);
207     for (uint32_t i = 1; i < fontFamilyVector.size(); ++i) {
208         fontFamily += ',' + fontFamilyVector.at(i);
209     }
210     return fontFamily;
211 }
GetSymbolRenderingStrategyInJson(const std::optional<uint32_t> & value)212 std::string GetSymbolRenderingStrategyInJson(const std::optional<uint32_t>& value)
213 {
214     std::string text;
215     if (value == RENDERINGSTRATEGY_MULTIPLE_COLOR) {
216         text = "SymbolRenderingStrategy.MULTIPLE_COLOR";
217     } else if (value == RENDERINGSTRATEGY_MULTIPLE_OPACITY) {
218         text = "SymbolRenderingStrategy.MULTIPLE_OPACITY";
219     } else {
220         text = "SymbolRenderingStrategy.SINGLE";
221     }
222     return text;
223 }
GetSymbolEffectStrategyInJson(const std::optional<uint32_t> & value)224 std::string GetSymbolEffectStrategyInJson(const std::optional<uint32_t>& value)
225 {
226     std::string text;
227     SymbolEffectType type = static_cast<SymbolEffectType>(value.value_or(0));
228     if (type == SymbolEffectType::SCALE) {
229         text = "SymbolEffectStrategy.SCALE";
230     } else if (type == SymbolEffectType::HIERARCHICAL) {
231         text = "SymbolEffectStrategy.HIERARCHICAL";
232     } else {
233         text = "SymbolEffectStrategy.NONE";
234     }
235     return text;
236 }
237 
GetLineBreakStrategyInJson(const std::optional<Ace::LineBreakStrategy> & value)238 std::string GetLineBreakStrategyInJson(const std::optional<Ace::LineBreakStrategy>& value)
239 {
240     std::string text;
241     if (value == LineBreakStrategy::HIGH_QUALITY) {
242         text = "HIGH_QUALITY";
243     } else if (value == LineBreakStrategy::BALANCED) {
244         text = "BALANCED";
245     } else {
246         text = "GREEDY";
247     }
248     return text;
249 }
250 
GetSymbolEffectOptionsInJson(const std::optional<SymbolEffectOptions> & value)251 std::string GetSymbolEffectOptionsInJson(const std::optional<SymbolEffectOptions>& value)
252 {
253     std::string text = "";
254     if (value.has_value()) {
255         text = value.value().ToString();
256     }
257     return text;
258 }
259 
GetSymbolShadowInJson(const std::optional<SymbolShadow> & value)260 std::unique_ptr<JsonValue> GetSymbolShadowInJson(const std::optional<SymbolShadow>& value)
261 {
262     auto res = JsonUtil::Create(true);
263     if (!value.has_value()) {
264         return res;
265     }
266     const auto& shadow = value.value();
267     res->Put("color", (shadow.color).ColorToString().c_str());
268     std::string offsetStr = "[" + std::to_string(shadow.offset.first) + ", "
269                            + std::to_string(shadow.offset.second) + "]";
270     res->Put("offset", offsetStr.c_str());
271     res->Put("radius", std::to_string(shadow.radius).c_str());
272     return res;
273 }
274 
GradientTypeToString(SymbolGradientType type)275 std::string GradientTypeToString(SymbolGradientType type)
276 {
277     switch (type) {
278         case SymbolGradientType::COLOR_SHADER:
279             return "COLOR_SHADER";
280         case SymbolGradientType::RADIAL_GRADIENT:
281             return "RADIAL_GRADIENT";
282         case SymbolGradientType::LINEAR_GRADIENT:
283             return "LINEAR_GRADIENT";
284         default:
285             return "UNKNOWN";
286     }
287 }
288 
GetShaderStyleInJson(const std::optional<std::vector<SymbolGradient>> & value)289 std::unique_ptr<JsonValue> GetShaderStyleInJson(const std::optional<std::vector<SymbolGradient>>& value)
290 {
291     auto array = JsonUtil::CreateArray(true);
292     if (!value.has_value() || value->empty()) {
293         return array;
294     }
295     for (const auto& gradient : *value) {
296         auto obj = JsonUtil::Create(true);
297         obj->Put("type", GradientTypeToString(gradient.type).c_str());
298         auto colorsArray = JsonUtil::CreateArray(true);
299         for (const auto& color : gradient.symbolColor) {
300             colorsArray->Put("", color.ColorToString().c_str());
301         }
302         obj->Put("symbolColor", colorsArray);
303         auto opacitiesArray = JsonUtil::CreateArray(true);
304         for (float opacity : gradient.symbolOpacities) {
305             opacitiesArray->Put("", std::to_string(opacity).c_str());
306         }
307         obj->Put("symbolOpacities", opacitiesArray);
308         obj->Put("repeating", gradient.repeating ? "true" : "false");
309         if (gradient.angle.has_value()) {
310             obj->Put("angle", std::to_string(*gradient.angle).c_str());
311         }
312         if (gradient.radius.has_value()) {
313             obj->Put("radius", gradient.radius->ToString().c_str());
314         }
315         if (gradient.radialCenterX.has_value()) {
316             obj->Put("radialCenterX", gradient.radialCenterX->ToString().c_str());
317         }
318         if (gradient.radialCenterY.has_value()) {
319             obj->Put("radialCenterY", gradient.radialCenterY->ToString().c_str());
320         }
321         array->Put(obj);
322     }
323     return array;
324 }
325 
UpdateColorByResourceId()326 void FontStyle::UpdateColorByResourceId()
327 {
328     if (propTextColor) {
329         propTextColor->UpdateColorByResourceId();
330     }
331     if (propTextDecorationColor) {
332         propTextDecorationColor->UpdateColorByResourceId();
333     }
334     if (propTextShadow) {
335         auto& shadows = propTextShadow.value();
336         std::for_each(shadows.begin(), shadows.end(), [](Shadow& sd) { sd.UpdateColorByResourceId(); });
337     }
338     if (propSymbolColorList) {
339         auto& colors = propSymbolColorList.value();
340         std::for_each(colors.begin(), colors.end(), [](Color& cl) { cl.UpdateColorByResourceId(); });
341     }
342 }
343 
GetPlaceHolderAlignmentFromVerticalAlign(VerticalAlign verticalAlign)344 PlaceholderAlignment GetPlaceHolderAlignmentFromVerticalAlign(VerticalAlign verticalAlign)
345 {
346     PlaceholderAlignment alignment;
347     switch (verticalAlign) {
348         case VerticalAlign::TOP:
349             alignment = PlaceholderAlignment::TOP;
350             break;
351         case VerticalAlign::CENTER:
352             alignment = PlaceholderAlignment::MIDDLE;
353             break;
354         case VerticalAlign::BOTTOM:
355         case VerticalAlign::NONE:
356             alignment = PlaceholderAlignment::BOTTOM;
357             break;
358         case VerticalAlign::BASELINE:
359             alignment = PlaceholderAlignment::ABOVEBASELINE;
360             break;
361         case VerticalAlign::FOLLOW_PARAGRAPH:
362             alignment = PlaceholderAlignment::FOLLOW_PARAGRAPH;
363             break;
364         default:
365             alignment = PlaceholderAlignment::BOTTOM;
366     }
367     return alignment;
368 }
369 } // namespace OHOS::Ace::NG
370