• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     /* no fixed attr below, just return */
111     if (filter.IsFastFilter()) {
112         return;
113     }
114     auto host = GetHost();
115     CHECK_NULL_VOID(host);
116     auto themeScopeId = host->GetThemeScopeId();
117     auto context = host->GetContext();
118     CHECK_NULL_VOID(context);
119     auto theme = context->GetTheme<TextTheme>(themeScopeId);
120     auto defaultColor = theme ? theme->GetTextStyle().GetTextColor() : Color::BLACK;
121     /* distinguish SymbolGlyph font color list and Text font color in "fontColor" */
122     if (host->GetTag() == V2::SYMBOL_ETS_TAG) {
123         const std::optional<std::vector<Color>>& colorListOptional = GetSymbolColorList();
124         if (colorListOptional.has_value()) {
125             json->PutExtAttr("fontColor", StringUtils::SymbolColorListToString(colorListOptional.value())
126                 .c_str(), filter);
127         } else {
128             json->PutExtAttr("fontColor", StringUtils::SymbolColorListToString(std::vector<Color>()).c_str(), filter);
129         }
130     } else {
131         json->PutExtAttr("fontColor", GetTextColor().value_or(defaultColor).ColorToString().c_str(), filter);
132     }
133     json->PutExtAttr("fontStyle", GetFontStyleInJson(GetItalicFontStyle()).c_str(), filter);
134     json->PutExtAttr("fontWeight", GetFontWeightInJson(GetFontWeight()).c_str(), filter);
135     json->PutExtAttr("fontFamily", GetFontFamilyInJson(GetFontFamily()).c_str(), filter);
136     json->PutExtAttr("renderingStrategy",
137         GetSymbolRenderingStrategyInJson(GetSymbolRenderingStrategy()).c_str(), filter);
138     json->PutExtAttr("effectStrategy", GetSymbolEffectStrategyInJson(GetSymbolEffectStrategy()).c_str(), filter);
139     json->Put("symbolEffect", GetSymbolEffectOptionsInJson(
140         GetSymbolEffectOptions().value_or(SymbolEffectOptions())).c_str());
141     json->PutExtAttr("symbolShadow", GetSymbolShadowInJson(GetSymbolShadow()), filter);
142 
143     auto jsonDecoration = JsonUtil::Create(true);
144     std::string type = V2::ConvertWrapTextDecorationToStirng(GetTextDecorationFirst());
145     jsonDecoration->Put("type", type.c_str());
146     jsonDecoration->Put("color", GetTextDecorationColor().value_or(Color::BLACK).ColorToString().c_str());
147     std::string style =
148         V2::ConvertWrapTextDecorationStyleToString(GetTextDecorationStyle().value_or(TextDecorationStyle::SOLID));
149     jsonDecoration->Put("style", style.c_str());
150     json->PutExtAttr("decoration", jsonDecoration->ToString().c_str(), filter);
151 
152     json->PutExtAttr("textCase",
153         V2::ConvertWrapTextCaseToStirng(GetTextCase().value_or(TextCase::NORMAL)).c_str(), filter);
154     json->PutExtAttr("minFontSize", GetAdaptMinFontSize().value_or(Dimension()).ToString().c_str(), filter);
155     json->PutExtAttr("maxFontSize", GetAdaptMaxFontSize().value_or(Dimension()).ToString().c_str(), filter);
156     json->PutExtAttr("letterSpacing", GetLetterSpacing().value_or(Dimension()).ToString().c_str(), filter);
157     json->PutExtAttr("lineHeight", GetLineHeight().value_or(0.0_vp).ToString().c_str(), filter);
158     json->PutExtAttr("textBaseline",
159         TEXT_BASE_LINE_TO_STRING.at(static_cast<int32_t>(GetTextBaseline().value_or(TextBaseline::ALPHABETIC)))
160             .c_str(), filter);
161     json->PutExtAttr("baselineOffset",
162         std::to_string(static_cast<int32_t>(GetBaselineOffset().value_or(0.0_vp).Value())).c_str(), filter);
163     json->PutExtAttr("textAlign",
164         V2::ConvertWrapTextAlignToString(GetTextAlign().value_or(TextAlign::START)).c_str(), filter);
165     json->PutExtAttr("textVerticalAlign", V2::ConvertWrapTextVerticalAlignToString(
166         GetTextVerticalAlign().value_or(TextVerticalAlign::BASELINE)).c_str(), filter);
167     json->PutExtAttr("textOverflow",
168         V2::ConvertWrapTextOverflowToString(GetTextOverflow().value_or(TextOverflow::CLIP)).c_str(), filter);
169     json->PutExtAttr("maxLines", std::to_string(GetMaxLines().value_or(UINT32_MAX)).c_str(), filter);
170     json->PutExtAttr("enableAutoSpacing", std::to_string(GetEnableAutoSpacing().value_or(false)).c_str(), filter);
171 
172     auto shadow = GetTextShadow().value_or(std::vector<Shadow> { Shadow() });
173     // Determines if there are multiple textShadows
174     auto jsonShadow = (shadow.size() == 1) ? CovertShadowToJson(shadow.front()) : CovertShadowsToJson(shadow);
175     json->PutExtAttr("textShadow", jsonShadow, filter);
176     json->PutExtAttr("heightAdaptivePolicy", V2::ConvertWrapTextHeightAdaptivePolicyToString(
177         GetHeightAdaptivePolicy().value_or(TextHeightAdaptivePolicy::MAX_LINES_FIRST)).c_str(), filter);
178     json->PutExtAttr("copyOption", GetCopyOptionString().c_str(), filter);
179     json->PutExtAttr("wordBreak",
180         V2::ConvertWrapWordBreakToString(GetWordBreak().value_or(WordBreak::BREAK_WORD)).c_str(), filter);
181     json->PutExtAttr("lineBreakStrategy", V2::ConvertWrapLineBreakStrategyToString(
182         GetLineBreakStrategy().value_or(LineBreakStrategy::GREEDY)).c_str(), filter);
183     json->PutExtAttr("ellipsisMode",
184         V2::ConvertEllipsisModeToString(GetEllipsisMode().value_or(EllipsisMode::TAIL)).c_str(), filter);
185     json->PutExtAttr("textSelectable", V2::ConvertWrapTextSelectableToString(
186         GetTextSelectableMode().value_or(TextSelectableMode::SELECTABLE_UNFOCUSABLE)).c_str(), filter);
187     json->PutExtAttr("marqueeOptions", GetTextMarqueeOptionsString().c_str(), filter);
188     json->PutExtAttr("privacySensitive", host ? host->IsPrivacySensitive() : false, filter);
189     json->PutExtAttr("minFontScale", std::to_string(GetMinFontScale().value_or(MINFONTSCALE)).c_str(), filter);
190     json->PutExtAttr("maxFontScale", std::to_string(GetMaxFontScale().value_or(MAXFONTSCALE)).c_str(), filter);
191     json->PutExtAttr("lineSpacing", GetLineSpacing().value_or(0.0_vp).ToString().c_str(), filter);
192     json->PutExtAttr("onlyBetweenLines", GetIsOnlyBetweenLines().value_or(false) ? "true" : "false", filter);
193     json->PutExtAttr("optimizeTrailingSpace", GetOptimizeTrailingSpace().value_or(false) ? "true" : "false", filter);
194 
195     if (GetTextEffectStrategyValue(TextEffectStrategy::NONE) != TextEffectStrategy::NONE) {
196         auto jsonNumericTransiton = JsonUtil::Create(true);
197         std::string direction = StringUtils::ToString(GetTextFlipDirectionValue(TextFlipDirection::DOWN));
198         std::string enableBlur = GetTextFlipEnableBlurValue(false) ? "true" : "false";
199         jsonNumericTransiton->Put("flipDirection", direction.c_str());
200         jsonNumericTransiton->Put("enableBlur", enableBlur.c_str());
201         json->PutExtAttr("numericTextTransitionOptions", jsonNumericTransiton->ToString().c_str(), filter);
202     }
203 }
204 
FromJson(const std::unique_ptr<JsonValue> & json)205 void TextLayoutProperty::FromJson(const std::unique_ptr<JsonValue>& json)
206 {
207     UpdateContent(json->GetString("content"));
208     UpdateFontSize(Dimension::FromString(json->GetString("fontSize")));
209     UpdateTextColor(Color::ColorFromString(json->GetString("fontColor")));
210     UpdateFontWeight(V2::ConvertWrapStringToFontWeight(json->GetString("fontWeight")));
211     UpdateTextAlign(V2::ConvertWrapStringToTextAlign(json->GetString("textAlign")));
212     UpdateTextVerticalAlign(V2::ConvertWrapStringToTextVerticalAlign(json->GetString("textAlign")));
213     UpdateTextOverflow(V2::ConvertWrapStringToTextOverflow(json->GetString("textOverflow")));
214     UpdateMaxLines(StringUtils::StringToUint(json->GetString("maxLines")));
215     UpdateMarqueeOptionsFromJson(json->GetObject("marqueeOptions"));
216     LayoutProperty::FromJson(json);
217 }
218 } // namespace OHOS::Ace::NG
219