1 /*
2 * Copyright (c) 2022 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 "base/utils/utf_helper.h"
17 #include "core/components_ng/pattern/text/text_layout_property.h"
18
19 namespace OHOS::Ace::NG {
20 namespace {
21 constexpr float MINFONTSCALE = 0.85f;
22 constexpr float MAXFONTSCALE = 3.20f;
23 constexpr Dimension DEFAULT_MARQUEE_STEP_VP = 4.0_vp;
24 static const std::array<std::string, 6> TEXT_BASE_LINE_TO_STRING = {
25 "textBaseline.ALPHABETIC",
26 "textBaseline.IDEOGRAPHIC",
27 "textBaseline.TOP",
28 "textBaseline.BOTTOM",
29 "textBaseline.MIDDLE",
30 "textBaseline.HANGING",
31 };
32
CovertShadowToJson(const Shadow & shadow)33 inline std::unique_ptr<JsonValue> CovertShadowToJson(const Shadow& shadow)
34 {
35 auto jsonShadow = JsonUtil::Create(true);
36 jsonShadow->Put("radius", std::to_string(shadow.GetBlurRadius()).c_str());
37 jsonShadow->Put("color", shadow.GetColor().ColorToString().c_str());
38 jsonShadow->Put("offsetX", std::to_string(shadow.GetOffset().GetX()).c_str());
39 jsonShadow->Put("offsetY", std::to_string(shadow.GetOffset().GetY()).c_str());
40 jsonShadow->Put("type", std::to_string(static_cast<int32_t>(shadow.GetShadowType())).c_str());
41 return jsonShadow;
42 }
43
CovertShadowsToJson(const std::vector<Shadow> & shadows)44 std::unique_ptr<JsonValue> CovertShadowsToJson(const std::vector<Shadow>& shadows)
45 {
46 auto jsonShadows = JsonUtil::CreateArray(true);
47 for (const auto& shadow : shadows) {
48 jsonShadows->Put(CovertShadowToJson(shadow));
49 }
50 return jsonShadows;
51 }
52 } // namespace
53
GetCopyOptionString() const54 std::string TextLayoutProperty::GetCopyOptionString() const
55 {
56 std::string copyOptionString = "CopyOptions.None";
57 switch (GetCopyOptionValue(CopyOptions::None)) {
58 case CopyOptions::InApp:
59 copyOptionString = "CopyOptions.InApp";
60 break;
61 case CopyOptions::Local:
62 copyOptionString = "CopyOptions.Local";
63 break;
64 case CopyOptions::Distributed:
65 copyOptionString = "CopyOptions.Distributed";
66 break;
67 case CopyOptions::None:
68 default:
69 break;
70 }
71 return copyOptionString;
72 }
73
GetTextMarqueeOptionsString() const74 std::string TextLayoutProperty::GetTextMarqueeOptionsString() const
75 {
76 auto jsonValue = JsonUtil::Create(true);
77
78 jsonValue->Put("start", GetTextMarqueeStart().value_or(true));
79 jsonValue->Put("step",
80 StringUtils::DoubleToString(GetTextMarqueeStep().value_or(DEFAULT_MARQUEE_STEP_VP.ConvertToPx())).c_str());
81 jsonValue->Put("loop", std::to_string(GetTextMarqueeLoop().value_or(-1)).c_str());
82 jsonValue->Put(
83 "direction", GetTextMarqueeDirection().value_or(MarqueeDirection::DEFAULT) == MarqueeDirection::DEFAULT
84 ? "MarqueeDirection.DEFAULT"
85 : "MarqueeDirection.DEFAULT_REVERSE");
86 jsonValue->Put("delay", std::to_string(GetTextMarqueeDelay().value_or(0)).c_str());
87 jsonValue->Put("fadeout", GetTextMarqueeFadeout().value_or(false));
88 jsonValue->Put(
89 "startPolicy", GetTextMarqueeStartPolicy().value_or(MarqueeStartPolicy::DEFAULT) == MarqueeStartPolicy::DEFAULT
90 ? "MarqueeStartPolicy.DEFAULT"
91 : "MarqueeStartPolicy.ON_FOCUS");
92
93 return jsonValue->ToString();
94 }
95
UpdateMarqueeOptionsFromJson(const std::unique_ptr<JsonValue> & json)96 void TextLayoutProperty::UpdateMarqueeOptionsFromJson(const std::unique_ptr<JsonValue>& json)
97 {
98 UpdateTextMarqueeStart(json->GetBool("start"));
99 UpdateTextMarqueeStep(json->GetDouble("step"));
100 UpdateTextMarqueeLoop(json->GetInt("loop"));
101 UpdateTextMarqueeDirection(V2::ConvertWrapStringToMarqueeDirection(json->GetString("direction")));
102 UpdateTextMarqueeDelay(json->GetInt("delay"));
103 UpdateTextMarqueeFadeout(json->GetBool("fadeout"));
104 UpdateTextMarqueeStartPolicy(V2::ConvertWrapStringToMarqueeStartPolicy(json->GetString("startPolicy")));
105 }
106
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const107 void TextLayoutProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
108 {
109 LayoutProperty::ToJsonValue(json, filter);
110 json->PutFixedAttr("content", UtfUtils::Str16DebugToStr8(GetContent().value_or(u"")).c_str(), filter,
111 FIXED_ATTR_CONTENT);
112 /* no fixed attr below, just return */
113 if (filter.IsFastFilter()) {
114 return;
115 }
116 auto host = GetHost();
117 CHECK_NULL_VOID(host);
118 auto themeScopeId = host->GetThemeScopeId();
119 auto context = host->GetContext();
120 CHECK_NULL_VOID(context);
121 auto theme = context->GetTheme<TextTheme>(themeScopeId);
122 auto defaultColor = theme ? theme->GetTextStyle().GetTextColor() : Color::BLACK;
123 json->PutExtAttr("fontColor",
124 GetTextColor().value_or(defaultColor).ColorToString().c_str(), filter);
125 json->PutExtAttr("fontStyle", GetFontStyleInJson(GetItalicFontStyle()).c_str(), filter);
126 json->PutExtAttr("fontWeight", GetFontWeightInJson(GetFontWeight()).c_str(), filter);
127 json->PutExtAttr("fontFamily", GetFontFamilyInJson(GetFontFamily()).c_str(), filter);
128 json->PutExtAttr("renderingStrategy",
129 GetSymbolRenderingStrategyInJson(GetSymbolRenderingStrategy()).c_str(), filter);
130 json->PutExtAttr("effectStrategy", GetSymbolEffectStrategyInJson(GetSymbolEffectStrategy()).c_str(), filter);
131 json->Put("symbolEffect", GetSymbolEffectOptionsInJson(
132 GetSymbolEffectOptions().value_or(SymbolEffectOptions())).c_str());
133
134 auto jsonDecoration = JsonUtil::Create(true);
135 std::string type = V2::ConvertWrapTextDecorationToStirng(GetTextDecoration().value_or(TextDecoration::NONE));
136 jsonDecoration->Put("type", type.c_str());
137 jsonDecoration->Put("color", GetTextDecorationColor().value_or(Color::BLACK).ColorToString().c_str());
138 std::string style =
139 V2::ConvertWrapTextDecorationStyleToString(GetTextDecorationStyle().value_or(TextDecorationStyle::SOLID));
140 jsonDecoration->Put("style", style.c_str());
141 json->PutExtAttr("decoration", jsonDecoration->ToString().c_str(), filter);
142
143 json->PutExtAttr("textCase",
144 V2::ConvertWrapTextCaseToStirng(GetTextCase().value_or(TextCase::NORMAL)).c_str(), filter);
145 json->PutExtAttr("minFontSize", GetAdaptMinFontSize().value_or(Dimension()).ToString().c_str(), filter);
146 json->PutExtAttr("maxFontSize", GetAdaptMaxFontSize().value_or(Dimension()).ToString().c_str(), filter);
147 json->PutExtAttr("letterSpacing", GetLetterSpacing().value_or(Dimension()).ToString().c_str(), filter);
148 json->PutExtAttr("lineHeight", GetLineHeight().value_or(0.0_vp).ToString().c_str(), filter);
149 json->PutExtAttr("textBaseline",
150 TEXT_BASE_LINE_TO_STRING.at(static_cast<int32_t>(GetTextBaseline().value_or(TextBaseline::ALPHABETIC)))
151 .c_str(), filter);
152 json->PutExtAttr("baselineOffset",
153 std::to_string(static_cast<int32_t>(GetBaselineOffset().value_or(0.0_vp).Value())).c_str(), filter);
154 json->PutExtAttr("textAlign",
155 V2::ConvertWrapTextAlignToString(GetTextAlign().value_or(TextAlign::START)).c_str(), filter);
156 json->PutExtAttr("textOverflow",
157 V2::ConvertWrapTextOverflowToString(GetTextOverflow().value_or(TextOverflow::CLIP)).c_str(), filter);
158 json->PutExtAttr("maxLines", std::to_string(GetMaxLines().value_or(UINT32_MAX)).c_str(), filter);
159
160 ToJsonValueForOption(json, filter);
161 }
162
ToJsonValueForOption(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const163 void TextLayoutProperty::ToJsonValueForOption(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
164 {
165 auto shadow = GetTextShadow().value_or(std::vector<Shadow> { Shadow() });
166 // Determines if there are multiple textShadows
167 auto jsonShadow = (shadow.size() == 1) ? CovertShadowToJson(shadow.front()) : CovertShadowsToJson(shadow);
168 json->PutExtAttr("textShadow", jsonShadow, filter);
169 json->PutExtAttr("heightAdaptivePolicy", V2::ConvertWrapTextHeightAdaptivePolicyToString(
170 GetHeightAdaptivePolicy().value_or(TextHeightAdaptivePolicy::MAX_LINES_FIRST)).c_str(), filter);
171 json->PutExtAttr("copyOption", GetCopyOptionString().c_str(), filter);
172 json->PutExtAttr("wordBreak",
173 V2::ConvertWrapWordBreakToString(GetWordBreak().value_or(WordBreak::BREAK_WORD)).c_str(), filter);
174 json->PutExtAttr("lineBreakStrategy", V2::ConvertWrapLineBreakStrategyToString(
175 GetLineBreakStrategy().value_or(LineBreakStrategy::GREEDY)).c_str(), filter);
176 json->PutExtAttr("ellipsisMode",
177 V2::ConvertEllipsisModeToString(GetEllipsisMode().value_or(EllipsisMode::TAIL)).c_str(), filter);
178 json->PutExtAttr("textSelectable", V2::ConvertWrapTextSelectableToString(
179 GetTextSelectableMode().value_or(TextSelectableMode::SELECTABLE_UNFOCUSABLE)).c_str(), filter);
180 json->PutExtAttr("marqueeOptions", GetTextMarqueeOptionsString().c_str(), filter);
181 auto host = GetHost();
182 json->PutExtAttr("privacySensitive", host ? host->IsPrivacySensitive() : false, filter);
183 json->PutExtAttr("minFontScale", std::to_string(GetMinFontScale().value_or(MINFONTSCALE)).c_str(), filter);
184 json->PutExtAttr("maxFontScale", std::to_string(GetMaxFontScale().value_or(MAXFONTSCALE)).c_str(), filter);
185 }
186
FromJson(const std::unique_ptr<JsonValue> & json)187 void TextLayoutProperty::FromJson(const std::unique_ptr<JsonValue>& json)
188 {
189 UpdateContent(json->GetString("content"));
190 UpdateFontSize(Dimension::FromString(json->GetString("fontSize")));
191 UpdateTextColor(Color::ColorFromString(json->GetString("fontColor")));
192 UpdateFontWeight(V2::ConvertWrapStringToFontWeight(json->GetString("fontWeight")));
193 UpdateTextAlign(V2::ConvertWrapStringToTextAlign(json->GetString("textAlign")));
194 UpdateTextOverflow(V2::ConvertWrapStringToTextOverflow(json->GetString("textOverflow")));
195 UpdateMaxLines(StringUtils::StringToUint(json->GetString("maxLines")));
196 UpdateMarqueeOptionsFromJson(json->GetObject("marqueeOptions"));
197 LayoutProperty::FromJson(json);
198 }
199 } // namespace OHOS::Ace::NG
200