• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "frameworks/bridge/declarative_frontend/jsview/js_symbol.h"
16 
17 #include "core/components_ng/pattern/symbol/constants.h"
18 #include "frameworks/bridge/declarative_frontend/engine/bindings.h"
19 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
20 #include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
22 #include "frameworks/core/components_ng/pattern/symbol/symbol_model.h"
23 #include "frameworks/core/components_ng/pattern/symbol/symbol_model_ng.h"
24 
25 namespace OHOS::Ace {
26 constexpr int32_t SYSTEM_SYMBOL_BOUNDARY = 0XFFFFF;
27 const std::string DEFAULT_SYMBOL_FONTFAMILY = "HM Symbol";
28 
29 std::unique_ptr<SymbolModel> SymbolModel::instance_ = nullptr;
30 std::mutex SymbolModel::mutex_;
31 
GetInstance()32 SymbolModel* SymbolModel::GetInstance()
33 {
34     static NG::SymbolModelNG instance;
35     return &instance;
36 }
37 
38 } // namespace OHOS::Ace
39 
40 namespace OHOS::Ace::Framework {
41 
42 const std::map<std::string, Ace::SymbolEffectType> SYMBOL_EFFECT_TYPE_MAP = {
43     { "ScaleSymbolEffect", SymbolEffectType::SCALE },
44     { "HierarchicalSymbolEffect", SymbolEffectType::HIERARCHICAL },
45     { "AppearSymbolEffect", SymbolEffectType::APPEAR },
46     { "DisappearSymbolEffect", SymbolEffectType::DISAPPEAR },
47     { "BounceSymbolEffect", SymbolEffectType::BOUNCE },
48     { "ReplaceSymbolEffect", SymbolEffectType::REPLACE },
49     { "PulseSymbolEffect", SymbolEffectType::PULSE },
50 };
51 
JSBind(BindingTarget globalObj)52 void JSSymbol::JSBind(BindingTarget globalObj)
53 {
54     JSClass<JSSymbol>::Declare("SymbolGlyph");
55 
56     MethodOptions opt = MethodOptions::NONE;
57     JSClass<JSSymbol>::StaticMethod("create", &JSSymbol::Create, opt);
58     JSClass<JSSymbol>::StaticMethod("fontWeight", &JSSymbol::SetFontWeight, opt);
59     JSClass<JSSymbol>::StaticMethod("fontSize", &JSSymbol::SetFontSize, opt);
60     JSClass<JSSymbol>::StaticMethod("renderingStrategy", &JSSymbol::SetSymbolRenderingStrategy, opt);
61     JSClass<JSSymbol>::StaticMethod("fontColor", &JSSymbol::SetFontColor, opt);
62     JSClass<JSSymbol>::StaticMethod("effectStrategy", &JSSymbol::SetSymbolEffect, opt);
63     JSClass<JSSymbol>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
64     JSClass<JSSymbol>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
65     JSClass<JSSymbol>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
66     JSClass<JSSymbol>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
67     JSClass<JSSymbol>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
68     JSClass<JSSymbol>::StaticMethod("clip", &JSSymbol::JsClip);
69     JSClass<JSSymbol>::StaticMethod("symbolEffect", &JSSymbol::SetSymbolEffectOptions, opt);
70     JSClass<JSSymbol>::StaticMethod("minFontScale", &JSSymbol::SetMinFontScale);
71     JSClass<JSSymbol>::StaticMethod("maxFontScale", &JSSymbol::SetMaxFontScale);
72     JSClass<JSSymbol>::InheritAndBind<JSViewAbstract>(globalObj);
73 }
74 
Create(const JSCallbackInfo & info)75 void JSSymbol::Create(const JSCallbackInfo& info)
76 {
77     if (info[0]->IsUndefined()) {
78         SymbolModel::GetInstance()->Create(0);
79         return;
80     }
81     uint32_t symbolId;
82     RefPtr<ResourceObject> resourceObject;
83     ParseJsSymbolId(info[0], symbolId, resourceObject);
84     SymbolModel::GetInstance()->Create(symbolId);
85     std::vector<std::string> familyNames;
86     if (symbolId > SYSTEM_SYMBOL_BOUNDARY) {
87         ParseJsSymbolCustomFamilyNames(familyNames, info[0]);
88         SymbolModel::GetInstance()->SetFontFamilies(familyNames);
89         SymbolModel::GetInstance()->SetSymbolType(SymbolType::CUSTOM);
90     } else {
91         familyNames.push_back(DEFAULT_SYMBOL_FONTFAMILY);
92         SymbolModel::GetInstance()->SetFontFamilies(familyNames);
93         SymbolModel::GetInstance()->SetSymbolType(SymbolType::SYSTEM);
94     }
95 }
96 
SetFontSize(const JSCallbackInfo & info)97 void JSSymbol::SetFontSize(const JSCallbackInfo& info)
98 {
99     if (info.Length() < 1) {
100         return;
101     }
102     auto theme = GetTheme<TextTheme>();
103     CHECK_NULL_VOID(theme);
104     CalcDimension fontSize = theme->GetTextStyle().GetFontSize();
105     if (!ParseJsDimensionFpNG(info[0], fontSize, false)) {
106         fontSize = theme->GetTextStyle().GetFontSize();
107         SymbolModel::GetInstance()->SetFontSize(fontSize);
108         return;
109     }
110     if (fontSize.IsNegative()) {
111         fontSize = theme->GetTextStyle().GetFontSize();
112     }
113 
114     SymbolModel::GetInstance()->SetFontSize(fontSize);
115 }
116 
SetFontWeight(const std::string & value)117 void JSSymbol::SetFontWeight(const std::string& value)
118 {
119     SymbolModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(value));
120 }
121 
SetSymbolRenderingStrategy(const JSCallbackInfo & info)122 void JSSymbol::SetSymbolRenderingStrategy(const JSCallbackInfo& info)
123 {
124     uint32_t strategy = 0;
125     ParseJsInteger(info[0], strategy);
126     SymbolModel::GetInstance()->SetSymbolRenderingStrategy(strategy);
127 }
128 
SetFontColor(const JSCallbackInfo & info)129 void JSSymbol::SetFontColor(const JSCallbackInfo& info)
130 {
131     std::vector<Color> symbolColor;
132     if (!ParseJsSymbolColor(info[0], symbolColor)) {
133         return;
134     }
135     SymbolModel::GetInstance()->SetFontColor(symbolColor);
136 }
137 
SetSymbolEffect(const JSCallbackInfo & info)138 void JSSymbol::SetSymbolEffect(const JSCallbackInfo& info)
139 {
140     uint32_t strategy = 0;
141     ParseJsInteger(info[0], strategy);
142     SymbolModel::GetInstance()->SetSymbolEffect(strategy);
143 }
144 
JsClip(const JSCallbackInfo & info)145 void JSSymbol::JsClip(const JSCallbackInfo& info)
146 {
147     JSViewAbstract::JsClip(info);
148     if (info[0]->IsBoolean()) {
149         SymbolModel::GetInstance()->SetClipEdge();
150     }
151 }
152 
SetSymbolEffectOptions(const JSCallbackInfo & info)153 void JSSymbol::SetSymbolEffectOptions(const JSCallbackInfo& info)
154 {
155     if (info.Length() < 1 || !info[0]->IsObject()) {
156         return;
157     }
158 
159     auto symbolEffectObj = JSRef<JSObject>::Cast(info[0]);
160     NG::SymbolEffectOptions symbolEffectOptions;
161     parseSymbolEffect(symbolEffectObj, symbolEffectOptions);
162 
163     if (info.Length() > 1 && !info[1]->IsUndefined()) {
164         parseSymbolSwitch(info[1], symbolEffectOptions);
165     }
166 
167     SymbolModel::GetInstance()->SetSymbolEffectOptions(symbolEffectOptions);
168 }
169 
SetMinFontScale(const JSCallbackInfo & info)170 void JSSymbol::SetMinFontScale(const JSCallbackInfo& info)
171 {
172     double minFontScale;
173     if (info.Length() < 1 || !ParseJsDouble(info[0], minFontScale)) {
174         return;
175     }
176     if (LessOrEqual(minFontScale, 0.0f)) {
177         SymbolModel::GetInstance()->SetMinFontScale(0.0f);
178         return;
179     }
180     if (GreatOrEqual(minFontScale, 1.0f)) {
181         SymbolModel::GetInstance()->SetMinFontScale(1.0f);
182         return;
183     }
184     SymbolModel::GetInstance()->SetMinFontScale(static_cast<float>(minFontScale));
185 }
186 
SetMaxFontScale(const JSCallbackInfo & info)187 void JSSymbol::SetMaxFontScale(const JSCallbackInfo& info)
188 {
189     double maxFontScale;
190     if (info.Length() < 1 || !ParseJsDouble(info[0], maxFontScale)) {
191         return;
192     }
193     if (LessOrEqual(maxFontScale, 1.0f)) {
194         SymbolModel::GetInstance()->SetMaxFontScale(1.0f);
195         return;
196     }
197     SymbolModel::GetInstance()->SetMaxFontScale(static_cast<float>(maxFontScale));
198 }
199 
parseSymbolEffect(const JSRef<JSObject> symbolEffectObj,NG::SymbolEffectOptions & symbolEffectOptions)200 void JSSymbol::parseSymbolEffect(const JSRef<JSObject> symbolEffectObj, NG::SymbolEffectOptions& symbolEffectOptions)
201 {
202     auto typeParam = symbolEffectObj->GetProperty("type");
203     if (typeParam->IsString()) {
204         auto type = typeParam->ToString();
205         auto iter = SYMBOL_EFFECT_TYPE_MAP.find(type);
206         if (iter != SYMBOL_EFFECT_TYPE_MAP.end()) {
207             symbolEffectOptions.SetEffectType(iter->second);
208         }
209     }
210 
211     auto scopeTypeProperty = symbolEffectObj->GetProperty("scope");
212     if (scopeTypeProperty->IsNumber()) {
213         auto scopeTypeNum = scopeTypeProperty->ToNumber<uint32_t>();
214         if (scopeTypeNum >= static_cast<uint32_t>(ScopeType::LAYER) &&
215             scopeTypeNum <= static_cast<uint32_t>(ScopeType::WHOLE)) {
216             symbolEffectOptions.SetScopeType(static_cast<ScopeType>(scopeTypeNum));
217         }
218     }
219 
220     auto commonSubTypeProperty = symbolEffectObj->GetProperty("direction");
221     if (commonSubTypeProperty->IsNumber()) {
222         auto commonSubTypeNum = commonSubTypeProperty->ToNumber<uint32_t>();
223         if (commonSubTypeNum >= static_cast<uint32_t>(CommonSubType::DOWN) &&
224             commonSubTypeNum <= static_cast<uint32_t>(CommonSubType::UP)) {
225             symbolEffectOptions.SetCommonSubType(static_cast<CommonSubType>(commonSubTypeNum));
226         }
227     }
228 
229     auto fillStyleProperty = symbolEffectObj->GetProperty("fillStyle");
230     if (fillStyleProperty->IsNumber()) {
231         auto fillStyleNum = fillStyleProperty->ToNumber<uint32_t>();
232         if (fillStyleNum >= static_cast<uint32_t>(FillStyle::CUMULATIVE) &&
233             fillStyleNum <= static_cast<uint32_t>(FillStyle::ITERATIVE)) {
234             symbolEffectOptions.SetFillStyle(static_cast<FillStyle>(fillStyleNum));
235         }
236     }
237 }
238 
parseSymbolSwitch(const JSRef<JSVal> jsVal,NG::SymbolEffectOptions & symbolEffectOptions)239 void JSSymbol::parseSymbolSwitch(const JSRef<JSVal> jsVal, NG::SymbolEffectOptions& symbolEffectOptions)
240 {
241     if (jsVal->IsBoolean()) {
242         symbolEffectOptions.SetIsActive(jsVal->ToBoolean());
243     }
244 
245     if (jsVal->IsNumber()) {
246         int32_t triggerValue = -1;
247         ParseJsInteger(jsVal, triggerValue);
248         symbolEffectOptions.SetTriggerNum(triggerValue);
249     }
250 }
251 } // namespace OHOS::Ace::Framework