1 /*
2 * Copyright (c) 2024 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/engine/jsi/nativeModule/arkts_native_symbol_span_bridge.h"
16
17 #include "frameworks/base/geometry/calc_dimension.h"
18 #include "frameworks/base/geometry/dimension.h"
19 #include "frameworks/base/utils/string_utils.h"
20 #include "frameworks/base/utils/utils.h"
21 #include "frameworks/bridge/declarative_frontend/engine/js_types.h"
22 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
23 #include "frameworks/core/components_ng/pattern/text/span_node.h"
24
25 namespace OHOS::Ace::NG {
26 namespace {
27 constexpr int NUM_0 = 0;
28 constexpr int NUM_1 = 1;
29 constexpr int NUM_2 = 2;
30 constexpr int32_t SYSTEM_SYMBOL_BOUNDARY = 0XFFFFF;
31 } // namespace
32
SetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)33 ArkUINativeModuleValue SymbolSpanBridge::SetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
34 {
35 EcmaVM* vm = runtimeCallInfo->GetVM();
36 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
37 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
38 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
39
40 if (!secondArg->IsArray(vm)) {
41 return panda::JSValueRef::Undefined(vm);
42 }
43 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
44 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
45 auto array = Local<panda::ArrayRef>(secondArg);
46 auto length = array->Length(vm);
47
48 std::vector<ArkUI_Uint32> colorArray;
49 std::vector<Color> colorArr;
50 std::vector<std::pair<int32_t, RefPtr<ResourceObject>>> resObjArr;
51 for (uint32_t index = 0; index < length; index++) {
52 Local<JSValueRef> value = panda::ArrayRef::GetValueAt(vm, array, index);
53 Color color;
54 RefPtr<ResourceObject> resObj;
55 auto nodeInfo = ArkTSUtils::MakeNativeNodeInfo(nativeNode);
56 if (ArkTSUtils::ParseJsColorAlpha(vm, value, color, resObj, nodeInfo)) {
57 colorArray.emplace_back(color.GetValue());
58 colorArr.emplace_back(color);
59 } else {
60 colorArray.clear();
61 break;
62 }
63 if (SystemProperties::ConfigChangePerform() && resObj) {
64 std::pair<int32_t, RefPtr<ResourceObject>> pair(index, resObj);
65 resObjArr.push_back(pair);
66 }
67 }
68 if (static_cast<uint32_t>(length) == colorArray.size() && (static_cast<uint32_t>(length) & 1)) {
69 for (uint32_t i = 0; i < length; i++) {
70 colorArray.emplace_back(colorArray[i]);
71 }
72 }
73 GetArkUINodeModifiers()->getSymbolSpanModifier()->setSymbolSpanFontColor(
74 nativeNode, colorArray.data(), colorArray.size());
75 auto* uiNode = reinterpret_cast<UINode*>(nativeNode);
76 CHECK_NULL_RETURN(uiNode, panda::JSValueRef::Undefined(vm));
77 auto spanNode = AceType::DynamicCast<NG::SpanNode>(uiNode);
78 CHECK_NULL_RETURN(spanNode, panda::JSValueRef::Undefined(vm));
79 if (!resObjArr.empty()) {
80 spanNode->RegisterSymbolFontColorResource("symbolColor",
81 colorArr, resObjArr);
82 } else {
83 spanNode->UnregisterResource("symbolColor");
84 }
85 return panda::JSValueRef::Undefined(vm);
86 }
87
ResetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)88 ArkUINativeModuleValue SymbolSpanBridge::ResetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
89 {
90 EcmaVM* vm = runtimeCallInfo->GetVM();
91 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
92 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
93 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
94 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
95 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanFontColor(nativeNode);
96 return panda::JSValueRef::Undefined(vm);
97 }
98
SetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)99 ArkUINativeModuleValue SymbolSpanBridge::SetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
100 {
101 EcmaVM* vm = runtimeCallInfo->GetVM();
102 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
103 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
104 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
105 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
106 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
107 CalcDimension fontSize;
108 RefPtr<ResourceObject> resObj;
109 if (!ArkTSUtils::ParseJsDimensionFpNG(vm, secondArg, fontSize, resObj, false)) {
110 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanFontSize(nativeNode);
111 } else {
112 GetArkUINodeModifiers()->getSymbolSpanModifier()->setSymbolSpanFontSize(
113 nativeNode, fontSize.Value(), static_cast<int>(fontSize.Unit()), AceType::RawPtr(resObj));
114 }
115 return panda::JSValueRef::Undefined(vm);
116 }
117
ResetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)118 ArkUINativeModuleValue SymbolSpanBridge::ResetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
119 {
120 EcmaVM* vm = runtimeCallInfo->GetVM();
121 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
122 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
123 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
124 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
125 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanFontSize(nativeNode);
126 return panda::JSValueRef::Undefined(vm);
127 }
128
SetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)129 ArkUINativeModuleValue SymbolSpanBridge::SetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
130 {
131 EcmaVM* vm = runtimeCallInfo->GetVM();
132 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
133 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
134 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
135 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
136 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
137 if (secondArg->IsString(vm)) {
138 std::string weight = secondArg->ToString(vm)->ToString(vm);
139 GetArkUINodeModifiers()->getSymbolSpanModifier()->setSymbolSpanFontWeightStr(
140 nativeNode, weight.c_str());
141 } else {
142 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanFontWeight(nativeNode);
143 }
144 return panda::JSValueRef::Undefined(vm);
145 }
146
ResetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)147 ArkUINativeModuleValue SymbolSpanBridge::ResetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
148 {
149 EcmaVM* vm = runtimeCallInfo->GetVM();
150 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
151 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
152 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
153 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
154 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanFontWeight(nativeNode);
155 return panda::JSValueRef::Undefined(vm);
156 }
157
SetRenderingStrategy(ArkUIRuntimeCallInfo * runtimeCallInfo)158 ArkUINativeModuleValue SymbolSpanBridge::SetRenderingStrategy(ArkUIRuntimeCallInfo* runtimeCallInfo)
159 {
160 EcmaVM* vm = runtimeCallInfo->GetVM();
161 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
162 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
163 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
164 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
165 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
166 if (secondArg->IsNumber() && secondArg->Int32Value(vm) >= NUM_0 &&
167 secondArg->Int32Value(vm) <= NUM_2) {
168 GetArkUINodeModifiers()->getSymbolSpanModifier()->setSymbolSpanRenderingStrategy(
169 nativeNode, secondArg->Int32Value(vm));
170 } else {
171 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanRenderingStrategy(nativeNode);
172 }
173 return panda::JSValueRef::Undefined(vm);
174 }
175
ResetRenderingStrategy(ArkUIRuntimeCallInfo * runtimeCallInfo)176 ArkUINativeModuleValue SymbolSpanBridge::ResetRenderingStrategy(ArkUIRuntimeCallInfo* runtimeCallInfo)
177 {
178 EcmaVM* vm = runtimeCallInfo->GetVM();
179 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
180 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
181 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
182 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
183 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanRenderingStrategy(nativeNode);
184 return panda::JSValueRef::Undefined(vm);
185 }
186
SetEffectStrategy(ArkUIRuntimeCallInfo * runtimeCallInfo)187 ArkUINativeModuleValue SymbolSpanBridge::SetEffectStrategy(ArkUIRuntimeCallInfo* runtimeCallInfo)
188 {
189 EcmaVM* vm = runtimeCallInfo->GetVM();
190 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
191 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
192 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
193 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
194 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
195 if (secondArg->IsNumber() && secondArg->Int32Value(vm) >= NUM_0 &&
196 secondArg->Int32Value(vm) <= NUM_2) {
197 GetArkUINodeModifiers()->getSymbolSpanModifier()->setSymbolSpanEffectStrategy(
198 nativeNode, secondArg->Int32Value(vm));
199 } else {
200 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanEffectStrategy(nativeNode);
201 }
202 return panda::JSValueRef::Undefined(vm);
203 }
204
ResetEffectStrategy(ArkUIRuntimeCallInfo * runtimeCallInfo)205 ArkUINativeModuleValue SymbolSpanBridge::ResetEffectStrategy(ArkUIRuntimeCallInfo* runtimeCallInfo)
206 {
207 EcmaVM* vm = runtimeCallInfo->GetVM();
208 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
209 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
210 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
211 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
212 GetArkUINodeModifiers()->getSymbolSpanModifier()->resetSymbolSpanEffectStrategy(nativeNode);
213 return panda::JSValueRef::Undefined(vm);
214 }
215
SetId(ArkUIRuntimeCallInfo * runtimeCallInfo)216 ArkUINativeModuleValue SymbolSpanBridge::SetId(ArkUIRuntimeCallInfo* runtimeCallInfo)
217 {
218 EcmaVM* vm = runtimeCallInfo->GetVM();
219 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
220 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
221 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
222 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
223 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
224 uint32_t content = 0;
225 if (ArkTSUtils::ParseJsSymbolId(vm, secondArg, content)) {
226 if (content > SYSTEM_SYMBOL_BOUNDARY) {
227 std::string symbolFontFamilyName;
228 ArkTSUtils::ParseJsSymbolFontFamilyName(vm, secondArg, symbolFontFamilyName);
229 GetArkUINodeModifiers()->getSymbolSpanModifier()->setCustomSymbolSpanId(nativeNode, content,
230 symbolFontFamilyName.c_str());
231 } else {
232 GetArkUINodeModifiers()->getSymbolSpanModifier()->setSymbolSpanId(nativeNode, content);
233 }
234 }
235 return panda::JSValueRef::Undefined(vm);
236 }
237
238 } // namespace OHOS::Ace::NG
239