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
16 #include "frameworks/bridge/declarative_frontend/style_string/js_span_object.h"
17
18 #include <numeric>
19 #include <string>
20
21 #include "canvas_napi/js_canvas.h"
22
23 #include "base/geometry/calc_dimension.h"
24 #include "base/geometry/dimension.h"
25 #include "base/log/ace_scoring_log.h"
26 #include "base/memory/ace_type.h"
27 #include "bridge/common/utils/engine_helper.h"
28 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
29 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.h"
30 #include "bridge/declarative_frontend/engine/js_converter.h"
31 #include "bridge/declarative_frontend/engine/js_types.h"
32 #include "bridge/declarative_frontend/jsview/js_richeditor.h"
33 #include "bridge/declarative_frontend/jsview/js_utils.h"
34 #include "core/components/common/layout/constants.h"
35 #include "core/components/common/properties/text_style.h"
36 #include "core/components/text/text_theme.h"
37 #include "core/components/text_field/textfield_theme.h"
38 #include "core/components_ng/pattern/text/span/span_object.h"
39 #include "core/components_ng/pattern/text/span/span_string.h"
40 #include "core/components_ng/render/paragraph.h"
41 #include "frameworks/bridge/common/utils/utils.h"
42 #include "frameworks/bridge/declarative_frontend/jsview/js_container_span.h"
43 #include "frameworks/bridge/declarative_frontend/jsview/js_image.h"
44 #include "frameworks/bridge/declarative_frontend/jsview/js_container_span.h"
45 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
46
47 namespace OHOS::Ace::Framework {
48 namespace {
49 const std::vector<TextAlign> TEXT_ALIGNS = { TextAlign::START, TextAlign::CENTER, TextAlign::END, TextAlign::JUSTIFY };
50 const std::vector<TextVerticalAlign> TEXT_VERTICAL_ALIGNS = {
51 TextVerticalAlign::BASELINE, TextVerticalAlign::BOTTOM, TextVerticalAlign::CENTER, TextVerticalAlign::TOP };
52 const std::vector<TextOverflow> TEXT_OVERFLOWS = { TextOverflow::NONE, TextOverflow::CLIP, TextOverflow::ELLIPSIS,
53 TextOverflow::MARQUEE };
54 const int32_t WORD_BREAK_TYPES_DEFAULT = 2;
55 const std::vector<float> DEFAULT_COLORFILTER_MATRIX = {
56 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
57 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
58 };
59 } // namespace
60
ParseLengthMetrics(const JSRef<JSObject> & obj,bool withoutPercent=true)61 CalcDimension ParseLengthMetrics(const JSRef<JSObject>& obj, bool withoutPercent = true)
62 {
63 auto value = 0.0;
64 auto valueObj = obj->GetProperty("value");
65 if (!valueObj->IsNull() && valueObj->IsNumber()) {
66 value = valueObj->ToNumber<float>();
67 }
68 auto unit = DimensionUnit::VP;
69 auto unitObj = obj->GetProperty("unit");
70 if (!unitObj->IsNull() && unitObj->IsNumber()) {
71 unit = static_cast<DimensionUnit>(unitObj->ToNumber<int32_t>());
72 }
73 CalcDimension size = CalcDimension(value, unit);
74 if (withoutPercent && unit == DimensionUnit::PERCENT) {
75 size = CalcDimension(0, DimensionUnit::VP);
76 }
77 return size;
78 }
79
JSBind(BindingTarget globalObj)80 void JSFontSpan::JSBind(BindingTarget globalObj)
81 {
82 JSClass<JSFontSpan>::Declare("TextStyle");
83 JSClass<JSFontSpan>::CustomProperty("fontColor", &JSFontSpan::GetFontColor, &JSFontSpan::SetFontColor);
84 JSClass<JSFontSpan>::CustomProperty("fontSize", &JSFontSpan::GetFontSize, &JSFontSpan::SetFontSize);
85 JSClass<JSFontSpan>::CustomProperty("fontStyle", &JSFontSpan::GetFontStyle, &JSFontSpan::SetFontStyle);
86 JSClass<JSFontSpan>::CustomProperty("fontWeight", &JSFontSpan::GetFontWeight, &JSFontSpan::SetFontWeight);
87 JSClass<JSFontSpan>::CustomProperty("fontFamily", &JSFontSpan::GetFontFamily, &JSFontSpan::SetFontFamily);
88 JSClass<JSFontSpan>::CustomProperty("strokeWidth", &JSFontSpan::GetStrokeWidth, &JSFontSpan::SetStrokeWidth);
89 JSClass<JSFontSpan>::CustomProperty("strokeColor", &JSFontSpan::GetStrokeColor, &JSFontSpan::SetStrokeColor);
90 JSClass<JSFontSpan>::CustomProperty("superscript", &JSFontSpan::GetSuperscript, &JSFontSpan::SetSuperscript);
91 JSClass<JSFontSpan>::Bind(globalObj, JSFontSpan::Constructor, JSFontSpan::Destructor);
92 }
93
Constructor(const JSCallbackInfo & args)94 void JSFontSpan::Constructor(const JSCallbackInfo& args)
95 {
96 auto fontSpan = Referenced::MakeRefPtr<JSFontSpan>();
97 fontSpan->IncRefCount();
98
99 RefPtr<FontSpan> span;
100 if (args.Length() <= 0) {
101 Font font;
102 span = AceType::MakeRefPtr<FontSpan>(font);
103 } else {
104 if (!args[0]->IsObject()) {
105 return;
106 }
107 span = JSFontSpan::ParseJsFontSpan(JSRef<JSObject>::Cast(args[0]));
108 }
109 fontSpan->fontSpan_ = span;
110 args.SetReturnValue(Referenced::RawPtr(fontSpan));
111 }
112
Destructor(JSFontSpan * fontSpan)113 void JSFontSpan::Destructor(JSFontSpan* fontSpan)
114 {
115 if (fontSpan != nullptr) {
116 fontSpan->DecRefCount();
117 }
118 }
119
ParseJsFontSpan(const JSRef<JSObject> & obj)120 RefPtr<FontSpan> JSFontSpan::ParseJsFontSpan(const JSRef<JSObject>& obj)
121 {
122 Font font;
123 ParseJsFontColor(obj, font);
124 ParseJsFontSize(obj, font);
125 ParseJsFontWeight(obj, font);
126 ParseJsFontFamily(obj, font);
127 ParseJsFontStyle(obj, font);
128 ParseJsStrokeWidth(obj, font);
129 ParseJsStrokeColor(obj, font);
130 ParseJsSuperscript(obj, font);
131 return AceType::MakeRefPtr<FontSpan>(font);
132 }
133
ParseJsFontColor(const JSRef<JSObject> & obj,Font & font)134 void JSFontSpan::ParseJsFontColor(const JSRef<JSObject>& obj, Font& font)
135 {
136 if (obj->HasProperty("fontColor")) {
137 JSRef<JSVal> colorObj = JSRef<JSVal>::Cast(obj->GetProperty("fontColor"));
138 Color color;
139 if (!colorObj->IsNull() && !JSViewAbstract::ParseJsColor(colorObj, color)) {
140 auto context = PipelineBase::GetCurrentContextSafely();
141 CHECK_NULL_VOID(context);
142 auto theme = context->GetTheme<TextTheme>();
143 CHECK_NULL_VOID(theme);
144 color = theme->GetTextStyle().GetTextColor();
145 }
146 font.fontColor = color;
147 }
148 }
149
ParseJsFontSize(const JSRef<JSObject> & obj,Font & font)150 void JSFontSpan::ParseJsFontSize(const JSRef<JSObject>& obj, Font& font)
151 {
152 if (obj->HasProperty("fontSize")) {
153 auto context = PipelineBase::GetCurrentContextSafely();
154 CHECK_NULL_VOID(context);
155 auto theme = context->GetTheme<TextTheme>();
156 CHECK_NULL_VOID(theme);
157 auto fontSize = obj->GetProperty("fontSize");
158 CalcDimension size = theme->GetTextStyle().GetFontSize();
159 if (!fontSize->IsNull() && fontSize->IsObject()) {
160 auto sizeTmp = ParseLengthMetrics(fontSize, false);
161 if (sizeTmp.Value() >= 0 && sizeTmp.Unit() != DimensionUnit::PERCENT) {
162 size = sizeTmp;
163 }
164 }
165 font.fontSize = size;
166 }
167 }
168
ParseJsFontWeight(const JSRef<JSObject> & obj,Font & font)169 void JSFontSpan::ParseJsFontWeight(const JSRef<JSObject>& obj, Font& font)
170 {
171 if (obj->HasProperty("fontWeight")) {
172 auto fontWeight = obj->GetProperty("fontWeight");
173 std::string weight = "";
174 if (fontWeight->IsNumber()) {
175 weight = std::to_string(fontWeight->ToNumber<int32_t>());
176 } else {
177 JSViewAbstract::ParseJsString(fontWeight, weight);
178 }
179 if (weight != "") {
180 font.fontWeight = ConvertStrToFontWeight(weight);
181 } else {
182 auto context = PipelineBase::GetCurrentContextSafely();
183 CHECK_NULL_VOID(context);
184 auto theme = context->GetTheme<TextTheme>();
185 CHECK_NULL_VOID(theme);
186 font.fontWeight = theme->GetTextStyle().GetFontWeight();
187 }
188 }
189 }
190
ParseJsFontFamily(const JSRef<JSObject> & obj,Font & font)191 void JSFontSpan::ParseJsFontFamily(const JSRef<JSObject>& obj, Font& font)
192 {
193 if (obj->HasProperty("fontFamily")) {
194 auto fontFamily = obj->GetProperty("fontFamily");
195 std::vector<std::string> fontFamilies;
196 if (JSViewAbstract::ParseJsFontFamilies(fontFamily, fontFamilies)) {
197 font.fontFamiliesNG = fontFamilies;
198 } else {
199 auto context = PipelineBase::GetCurrentContextSafely();
200 CHECK_NULL_VOID(context);
201 auto theme = context->GetTheme<TextTheme>();
202 CHECK_NULL_VOID(theme);
203 font.fontFamiliesNG = theme->GetTextStyle().GetFontFamilies();
204 }
205 }
206 }
207
ParseJsFontStyle(const JSRef<JSObject> & obj,Font & font)208 void JSFontSpan::ParseJsFontStyle(const JSRef<JSObject>& obj, Font& font)
209 {
210 if (obj->HasProperty("fontStyle")) {
211 auto style = obj->GetProperty("fontStyle");
212 OHOS::Ace::FontStyle fontStyle = FontStyle::NORMAL;
213 if (!style->IsNull() && style->IsNumber()) {
214 auto value = style->ToNumber<int32_t>();
215 if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
216 fontStyle = static_cast<FontStyle>(value);
217 }
218 }
219 font.fontStyle = fontStyle;
220 }
221 }
222
ParseJsStrokeWidth(const JSRef<JSObject> & obj,Font & font)223 void JSFontSpan::ParseJsStrokeWidth(const JSRef<JSObject>& obj, Font& font)
224 {
225 auto context = PipelineBase::GetCurrentContextSafelyWithCheck();
226 CHECK_NULL_VOID(context);
227 auto theme = context->GetTheme<TextTheme>();
228 CHECK_NULL_VOID(theme);
229 CalcDimension width = theme->GetTextStyle().GetStrokeWidth();
230 if (obj->HasProperty("strokeWidth")) {
231 auto strokeWidth = obj->GetProperty("strokeWidth");
232 if (!strokeWidth->IsNull() && strokeWidth->IsObject()) {
233 auto strokeWidthTmp = ParseLengthMetrics(strokeWidth, false);
234 if (strokeWidthTmp.Unit() != DimensionUnit::PERCENT) {
235 width = strokeWidthTmp;
236 }
237 }
238 }
239 font.strokeWidth = width;
240 }
241
GetStrokeColorFallback(const JSRef<JSObject> & obj,const RefPtr<TextTheme> & theme,Color & color)242 void JSFontSpan::GetStrokeColorFallback(const JSRef<JSObject>& obj, const RefPtr<TextTheme>& theme, Color& color)
243 {
244 if (obj->HasProperty("fontColor")) {
245 JSRef<JSVal> colorObj = JSRef<JSVal>::Cast(obj->GetProperty("fontColor"));
246 if (!colorObj->IsNull() && !JSViewAbstract::ParseJsColor(colorObj, color)) {
247 color = theme->GetTextStyle().GetTextColor();
248 }
249 } else {
250 color = theme->GetTextStyle().GetTextColor();
251 }
252 }
253
ParseJsStrokeColor(const JSRef<JSObject> & obj,Font & font)254 void JSFontSpan::ParseJsStrokeColor(const JSRef<JSObject>& obj, Font& font)
255 {
256 Color color;
257 auto context = PipelineBase::GetCurrentContextSafelyWithCheck();
258 CHECK_NULL_VOID(context);
259 auto theme = context->GetTheme<TextTheme>();
260 CHECK_NULL_VOID(theme);
261 if (obj->HasProperty("strokeColor")) {
262 JSRef<JSVal> strokeColorObj = JSRef<JSVal>::Cast(obj->GetProperty("strokeColor"));
263 if (!strokeColorObj->IsNull() && !JSViewAbstract::ParseJsColor(strokeColorObj, color)) {
264 GetStrokeColorFallback(obj, theme, color);
265 }
266 font.strokeColor = color;
267 } else if (obj->HasProperty("fontColor")) {
268 JSRef<JSVal> colorObj = JSRef<JSVal>::Cast(obj->GetProperty("fontColor"));
269 if (!colorObj->IsNull() && !JSViewAbstract::ParseJsColor(colorObj, color)) {
270 color = theme->GetTextStyle().GetTextColor();
271 }
272 font.strokeColor = color;
273 } else {
274 font.strokeColor = theme->GetTextStyle().GetTextColor();
275 }
276 }
277
ParseJsSuperscript(const JSRef<JSObject> & obj,Font & font)278 void JSFontSpan::ParseJsSuperscript(const JSRef<JSObject>& obj, Font& font)
279 {
280 if (obj->HasProperty("superscript")) {
281 auto style = obj->GetProperty("superscript");
282 OHOS::Ace::SuperscriptStyle superscriptStyle = SuperscriptStyle::NORMAL;
283 if (!style->IsNull() && style->IsNumber()) {
284 auto value = style->ToNumber<int32_t>();
285 if (value >= 0 && value < static_cast<int32_t>(SuperscriptStyle::NONE)) {
286 superscriptStyle = static_cast<SuperscriptStyle>(value);
287 }
288 }
289 font.superscript = superscriptStyle;
290 } else {
291 font.superscript = SuperscriptStyle::NORMAL;
292 }
293 }
294
GetFontColor(const JSCallbackInfo & info)295 void JSFontSpan::GetFontColor(const JSCallbackInfo& info)
296 {
297 CHECK_NULL_VOID(fontSpan_);
298 if (!fontSpan_->GetFont().fontColor.has_value()) {
299 return;
300 }
301 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(fontSpan_->GetFont().fontColor.value().ColorToString())));
302 info.SetReturnValue(ret);
303 }
304
SetFontColor(const JSCallbackInfo & info)305 void JSFontSpan::SetFontColor(const JSCallbackInfo& info) {}
306
GetFontSize(const JSCallbackInfo & info)307 void JSFontSpan::GetFontSize(const JSCallbackInfo& info)
308 {
309 CHECK_NULL_VOID(fontSpan_);
310 if (!fontSpan_->GetFont().fontSize.has_value()) {
311 return;
312 }
313 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(fontSpan_->GetFont().fontSize.value().ConvertToVp())));
314 info.SetReturnValue(ret);
315 }
316
SetFontSize(const JSCallbackInfo & info)317 void JSFontSpan::SetFontSize(const JSCallbackInfo& info) {}
318
GetFontStyle(const JSCallbackInfo & info)319 void JSFontSpan::GetFontStyle(const JSCallbackInfo& info)
320 {
321 CHECK_NULL_VOID(fontSpan_);
322 if (!fontSpan_->GetFont().fontStyle.has_value()) {
323 return;
324 }
325 auto ret = JSRef<JSVal>::Make(
326 JSVal(ToJSValue(std::to_string(static_cast<int32_t>(fontSpan_->GetFont().fontStyle.value())))));
327 info.SetReturnValue(ret);
328 }
329
SetFontStyle(const JSCallbackInfo & info)330 void JSFontSpan::SetFontStyle(const JSCallbackInfo& info) {}
331
GetFontWeight(const JSCallbackInfo & info)332 void JSFontSpan::GetFontWeight(const JSCallbackInfo& info)
333 {
334 CHECK_NULL_VOID(fontSpan_);
335 if (!fontSpan_->GetFont().fontWeight.has_value()) {
336 return;
337 }
338 auto ret = JSRef<JSVal>::Make(
339 JSVal(ToJSValue(std::to_string(static_cast<int32_t>(fontSpan_->GetFont().fontWeight.value())))));
340 info.SetReturnValue(ret);
341 }
342
SetFontWeight(const JSCallbackInfo & info)343 void JSFontSpan::SetFontWeight(const JSCallbackInfo& info) {}
344
GetFontFamily(const JSCallbackInfo & info)345 void JSFontSpan::GetFontFamily(const JSCallbackInfo& info)
346 {
347 CHECK_NULL_VOID(fontSpan_);
348 if (!fontSpan_->GetFont().fontFamiliesNG.has_value()) {
349 return;
350 }
351 auto fontFamilies = fontSpan_->GetFont().fontFamiliesNG.value();
352 auto retStr = std::accumulate(fontFamilies.begin(), fontFamilies.end(), std::string());
353 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(retStr)));
354 info.SetReturnValue(ret);
355 }
356
SetFontFamily(const JSCallbackInfo & info)357 void JSFontSpan::SetFontFamily(const JSCallbackInfo& info) {}
358
GetStrokeWidth(const JSCallbackInfo & info)359 void JSFontSpan::GetStrokeWidth(const JSCallbackInfo& info)
360 {
361 CHECK_NULL_VOID(fontSpan_);
362 if (!fontSpan_->GetFont().strokeWidth.has_value()) {
363 return;
364 }
365 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(fontSpan_->GetFont().strokeWidth.value().ConvertToVp())));
366 info.SetReturnValue(ret);
367 }
368
SetStrokeWidth(const JSCallbackInfo & info)369 void JSFontSpan::SetStrokeWidth(const JSCallbackInfo& info) {}
370
GetStrokeColor(const JSCallbackInfo & info)371 void JSFontSpan::GetStrokeColor(const JSCallbackInfo& info)
372 {
373 CHECK_NULL_VOID(fontSpan_);
374 if (!fontSpan_->GetFont().strokeColor.has_value()) {
375 return;
376 }
377 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(fontSpan_->GetFont().strokeColor.value().ColorToString())));
378 info.SetReturnValue(ret);
379 }
380
SetStrokeColor(const JSCallbackInfo & info)381 void JSFontSpan::SetStrokeColor(const JSCallbackInfo& info) {}
382
GetSuperscript(const JSCallbackInfo & info)383 void JSFontSpan::GetSuperscript(const JSCallbackInfo& info)
384 {
385 CHECK_NULL_VOID(fontSpan_);
386 if (!fontSpan_->GetFont().superscript.has_value()) {
387 return;
388 }
389 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(static_cast<int32_t>(fontSpan_->GetFont().superscript.value()))));
390 info.SetReturnValue(ret);
391 }
392
SetSuperscript(const JSCallbackInfo & info)393 void JSFontSpan::SetSuperscript(const JSCallbackInfo& info) {}
394
GetFontSpan()395 const RefPtr<FontSpan>& JSFontSpan::GetFontSpan()
396 {
397 return fontSpan_;
398 }
399
SetFontSpan(const RefPtr<FontSpan> & fontSpan)400 void JSFontSpan::SetFontSpan(const RefPtr<FontSpan>& fontSpan)
401 {
402 fontSpan_ = fontSpan;
403 }
404
JSBind(BindingTarget globalObj)405 void JSDecorationSpan::JSBind(BindingTarget globalObj)
406 {
407 JSClass<JSDecorationSpan>::Declare("DecorationStyle");
408 JSClass<JSDecorationSpan>::CustomProperty(
409 "type", &JSDecorationSpan::GetTextDecorationType, &JSDecorationSpan::SetTextDecorationType);
410 JSClass<JSDecorationSpan>::CustomProperty(
411 "color", &JSDecorationSpan::GetTextDecorationColor, &JSDecorationSpan::SetTextDecorationColor);
412 JSClass<JSDecorationSpan>::CustomProperty(
413 "style", &JSDecorationSpan::GetTextDecorationStyle, &JSDecorationSpan::SetTextDecorationStyle);
414 JSClass<JSDecorationSpan>::CustomProperty(
415 "thicknessScale", &JSDecorationSpan::GetLineThicknessScale, &JSDecorationSpan::SetLineThicknessScale);
416 JSClass<JSDecorationSpan>::CustomProperty(
417 "options", &JSDecorationSpan::GetTextDecorationOptions, &JSDecorationSpan::SetTextDecorationOptions);
418 JSClass<JSDecorationSpan>::Bind(globalObj, JSDecorationSpan::Constructor, JSDecorationSpan::Destructor);
419 }
420
Constructor(const JSCallbackInfo & args)421 void JSDecorationSpan::Constructor(const JSCallbackInfo& args)
422 {
423 auto decorationSpan = Referenced::MakeRefPtr<JSDecorationSpan>();
424 decorationSpan->IncRefCount();
425
426 RefPtr<DecorationSpan> span = JSDecorationSpan::ParseJsDecorationSpan(args);
427 decorationSpan->decorationSpan_ = span;
428 args.SetReturnValue(Referenced::RawPtr(decorationSpan));
429 }
430
Destructor(JSDecorationSpan * decorationSpan)431 void JSDecorationSpan::Destructor(JSDecorationSpan* decorationSpan)
432 {
433 if (decorationSpan != nullptr) {
434 decorationSpan->DecRefCount();
435 }
436 }
437
ParseJsDecorationSpan(const JSCallbackInfo & args)438 RefPtr<DecorationSpan> JSDecorationSpan::ParseJsDecorationSpan(const JSCallbackInfo& args)
439 {
440 if (args.Length() <= 0 || !args[0]->IsObject()) {
441 return AceType::MakeRefPtr<DecorationSpan>();
442 }
443 auto obj = JSRef<JSObject>::Cast(args[0]);
444 std::optional<Color> colorOption;
445 Color color;
446 JSRef<JSVal> colorObj = JSRef<JSVal>::Cast(obj->GetProperty("color"));
447 if (!colorObj->IsNull() && JSViewAbstract::ParseJsColor(colorObj, color)) {
448 colorOption = color;
449 }
450 std::optional<TextDecorationStyle> styleOption;
451 JSRef<JSVal> styleObj = JSRef<JSVal>::Cast(obj->GetProperty("style"));
452 if (!styleObj->IsNull() && styleObj->IsNumber()) {
453 styleOption = static_cast<TextDecorationStyle>(styleObj->ToNumber<int32_t>());
454 }
455 TextDecoration type = TextDecoration::NONE;
456 JSRef<JSVal> typeObj = JSRef<JSVal>::Cast(obj->GetProperty("type"));
457 if (!typeObj->IsNull() && typeObj->IsNumber()) {
458 type = static_cast<TextDecoration>(typeObj->ToNumber<int32_t>());
459 }
460 std::optional<float> lineThicknessScale;
461 JSRef<JSVal> thicknessScaleValue = obj->GetProperty("thicknessScale");
462 if (thicknessScaleValue->IsNumber()) {
463 lineThicknessScale = thicknessScaleValue->ToNumber<float>();
464 lineThicknessScale = LessNotEqual(lineThicknessScale.value_or(-1.0f), 0) ? 1.0f : lineThicknessScale;
465 }
466 std::optional<TextDecorationOptions> options;
467 if (args.Length() > 1 && args[1]->IsObject()) {
468 options = JSDecorationSpan::ParseJsDecorationOptions(JSRef<JSObject>::Cast(args[1]));
469 }
470 return AceType::MakeRefPtr<DecorationSpan>(
471 std::vector<TextDecoration>({type}), colorOption, styleOption, lineThicknessScale, options);
472 }
473
ParseJsDecorationOptions(const JSRef<JSObject> & obj)474 TextDecorationOptions JSDecorationSpan::ParseJsDecorationOptions(const JSRef<JSObject>& obj)
475 {
476 TextDecorationOptions options;
477 JSRef<JSVal> enableMultiTypeObj = JSRef<JSVal>::Cast(obj->GetProperty("enableMultiType"));
478 if (!enableMultiTypeObj->IsNull() && enableMultiTypeObj->IsBoolean()) {
479 options.enableMultiType = enableMultiTypeObj->ToBoolean();
480 }
481 return options;
482 }
483
GetTextDecorationType(const JSCallbackInfo & info)484 void JSDecorationSpan::GetTextDecorationType(const JSCallbackInfo& info)
485 {
486 CHECK_NULL_VOID(decorationSpan_);
487 auto ret = JSRef<JSVal>::Make(
488 JSVal(ToJSValue(static_cast<int32_t>(decorationSpan_->GetTextDecorationFirst()))));
489 info.SetReturnValue(ret);
490 }
491
SetTextDecorationType(const JSCallbackInfo & info)492 void JSDecorationSpan::SetTextDecorationType(const JSCallbackInfo& info) {}
493
GetTextDecorationColor(const JSCallbackInfo & info)494 void JSDecorationSpan::GetTextDecorationColor(const JSCallbackInfo& info)
495 {
496 CHECK_NULL_VOID(decorationSpan_);
497 if (!decorationSpan_->GetColor().has_value()) {
498 return;
499 }
500 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(decorationSpan_->GetColor()->ColorToString())));
501 info.SetReturnValue(ret);
502 }
503
SetTextDecorationColor(const JSCallbackInfo & info)504 void JSDecorationSpan::SetTextDecorationColor(const JSCallbackInfo& info) {}
505
GetTextDecorationStyle(const JSCallbackInfo & info)506 void JSDecorationSpan::GetTextDecorationStyle(const JSCallbackInfo& info)
507 {
508 CHECK_NULL_VOID(decorationSpan_);
509 if (!decorationSpan_->GetTextDecorationStyle().has_value()) {
510 return;
511 }
512 auto ret =
513 JSRef<JSVal>::Make(JSVal(ToJSValue(static_cast<int32_t>(decorationSpan_->GetTextDecorationStyle().value()))));
514 info.SetReturnValue(ret);
515 }
516
SetTextDecorationStyle(const JSCallbackInfo & info)517 void JSDecorationSpan::SetTextDecorationStyle(const JSCallbackInfo& info) {}
518
GetLineThicknessScale(const JSCallbackInfo & info)519 void JSDecorationSpan::GetLineThicknessScale(const JSCallbackInfo& info)
520 {
521 CHECK_NULL_VOID(decorationSpan_);
522 if (!decorationSpan_->GetLineThicknessScale().has_value()) {
523 return;
524 }
525 auto ret =
526 JSRef<JSVal>::Make(JSVal(ToJSValue(decorationSpan_->GetLineThicknessScale().value())));
527 info.SetReturnValue(ret);
528 }
529
SetLineThicknessScale(const JSCallbackInfo & info)530 void JSDecorationSpan::SetLineThicknessScale(const JSCallbackInfo& info) {}
531
GetTextDecorationOptions(const JSCallbackInfo & info)532 void JSDecorationSpan::GetTextDecorationOptions(const JSCallbackInfo& info)
533 {
534 CHECK_NULL_VOID(decorationSpan_);
535 if (!decorationSpan_->GetTextDecorationOptions().has_value()) {
536 return;
537 }
538 auto options = decorationSpan_->GetTextDecorationOptions().value();
539 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
540 objectTemplate->SetInternalFieldCount(1);
541 JSRef<JSObject> retObj = objectTemplate->NewInstance();
542 if (options.enableMultiType.has_value()) {
543 bool enableMultiType = options.enableMultiType.value_or(false);
544 retObj->SetProperty<bool>("enableMultiType", enableMultiType);
545 }
546 info.SetReturnValue(retObj);
547 }
548
SetTextDecorationOptions(const JSCallbackInfo & info)549 void JSDecorationSpan::SetTextDecorationOptions(const JSCallbackInfo& info) {}
550
GetDecorationSpan()551 RefPtr<DecorationSpan>& JSDecorationSpan::GetDecorationSpan()
552 {
553 return decorationSpan_;
554 }
555
SetDecorationSpan(const RefPtr<DecorationSpan> & decorationSpan)556 void JSDecorationSpan::SetDecorationSpan(const RefPtr<DecorationSpan>& decorationSpan)
557 {
558 decorationSpan_ = decorationSpan;
559 }
560
JSBind(BindingTarget globalObj)561 void JSBaselineOffsetSpan::JSBind(BindingTarget globalObj)
562 {
563 JSClass<JSBaselineOffsetSpan>::Declare("BaselineOffsetStyle");
564 JSClass<JSBaselineOffsetSpan>::CustomProperty(
565 "baselineOffset", &JSBaselineOffsetSpan::GetBaselineOffset, &JSBaselineOffsetSpan::SetBaselineOffset);
566 JSClass<JSBaselineOffsetSpan>::Bind(globalObj, JSBaselineOffsetSpan::Constructor, JSBaselineOffsetSpan::Destructor);
567 }
568
Constructor(const JSCallbackInfo & args)569 void JSBaselineOffsetSpan::Constructor(const JSCallbackInfo& args)
570 {
571 auto baselineOffsetSpan = Referenced::MakeRefPtr<JSBaselineOffsetSpan>();
572 baselineOffsetSpan->IncRefCount();
573 RefPtr<BaselineOffsetSpan> span;
574 if (args.Length() <= 0 || !args[0]->IsObject()) {
575 span = AceType::MakeRefPtr<BaselineOffsetSpan>();
576 } else {
577 span = JSBaselineOffsetSpan::ParseJSBaselineOffsetSpan(JSRef<JSObject>::Cast(args[0]));
578 }
579 baselineOffsetSpan->baselineOffsetSpan_ = span;
580 args.SetReturnValue(Referenced::RawPtr(baselineOffsetSpan));
581 }
582
Destructor(JSBaselineOffsetSpan * baselineOffsetSpan)583 void JSBaselineOffsetSpan::Destructor(JSBaselineOffsetSpan* baselineOffsetSpan)
584 {
585 if (baselineOffsetSpan != nullptr) {
586 baselineOffsetSpan->DecRefCount();
587 }
588 }
589
ParseJSBaselineOffsetSpan(const JSRef<JSObject> & obj)590 RefPtr<BaselineOffsetSpan> JSBaselineOffsetSpan::ParseJSBaselineOffsetSpan(const JSRef<JSObject>& obj)
591 {
592 if (obj->IsUndefined()) {
593 return AceType::MakeRefPtr<BaselineOffsetSpan>(CalcDimension(0, DimensionUnit::VP));
594 }
595 return AceType::MakeRefPtr<BaselineOffsetSpan>(ParseLengthMetrics(obj));
596 }
597
GetBaselineOffset(const JSCallbackInfo & info)598 void JSBaselineOffsetSpan::GetBaselineOffset(const JSCallbackInfo& info)
599 {
600 CHECK_NULL_VOID(baselineOffsetSpan_);
601 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(baselineOffsetSpan_->GetBaselineOffset().ConvertToVp())));
602 info.SetReturnValue(ret);
603 }
604
SetBaselineOffset(const JSCallbackInfo & info)605 void JSBaselineOffsetSpan::SetBaselineOffset(const JSCallbackInfo& info) {}
606
GetBaselineOffsetSpan()607 RefPtr<BaselineOffsetSpan>& JSBaselineOffsetSpan::GetBaselineOffsetSpan()
608 {
609 return baselineOffsetSpan_;
610 }
611
SetBaselineOffsetSpan(const RefPtr<BaselineOffsetSpan> & baselineOffsetSpan)612 void JSBaselineOffsetSpan::SetBaselineOffsetSpan(const RefPtr<BaselineOffsetSpan>& baselineOffsetSpan)
613 {
614 baselineOffsetSpan_ = baselineOffsetSpan;
615 }
616
JSBind(BindingTarget globalObj)617 void JSLetterSpacingSpan::JSBind(BindingTarget globalObj)
618 {
619 JSClass<JSLetterSpacingSpan>::Declare("LetterSpacingStyle");
620 JSClass<JSLetterSpacingSpan>::CustomProperty(
621 "letterSpacing", &JSLetterSpacingSpan::GetLetterSpacing, &JSLetterSpacingSpan::SetLetterSpacing);
622 JSClass<JSLetterSpacingSpan>::Bind(globalObj, JSLetterSpacingSpan::Constructor, JSLetterSpacingSpan::Destructor);
623 }
624
Constructor(const JSCallbackInfo & args)625 void JSLetterSpacingSpan::Constructor(const JSCallbackInfo& args)
626 {
627 auto letterSpacingSpan = Referenced::MakeRefPtr<JSLetterSpacingSpan>();
628 letterSpacingSpan->IncRefCount();
629
630 RefPtr<LetterSpacingSpan> span;
631 if (args.Length() <= 0 || !args[0]->IsObject()) {
632 span = AceType::MakeRefPtr<LetterSpacingSpan>();
633 } else {
634 span = JSLetterSpacingSpan::ParseJSLetterSpacingSpan(JSRef<JSObject>::Cast(args[0]));
635 }
636 letterSpacingSpan->letterSpacingSpan_ = span;
637 args.SetReturnValue(Referenced::RawPtr(letterSpacingSpan));
638 }
639
Destructor(JSLetterSpacingSpan * letterSpacingSpan)640 void JSLetterSpacingSpan::Destructor(JSLetterSpacingSpan* letterSpacingSpan)
641 {
642 if (letterSpacingSpan != nullptr) {
643 letterSpacingSpan->DecRefCount();
644 }
645 }
646
ParseJSLetterSpacingSpan(const JSRef<JSObject> & obj)647 RefPtr<LetterSpacingSpan> JSLetterSpacingSpan::ParseJSLetterSpacingSpan(const JSRef<JSObject>& obj)
648 {
649 if (obj->IsUndefined()) {
650 return AceType::MakeRefPtr<LetterSpacingSpan>(CalcDimension(0, DimensionUnit::VP));
651 }
652 return AceType::MakeRefPtr<LetterSpacingSpan>(ParseLengthMetrics(obj));
653 }
654
GetLetterSpacing(const JSCallbackInfo & info)655 void JSLetterSpacingSpan::GetLetterSpacing(const JSCallbackInfo& info)
656 {
657 CHECK_NULL_VOID(letterSpacingSpan_);
658 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(letterSpacingSpan_->GetLetterSpacing().ConvertToVp())));
659 info.SetReturnValue(ret);
660 }
661
SetLetterSpacing(const JSCallbackInfo & info)662 void JSLetterSpacingSpan::SetLetterSpacing(const JSCallbackInfo& info) {}
663
GetLetterSpacingSpan()664 RefPtr<LetterSpacingSpan>& JSLetterSpacingSpan::GetLetterSpacingSpan()
665 {
666 return letterSpacingSpan_;
667 }
668
SetLetterSpacingSpan(const RefPtr<LetterSpacingSpan> & letterSpacingSpan)669 void JSLetterSpacingSpan::SetLetterSpacingSpan(const RefPtr<LetterSpacingSpan>& letterSpacingSpan)
670 {
671 letterSpacingSpan_ = letterSpacingSpan;
672 }
673
Constructor(const JSCallbackInfo & args)674 void JSGestureSpan::Constructor(const JSCallbackInfo& args)
675 {
676 auto gestureSpan = Referenced::MakeRefPtr<JSGestureSpan>();
677 gestureSpan->IncRefCount();
678
679 RefPtr<GestureSpan> span;
680 if (args.Length() <= 0) {
681 GestureStyle gestureInfo;
682 span = AceType::MakeRefPtr<GestureSpan>(gestureInfo);
683 } else {
684 span = JSGestureSpan::ParseJSGestureSpan(args);
685 }
686 gestureSpan->gestureSpan_ = span;
687 args.SetReturnValue(Referenced::RawPtr(gestureSpan));
688 }
689
Destructor(JSGestureSpan * gestureSpan)690 void JSGestureSpan::Destructor(JSGestureSpan* gestureSpan)
691 {
692 if (gestureSpan != nullptr) {
693 gestureSpan->DecRefCount();
694 }
695 }
696
JSBind(BindingTarget globalObj)697 void JSGestureSpan::JSBind(BindingTarget globalObj)
698 {
699 JSClass<JSGestureSpan>::Declare("NativeGestureStyle");
700 JSClass<JSGestureSpan>::Bind(globalObj, JSGestureSpan::Constructor, JSGestureSpan::Destructor);
701 }
702
ParseJSGestureSpan(const JSCallbackInfo & args)703 RefPtr<GestureSpan> JSGestureSpan::ParseJSGestureSpan(const JSCallbackInfo& args)
704 {
705 GestureStyle gestureInfo;
706 if (args.Length() <= 0 || !args[0]->IsObject()) {
707 gestureInfo = { std::nullopt, std::nullopt, std::nullopt };
708 return AceType::MakeRefPtr<GestureSpan>(gestureInfo);
709 }
710 JSRef<JSObject> object = JSRef<JSObject>::Cast(args[0]);
711
712 auto clickFunc = object->GetProperty("onClick");
713 if (clickFunc->IsUndefined() || !clickFunc->IsFunction()) {
714 gestureInfo.onClick = std::nullopt;
715 } else {
716 auto jsOnClickFunc = AceType::MakeRefPtr<JsWeakClickFunction>(JSRef<JSFunc>::Cast(clickFunc));
717 auto onClick = [execCtx = args.GetExecutionContext(), func = jsOnClickFunc](BaseEventInfo* info) {
718 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
719 auto* clickInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
720 ACE_SCORING_EVENT("SpanString.onClick");
721 func->Execute(*clickInfo);
722 };
723 auto tmpClickFunc = [func = std::move(onClick)](GestureEvent& info) { func(&info); };
724 gestureInfo.onClick = std::move(tmpClickFunc);
725 }
726
727 auto longPressFunc = object->GetProperty("onLongPress");
728 if (longPressFunc->IsUndefined() || !longPressFunc->IsFunction()) {
729 gestureInfo.onLongPress = std::nullopt;
730 } else {
731 auto jsOnLongPressFunc = AceType::MakeRefPtr<JsWeakClickFunction>(JSRef<JSFunc>::Cast(longPressFunc));
732 auto onLongPress = [execCtx = args.GetExecutionContext(), func = jsOnLongPressFunc](BaseEventInfo* info) {
733 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
734 auto* longPressInfo = TypeInfoHelper::DynamicCast<GestureEvent>(info);
735 ACE_SCORING_EVENT("SpanString.onLongPress");
736 func->Execute(*longPressInfo);
737 };
738 auto tmpLongPressFunc = [func = std::move(onLongPress)](GestureEvent& info) { func(&info); };
739 gestureInfo.onLongPress = std::move(tmpLongPressFunc);
740 }
741
742 auto touchFunc = object->GetProperty("onTouch");
743 if (touchFunc->IsUndefined() || !touchFunc->IsFunction()) {
744 gestureInfo.onTouch = std::nullopt;
745 } else {
746 auto jsOnTouchWeakFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSFunc>::Cast(touchFunc));
747 auto onTouch = [execCtx = args.GetExecutionContext(), func = jsOnTouchWeakFunc](TouchEventInfo& info) {
748 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
749 ACE_SCORING_EVENT("SpanString.onTouch");
750 JSRef<JSVal> param = JsTouchFunction::CreateJSEventInfo(info);
751 func->ExecuteJS(1, ¶m);
752 };
753 gestureInfo.onTouch = std::move(onTouch);
754 }
755 return AceType::MakeRefPtr<GestureSpan>(gestureInfo);
756 }
757
GetGestureSpan()758 RefPtr<GestureSpan>& JSGestureSpan::GetGestureSpan()
759 {
760 return gestureSpan_;
761 }
762
SetGestureSpan(const RefPtr<GestureSpan> & gestureSpan)763 void JSGestureSpan::SetGestureSpan(const RefPtr<GestureSpan>& gestureSpan)
764 {
765 gestureSpan_ = gestureSpan;
766 }
JSBind(BindingTarget globalObj)767 void JSTextShadowSpan::JSBind(BindingTarget globalObj)
768 {
769 JSClass<JSTextShadowSpan>::Declare("TextShadowStyle");
770 JSClass<JSTextShadowSpan>::CustomProperty(
771 "textShadow", &JSTextShadowSpan::GetTextShadow, &JSTextShadowSpan::SetTextShadow);
772 JSClass<JSTextShadowSpan>::Bind(globalObj, JSTextShadowSpan::Constructor, JSTextShadowSpan::Destructor);
773 }
774
Constructor(const JSCallbackInfo & args)775 void JSTextShadowSpan::Constructor(const JSCallbackInfo& args)
776 {
777 auto textShadowSpan = Referenced::MakeRefPtr<JSTextShadowSpan>();
778 textShadowSpan->IncRefCount();
779
780 RefPtr<TextShadowSpan> span;
781 if (args.Length() <= 0 || !args[0]->IsObject()) {
782 std::vector<Shadow> shadows;
783 span = AceType::MakeRefPtr<TextShadowSpan>(shadows);
784 } else {
785 span = JSTextShadowSpan::ParseJSTextShadowSpan(JSRef<JSObject>::Cast(args[0]));
786 }
787 textShadowSpan->textShadowSpan_ = span;
788 args.SetReturnValue(Referenced::RawPtr(textShadowSpan));
789 }
790
Destructor(JSTextShadowSpan * textShadowSpan)791 void JSTextShadowSpan::Destructor(JSTextShadowSpan* textShadowSpan)
792 {
793 if (textShadowSpan != nullptr) {
794 textShadowSpan->DecRefCount();
795 }
796 }
797
ParseJSTextShadowSpan(const JSRef<JSObject> & obj)798 RefPtr<TextShadowSpan> JSTextShadowSpan::ParseJSTextShadowSpan(const JSRef<JSObject>& obj)
799 {
800 std::vector<Shadow> shadows;
801 ParseTextShadowFromShadowObject(obj, shadows);
802 return AceType::MakeRefPtr<TextShadowSpan>(shadows);
803 }
804
GetTextShadow(const JSCallbackInfo & info)805 void JSTextShadowSpan::GetTextShadow(const JSCallbackInfo& info)
806 {
807 CHECK_NULL_VOID(textShadowSpan_);
808 auto shadows = textShadowSpan_->GetTextShadow();
809
810 JSRef<JSArray> result = JSRef<JSArray>::New();
811 uint32_t index = 0;
812 for (auto iterator = shadows.begin(); iterator != shadows.end(); ++iterator) {
813 auto shadow = *iterator;
814 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
815 objectTemplate->SetInternalFieldCount(1);
816 JSRef<JSObject> shadowObj = objectTemplate->NewInstance();
817 shadowObj->SetProperty<double>("radius", shadow.GetBlurRadius());
818 shadowObj->SetProperty<double>("offsetX", shadow.GetOffset().GetX());
819 shadowObj->SetProperty<double>("offsetY", shadow.GetOffset().GetY());
820 shadowObj->SetProperty<std::string>("color", shadow.GetColor().ColorToString());
821 shadowObj->SetProperty<int32_t>("type", static_cast<int32_t>(shadow.GetShadowType()));
822 result->SetValueAt(index++, shadowObj);
823 }
824 info.SetReturnValue(result);
825 }
826
SetTextShadow(const JSCallbackInfo & info)827 void JSTextShadowSpan::SetTextShadow(const JSCallbackInfo& info) {}
828
GetTextShadowSpan()829 RefPtr<TextShadowSpan>& JSTextShadowSpan::GetTextShadowSpan()
830 {
831 return textShadowSpan_;
832 }
833
SetTextShadowSpan(const RefPtr<TextShadowSpan> & textShadowSpan)834 void JSTextShadowSpan::SetTextShadowSpan(const RefPtr<TextShadowSpan>& textShadowSpan)
835 {
836 textShadowSpan_ = textShadowSpan;
837 }
838
839 // JSImageAttachment
Constructor(const JSCallbackInfo & args)840 void JSImageAttachment::Constructor(const JSCallbackInfo& args)
841 {
842 auto imageAttachment = Referenced::MakeRefPtr<JSImageAttachment>();
843 imageAttachment->IncRefCount();
844
845 RefPtr<ImageSpan> span;
846 if (args.Length() <= 0 || !args[0]->IsObject()) {
847 ImageSpanOptions imageOption;
848 span = AceType::MakeRefPtr<ImageSpan>(imageOption);
849 } else {
850 span = JSImageAttachment::ParseJsImageSpan(JSRef<JSObject>::Cast(args[0]));
851 }
852 imageAttachment->imageSpan_ = span;
853 args.SetReturnValue(Referenced::RawPtr(imageAttachment));
854 }
855
Destructor(JSImageAttachment * imageSpan)856 void JSImageAttachment::Destructor(JSImageAttachment* imageSpan)
857 {
858 if (imageSpan != nullptr) {
859 imageSpan->DecRefCount();
860 }
861 }
862
JSBind(BindingTarget globalObj)863 void JSImageAttachment::JSBind(BindingTarget globalObj)
864 {
865 JSClass<JSImageAttachment>::Declare("ImageAttachment");
866 JSClass<JSImageAttachment>::CustomProperty(
867 "value", &JSImageAttachment::GetImageSrc, &JSImageAttachment::SetImageSrc);
868 JSClass<JSImageAttachment>::CustomProperty(
869 "size", &JSImageAttachment::GetImageSize, &JSImageAttachment::SetImageSize);
870 JSClass<JSImageAttachment>::CustomProperty(
871 "verticalAlign", &JSImageAttachment::GetImageVerticalAlign, &JSImageAttachment::SetImageVerticalAlign);
872 JSClass<JSImageAttachment>::CustomProperty(
873 "objectFit", &JSImageAttachment::GetImageObjectFit, &JSImageAttachment::SetImageObjectFit);
874 JSClass<JSImageAttachment>::CustomProperty(
875 "layoutStyle", &JSImageAttachment::GetImageLayoutStyle, &JSImageAttachment::SetImageLayoutStyle);
876 JSClass<JSImageAttachment>::CustomProperty(
877 "colorFilter", &JSImageAttachment::GetImageColorFilter, &JSImageAttachment::SetImageColorFilter);
878 JSClass<JSImageAttachment>::Bind(globalObj, JSImageAttachment::Constructor, JSImageAttachment::Destructor);
879 }
880
ParseJsImageSpan(const JSRef<JSObject> & obj)881 RefPtr<ImageSpan> JSImageAttachment::ParseJsImageSpan(const JSRef<JSObject>& obj)
882 {
883 auto imageOptions = JSImageAttachment::CreateImageOptions(obj);
884 auto imageAttribute = JSImageAttachment::ParseJsImageSpanAttribute(obj);
885 imageOptions.imageAttribute = imageAttribute;
886 auto imageSpan = MakeRefPtr<ImageSpan>(imageOptions);
887 return imageSpan;
888 }
889
CreateImageOptions(const JSRef<JSObject> & obj)890 ImageSpanOptions JSImageAttachment::CreateImageOptions(const JSRef<JSObject>& obj)
891 {
892 ImageSpanOptions options;
893 auto container = Container::CurrentSafely();
894 auto context = PipelineBase::GetCurrentContextSafelyWithCheck();
895 CHECK_NULL_RETURN(context, options);
896 bool isCard = context->IsFormRender() && container && !container->IsDynamicRender();
897
898 std::string imageSrc;
899 std::string bundleName;
900 std::string moduleName;
901 int32_t resId = 0;
902 auto srcValid = obj->HasProperty("resourceValue");
903 auto imageValue = srcValid ? obj->GetProperty("resourceValue") : obj->GetProperty("value");
904 JSViewAbstract::ParseJsMediaWithBundleName(imageValue, imageSrc, bundleName, moduleName, resId);
905 if (isCard && imageValue->IsString()) {
906 SrcType srcType = ImageSourceInfo::ResolveURIType(imageSrc);
907 bool notSupport = (srcType == SrcType::NETWORK || srcType == SrcType::FILE || srcType == SrcType::DATA_ABILITY);
908 if (notSupport) {
909 imageSrc.clear();
910 }
911 }
912 options.image = imageSrc;
913 options.bundleName = bundleName;
914 options.moduleName = moduleName;
915 options.isUriPureNumber = (resId == -1);
916 if (!srcValid) {
917 #if defined(PIXEL_MAP_SUPPORTED)
918 if (!isCard) {
919 if (JSImage::IsDrawable(imageValue)) {
920 options.imagePixelMap = GetDrawablePixmap(imageValue);
921 } else {
922 options.imagePixelMap = CreatePixelMapFromNapiValue(imageValue);
923 }
924 }
925 #endif
926 }
927 return options;
928 }
929
ParseJsImageSpanAttribute(const JSRef<JSObject> & obj)930 ImageSpanAttribute JSImageAttachment::ParseJsImageSpanAttribute(const JSRef<JSObject>& obj)
931 {
932 ImageSpanAttribute imageStyle;
933 ParseJsImageSpanSizeAttribute(obj, imageStyle);
934 JSRef<JSVal> verticalAlign = obj->GetProperty("verticalAlign");
935 if (!verticalAlign->IsNull()) {
936 auto align = static_cast<VerticalAlign>(verticalAlign->ToNumber<int32_t>());
937 if (align < VerticalAlign::TOP || align > VerticalAlign::NONE) {
938 align = VerticalAlign::BOTTOM;
939 }
940 imageStyle.verticalAlign = align;
941 }
942 JSRef<JSVal> objectFit = obj->GetProperty("objectFit");
943 if (!objectFit->IsNull() && objectFit->IsNumber()) {
944 auto fit = static_cast<ImageFit>(objectFit->ToNumber<int32_t>());
945 if (fit < ImageFit::FILL || fit > ImageFit::BOTTOM_END) {
946 fit = ImageFit::COVER;
947 }
948 imageStyle.objectFit = fit;
949 } else {
950 imageStyle.objectFit = ImageFit::COVER;
951 }
952 auto layoutStyleObj = obj->GetProperty("layoutStyle");
953 if (layoutStyleObj->IsObject()) {
954 auto layoutStyleObject = JSRef<JSObject>::Cast(layoutStyleObj);
955 if (!layoutStyleObject->IsUndefined()) {
956 auto marginAttr = layoutStyleObject->GetProperty("margin");
957 imageStyle.marginProp = JSRichEditor::ParseMarginAttr(marginAttr);
958 auto paddingAttr = layoutStyleObject->GetProperty("padding");
959 imageStyle.paddingProp = JSRichEditor::ParseMarginAttr(paddingAttr);
960 auto borderRadiusAttr = layoutStyleObject->GetProperty("borderRadius");
961 imageStyle.borderRadius = JSRichEditor::ParseBorderRadiusAttr(borderRadiusAttr);
962 }
963 }
964
965 auto syncLoadObj = obj->GetProperty("syncLoad");
966 if (!syncLoadObj->IsNull() && syncLoadObj->IsBoolean()) {
967 imageStyle.syncLoad = syncLoadObj->ToBoolean();
968 }
969
970 ParseJsImageSpanColorFilterAttribute(obj, imageStyle);
971 return imageStyle;
972 }
973
ParseJsImageSpanColorFilterAttribute(const JSRef<JSObject> & obj,ImageSpanAttribute & imageStyle)974 void JSImageAttachment::ParseJsImageSpanColorFilterAttribute(const JSRef<JSObject>& obj, ImageSpanAttribute& imageStyle)
975 {
976 auto colorFilterObj = obj->GetProperty("colorFilter");
977 if (colorFilterObj->IsNull()) {
978 return;
979 }
980 if (!colorFilterObj->IsArray() && !colorFilterObj->IsObject()) {
981 SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
982 return;
983 }
984 if (colorFilterObj->IsObject() && !colorFilterObj->IsArray()) {
985 auto drawingColorFilter = CreateDrawingColorFilter(colorFilterObj);
986 if (drawingColorFilter) {
987 imageStyle.colorFilterMatrix = std::nullopt;
988 imageStyle.drawingColorFilter = drawingColorFilter;
989 return;
990 }
991 JSColorFilter* colorFilter;
992 if (!colorFilterObj->IsUndefined() && !colorFilterObj->IsNull()) {
993 colorFilter = JSRef<JSObject>::Cast(colorFilterObj)->Unwrap<JSColorFilter>();
994 } else {
995 SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
996 return;
997 }
998 if (colorFilter && colorFilter->GetColorFilterMatrix().size() == COLOR_FILTER_MATRIX_SIZE) {
999 SetImageSpanColorFilterAttribute(imageStyle, colorFilter->GetColorFilterMatrix());
1000 return;
1001 }
1002 SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
1003 return;
1004 }
1005 JSRef<JSArray> array = JSRef<JSArray>::Cast(colorFilterObj);
1006 if (array->Length() != COLOR_FILTER_MATRIX_SIZE) {
1007 SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
1008 return;
1009 }
1010 std::vector<float> colorfilter;
1011 for (size_t i = 0; i < array->Length(); i++) {
1012 JSRef<JSVal> value = array->GetValueAt(i);
1013 if (!value->IsNumber()) {
1014 SetImageSpanColorFilterAttribute(imageStyle, DEFAULT_COLORFILTER_MATRIX);
1015 return;
1016 }
1017 colorfilter.emplace_back(value->ToNumber<float>());
1018 }
1019 SetImageSpanColorFilterAttribute(imageStyle, colorfilter);
1020 }
1021
SetImageSpanColorFilterAttribute(ImageSpanAttribute & imageStyle,const std::vector<float> & matrix)1022 void JSImageAttachment::SetImageSpanColorFilterAttribute(ImageSpanAttribute& imageStyle,
1023 const std::vector<float>& matrix)
1024 {
1025 imageStyle.colorFilterMatrix = matrix;
1026 imageStyle.drawingColorFilter = std::nullopt;
1027 }
1028
ParseJsImageSpanSizeAttribute(const JSRef<JSObject> & obj,ImageSpanAttribute & imageStyle)1029 void JSImageAttachment::ParseJsImageSpanSizeAttribute(const JSRef<JSObject>& obj, ImageSpanAttribute& imageStyle)
1030 {
1031 auto sizeObj = obj->GetProperty("size");
1032 if (sizeObj->IsObject()) {
1033 ImageSpanSize imageSize;
1034 auto size = JSRef<JSObject>::Cast(sizeObj);
1035 JSRef<JSVal> width = size->GetProperty("width");
1036 CalcDimension imageSpanWidth;
1037 if (!width->IsNull() && JSContainerBase::ParseJsDimensionVpNG(width, imageSpanWidth, false) &&
1038 GreatNotEqual(imageSpanWidth.Value(), 0.0)) {
1039 imageSize.width = imageSpanWidth;
1040 }
1041 JSRef<JSVal> height = size->GetProperty("height");
1042 CalcDimension imageSpanHeight;
1043 if (!height->IsNull() && JSContainerBase::ParseJsDimensionVpNG(height, imageSpanHeight, false) &&
1044 GreatNotEqual(imageSpanHeight.Value(), 0.0)) {
1045 imageSize.height = imageSpanHeight;
1046 }
1047 imageStyle.size = imageSize;
1048 }
1049 }
1050
GetImageSrc(const JSCallbackInfo & info)1051 void JSImageAttachment::GetImageSrc(const JSCallbackInfo& info)
1052 {
1053 CHECK_NULL_VOID(imageSpan_);
1054 auto imageOptions = imageSpan_->GetImageSpanOptions();
1055 JSRef<JSVal> ret;
1056 if (imageOptions.image.has_value()) {
1057 ret = JSRef<JSVal>::Make(ToJSValue(imageOptions.image.value()));
1058 }
1059 if (imageOptions.imagePixelMap.has_value()) {
1060 #ifdef PIXEL_MAP_SUPPORTED
1061 ret = ConvertPixmap(imageOptions.imagePixelMap.value());
1062 #endif
1063 }
1064 info.SetReturnValue(ret);
1065 }
1066
GetImageSize(const JSCallbackInfo & info)1067 void JSImageAttachment::GetImageSize(const JSCallbackInfo& info)
1068 {
1069 CHECK_NULL_VOID(imageSpan_);
1070 auto imageAttr = imageSpan_->GetImageAttribute();
1071 if (!imageAttr.has_value() || !imageAttr->size.has_value()) {
1072 return;
1073 }
1074 auto imageSize = JSRef<JSObject>::New();
1075 auto size = imageAttr->size;
1076 if (size->width.has_value()) {
1077 imageSize->SetProperty<float>("width", size->width->ConvertToPx());
1078 } else {
1079 imageSize->SetProperty<float>("width", 0.0);
1080 }
1081
1082 if (size->height.has_value()) {
1083 imageSize->SetProperty<float>("height", size->height->ConvertToPx());
1084 } else {
1085 imageSize->SetProperty<float>("height", 0.0);
1086 }
1087 info.SetReturnValue(imageSize);
1088 }
1089
GetImageVerticalAlign(const JSCallbackInfo & info)1090 void JSImageAttachment::GetImageVerticalAlign(const JSCallbackInfo& info)
1091 {
1092 CHECK_NULL_VOID(imageSpan_);
1093 auto imageAttr = imageSpan_->GetImageAttribute();
1094 if (!imageAttr.has_value() || !imageAttr->verticalAlign.has_value()) {
1095 return;
1096 }
1097 info.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(imageAttr->verticalAlign.value()))));
1098 }
1099
GetImageObjectFit(const JSCallbackInfo & info)1100 void JSImageAttachment::GetImageObjectFit(const JSCallbackInfo& info)
1101 {
1102 CHECK_NULL_VOID(imageSpan_);
1103 auto imageAttr = imageSpan_->GetImageAttribute();
1104 if (!imageAttr.has_value() || !imageAttr->objectFit.has_value()) {
1105 return;
1106 }
1107 info.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(imageAttr->objectFit.value()))));
1108 }
1109
CreateEdge(const NG::PaddingPropertyT<NG::CalcLength> & edge)1110 JSRef<JSObject> JSImageAttachment::CreateEdge(const NG::PaddingPropertyT<NG::CalcLength>& edge)
1111 {
1112 auto obj = JSRef<JSObject>::New();
1113 if (edge.top.has_value()) {
1114 obj->SetProperty("top", edge.top->GetDimension().ConvertToVp());
1115 }
1116 if (edge.bottom.has_value()) {
1117 obj->SetProperty("bottom", edge.bottom->GetDimension().ConvertToVp());
1118 }
1119 if (edge.left.has_value()) {
1120 obj->SetProperty("left", edge.left->GetDimension().ConvertToVp());
1121 }
1122 if (edge.right.has_value()) {
1123 obj->SetProperty("right", edge.right->GetDimension().ConvertToVp());
1124 }
1125 return obj;
1126 }
1127
CreateBorderRadius(const NG::BorderRadiusProperty & borderRadius)1128 JSRef<JSObject> JSImageAttachment::CreateBorderRadius(const NG::BorderRadiusProperty& borderRadius)
1129 {
1130 auto jsBorderRadius = JSRef<JSObject>::New();
1131 if (borderRadius.radiusTopLeft.has_value()) {
1132 jsBorderRadius->SetProperty("topLeft", borderRadius.radiusTopLeft->ConvertToVp());
1133 }
1134 if (borderRadius.radiusTopRight.has_value()) {
1135 jsBorderRadius->SetProperty("topRight", borderRadius.radiusTopRight->ConvertToVp());
1136 }
1137 if (borderRadius.radiusBottomLeft.has_value()) {
1138 jsBorderRadius->SetProperty("bottomLeft", borderRadius.radiusBottomLeft->ConvertToVp());
1139 }
1140 if (borderRadius.radiusBottomRight.has_value()) {
1141 jsBorderRadius->SetProperty("bottomRight", borderRadius.radiusBottomRight->ConvertToVp());
1142 }
1143 return jsBorderRadius;
1144 }
1145
GetImageLayoutStyle(const JSCallbackInfo & info)1146 void JSImageAttachment::GetImageLayoutStyle(const JSCallbackInfo& info)
1147 {
1148 CHECK_NULL_VOID(imageSpan_);
1149 auto imageAttr = imageSpan_->GetImageAttribute();
1150 if (!imageAttr.has_value()) {
1151 return;
1152 }
1153 auto layoutStyle = JSRef<JSObject>::New();
1154 if (imageAttr->marginProp.has_value()) {
1155 layoutStyle->SetPropertyObject("margin", CreateEdge(imageAttr->marginProp.value()));
1156 }
1157 if (imageAttr->paddingProp.has_value()) {
1158 layoutStyle->SetPropertyObject("padding", CreateEdge(imageAttr->paddingProp.value()));
1159 }
1160 if (imageAttr->borderRadius.has_value()) {
1161 layoutStyle->SetPropertyObject("borderRadius", CreateBorderRadius(imageAttr->borderRadius.value()));
1162 }
1163 info.SetReturnValue(layoutStyle);
1164 }
1165
GetImageColorFilter(const JSCallbackInfo & info)1166 void JSImageAttachment::GetImageColorFilter(const JSCallbackInfo& info)
1167 {
1168 CHECK_NULL_VOID(imageSpan_);
1169 auto imageAttr = imageSpan_->GetImageAttribute();
1170 if (!imageAttr.has_value()) {
1171 return;
1172 }
1173 if (imageAttr->colorFilterMatrix.has_value()) {
1174 JSRef<JSArray> colorFilterArr = JSRef<JSArray>::New();
1175 uint32_t othersIdx = 0;
1176 for (auto filterFloat : imageAttr->colorFilterMatrix.value()) {
1177 colorFilterArr->SetValueAt(othersIdx++, JSRef<JSVal>::Make(ToJSValue(filterFloat)));
1178 }
1179 info.SetReturnValue(colorFilterArr);
1180 return;
1181 }
1182 if (imageAttr->drawingColorFilter.has_value()) {
1183 auto engine = EngineHelper::GetCurrentEngine();
1184 CHECK_NULL_VOID(engine);
1185 NativeEngine* nativeEngine = engine->GetNativeEngine();
1186 CHECK_NULL_VOID(nativeEngine);
1187 auto jsColorFilter = imageAttr->drawingColorFilter.value()->GetDrawingColorFilterNapiValue(nativeEngine);
1188 CHECK_NULL_VOID(jsColorFilter);
1189 auto colorFilterJsVal = JsConverter::ConvertNapiValueToJsVal(jsColorFilter);
1190 CHECK_NULL_VOID(colorFilterJsVal->IsObject());
1191 info.SetReturnValue(JSRef<JSObject>::Cast(colorFilterJsVal));
1192 }
1193 }
1194
GetImageSpan()1195 const RefPtr<ImageSpan>& JSImageAttachment::GetImageSpan()
1196 {
1197 return imageSpan_;
1198 }
1199
SetImageSpan(const RefPtr<ImageSpan> & imageSpan)1200 void JSImageAttachment::SetImageSpan(const RefPtr<ImageSpan>& imageSpan)
1201 {
1202 imageSpan_ = imageSpan;
1203 }
1204
GetImageOptions() const1205 const ImageSpanOptions& JSImageAttachment::GetImageOptions() const
1206 {
1207 return imageSpan_->GetImageSpanOptions();
1208 }
1209
1210 // JSNativeCustomSpan
Constructor(const JSCallbackInfo & args)1211 void JSNativeCustomSpan::Constructor(const JSCallbackInfo& args)
1212 {
1213 auto customSpan = Referenced::MakeRefPtr<JSNativeCustomSpan>();
1214 customSpan->IncRefCount();
1215 args.SetReturnValue(Referenced::RawPtr(customSpan));
1216 }
1217
Destructor(JSNativeCustomSpan * customSpan)1218 void JSNativeCustomSpan::Destructor(JSNativeCustomSpan* customSpan)
1219 {
1220 if (customSpan != nullptr) {
1221 customSpan->DecRefCount();
1222 }
1223 }
1224
Invalidate(const JSCallbackInfo & info)1225 void JSNativeCustomSpan::Invalidate(const JSCallbackInfo& info)
1226 {
1227 for (const auto& styledStringWeakPtr : spanStringBaseSet_) {
1228 auto styledString = AceType::DynamicCast<SpanString>(styledStringWeakPtr.Upgrade());
1229 if (!styledString) {
1230 continue;
1231 }
1232 styledString->MarkDirtyFrameNode();
1233 }
1234 }
1235
JSBind(BindingTarget globalObj)1236 void JSNativeCustomSpan::JSBind(BindingTarget globalObj)
1237 {
1238 JSClass<JSNativeCustomSpan>::Declare("NativeCustomSpan");
1239 JSClass<JSNativeCustomSpan>::CustomMethod("invalidate", &JSNativeCustomSpan::Invalidate);
1240 JSClass<JSNativeCustomSpan>::Bind(globalObj, JSNativeCustomSpan::Constructor, JSNativeCustomSpan::Destructor);
1241 }
1242
AddStyledString(const WeakPtr<SpanStringBase> & spanString)1243 void JSNativeCustomSpan::AddStyledString(const WeakPtr<SpanStringBase>& spanString)
1244 {
1245 spanStringBaseSet_.insert(spanString);
1246 }
1247
RemoveStyledString(const WeakPtr<SpanStringBase> & spanString)1248 void JSNativeCustomSpan::RemoveStyledString(const WeakPtr<SpanStringBase>& spanString)
1249 {
1250 spanStringBaseSet_.erase(spanString);
1251 }
1252
1253 // JSCustomSpan
AddStyledString(const WeakPtr<SpanStringBase> & spanString)1254 void JSCustomSpan::AddStyledString(const WeakPtr<SpanStringBase>& spanString)
1255 {
1256 CHECK_NULL_VOID(customSpan_);
1257 customSpan_->AddStyledString(spanString);
1258 }
1259
RemoveStyledString(const WeakPtr<SpanStringBase> & spanString)1260 void JSCustomSpan::RemoveStyledString(const WeakPtr<SpanStringBase>& spanString)
1261 {
1262 CHECK_NULL_VOID(customSpan_);
1263 customSpan_->RemoveStyledString(spanString);
1264 }
1265
JSCustomSpan(JSRef<JSObject> customSpanObj,const JSCallbackInfo & args)1266 JSCustomSpan::JSCustomSpan(JSRef<JSObject> customSpanObj, const JSCallbackInfo& args) : customSpanObj_(customSpanObj)
1267 {
1268 auto obj = JSRef<JSObject>::Cast(customSpanObj);
1269 if (obj->IsUndefined()) {
1270 return;
1271 }
1272 JSRef<JSVal> onMeasure = obj->GetProperty("onMeasure");
1273 if (onMeasure->IsFunction()) {
1274 auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(obj), JSRef<JSFunc>::Cast(onMeasure));
1275 auto onMeasureFunc = JSCustomSpan::ParseOnMeasureFunc(jsDrawFunc, args.GetExecutionContext());
1276 CustomSpan::SetOnMeasure(onMeasureFunc);
1277 }
1278 JSRef<JSVal> onDraw = obj->GetProperty("onDraw");
1279 if (onDraw->IsFunction()) {
1280 auto jsDrawFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(obj), JSRef<JSFunc>::Cast(onDraw));
1281 auto onDrawFunc = JSCustomSpan::ParseOnDrawFunc(jsDrawFunc, args.GetExecutionContext());
1282 CustomSpan::SetOnDraw(onDrawFunc);
1283 }
1284 auto type = customSpanObj->Unwrap<AceType>();
1285 CHECK_NULL_VOID(type);
1286 auto* nativeCustomSpan = AceType::DynamicCast<JSNativeCustomSpan>(type);
1287 customSpan_ = nativeCustomSpan;
1288 }
1289
JSCustomSpan(JSRef<JSObject> customSpanObj,std::optional<std::function<CustomSpanMetrics (CustomSpanMeasureInfo)>> onMeasure,std::optional<std::function<void (NG::DrawingContext &,CustomSpanOptions)>> onDraw,int32_t start,int32_t end)1290 JSCustomSpan::JSCustomSpan(JSRef<JSObject> customSpanObj,
1291 std::optional<std::function<CustomSpanMetrics(CustomSpanMeasureInfo)>> onMeasure,
1292 std::optional<std::function<void(NG::DrawingContext&, CustomSpanOptions)>> onDraw, int32_t start, int32_t end)
1293 : CustomSpan(onMeasure, onDraw, start, end), customSpanObj_(customSpanObj)
1294 {
1295 auto type = customSpanObj->Unwrap<AceType>();
1296 CHECK_NULL_VOID(type);
1297 auto* nativeCustomSpan = AceType::DynamicCast<JSNativeCustomSpan>(type);
1298 customSpan_ = nativeCustomSpan;
1299 }
1300
SetJsCustomSpanObject(const JSRef<JSObject> & customSpanObj)1301 void JSCustomSpan::SetJsCustomSpanObject(const JSRef<JSObject>& customSpanObj)
1302 {
1303 customSpanObj_ = customSpanObj;
1304 }
1305
GetJsCustomSpanObject()1306 JSRef<JSObject>& JSCustomSpan::GetJsCustomSpanObject()
1307 {
1308 return customSpanObj_;
1309 }
GetSubSpan(int32_t start,int32_t end)1310 RefPtr<SpanBase> JSCustomSpan::GetSubSpan(int32_t start, int32_t end)
1311 {
1312 if (end - start > 1) {
1313 return nullptr;
1314 }
1315 RefPtr<SpanBase> spanBase = MakeRefPtr<JSCustomSpan>(customSpanObj_, GetOnMeasure(), GetOnDraw(), start, end);
1316 return spanBase;
1317 }
1318
IsAttributesEqual(const RefPtr<SpanBase> & other) const1319 bool JSCustomSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1320 {
1321 auto customSpan = DynamicCast<JSCustomSpan>(other);
1322 if (!customSpan) {
1323 return false;
1324 }
1325 return (customSpan->customSpanObj_)
1326 ->GetLocalHandle()
1327 ->IsStrictEquals(customSpanObj_->GetEcmaVM(), customSpanObj_->GetLocalHandle());
1328 }
1329
ParseOnMeasureFunc(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)1330 std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> JSCustomSpan::ParseOnMeasureFunc(
1331 const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
1332 {
1333 std::function<CustomSpanMetrics(CustomSpanMeasureInfo)> drawCallback =
1334 [func = std::move(jsDraw), execCtx](CustomSpanMeasureInfo customSpanMeasureInfo) -> CustomSpanMetrics {
1335 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
1336 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1337 objectTemplate->SetInternalFieldCount(1);
1338 JSRef<JSObject> contextObj = objectTemplate->NewInstance();
1339 contextObj->SetProperty<float>("fontSize", customSpanMeasureInfo.fontSize);
1340 auto jsVal = JSRef<JSVal>::Cast(contextObj);
1341 auto obj = func->ExecuteJS(1, &jsVal);
1342 if (obj->IsObject()) {
1343 JSRef<JSObject> result = JSRef<JSObject>::Cast(obj);
1344 float width = 0;
1345 if (result->HasProperty("width")) {
1346 auto widthObj = result->GetProperty("width");
1347 width = widthObj->ToNumber<float>();
1348 if (LessNotEqual(width, 0.0)) {
1349 width = 0;
1350 }
1351 }
1352 std::optional<float> heightOpt;
1353 if (result->HasProperty("height")) {
1354 auto heightObj = result->GetProperty("height");
1355 auto height = heightObj->ToNumber<float>();
1356 if (GreatOrEqual(height, 0.0)) {
1357 heightOpt = height;
1358 }
1359 }
1360 return { width, heightOpt };
1361 }
1362 return { 0, 0 };
1363 };
1364 return drawCallback;
1365 }
1366
ParseOnDrawFunc(const RefPtr<JsFunction> & jsDraw,const JSExecutionContext & execCtx)1367 std::function<void(NG::DrawingContext&, CustomSpanOptions)> JSCustomSpan::ParseOnDrawFunc(
1368 const RefPtr<JsFunction>& jsDraw, const JSExecutionContext& execCtx)
1369 {
1370 std::function<void(NG::DrawingContext&, CustomSpanOptions)> drawCallback =
1371 [func = std::move(jsDraw), execCtx](NG::DrawingContext& context, CustomSpanOptions customSpanOptions) -> void {
1372 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
1373
1374 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1375 objectTemplate->SetInternalFieldCount(1);
1376 JSRef<JSObject> contextObj = objectTemplate->NewInstance();
1377 JSRef<JSObject> sizeObj = objectTemplate->NewInstance();
1378 sizeObj->SetProperty<float>("height", PipelineBase::Px2VpWithCurrentDensity(context.height));
1379 sizeObj->SetProperty<float>("width", PipelineBase::Px2VpWithCurrentDensity(context.width));
1380 contextObj->SetPropertyObject("size", sizeObj);
1381
1382 JSRef<JSObject> sizeInPxObj = objectTemplate->NewInstance();
1383 sizeInPxObj->SetProperty<float>("height", context.height);
1384 sizeInPxObj->SetProperty<float>("width", context.width);
1385 contextObj->SetPropertyObject("sizeInPixel", sizeInPxObj);
1386
1387 auto engine = EngineHelper::GetCurrentEngine();
1388 CHECK_NULL_VOID(engine);
1389 NativeEngine* nativeEngine = engine->GetNativeEngine();
1390 napi_env env = reinterpret_cast<napi_env>(nativeEngine);
1391 ScopeRAII scope(env);
1392 auto jsCanvas = OHOS::Rosen::Drawing::JsCanvas::CreateJsCanvas(env, &context.canvas);
1393 OHOS::Rosen::Drawing::JsCanvas* unwrapCanvas = nullptr;
1394 napi_unwrap(env, jsCanvas, reinterpret_cast<void**>(&unwrapCanvas));
1395 if (unwrapCanvas) {
1396 unwrapCanvas->SaveCanvas();
1397 unwrapCanvas->ClipCanvas(context.width, context.height);
1398 }
1399 JsiRef<JsiValue> jsCanvasVal = JsConverter::ConvertNapiValueToJsVal(jsCanvas);
1400 contextObj->SetPropertyObject("canvas", jsCanvasVal);
1401
1402 auto jsVal = JSRef<JSVal>::Cast(contextObj);
1403 panda::Local<JsiValue> value = jsVal.Get().GetLocalHandle();
1404 JSValueWrapper valueWrapper = value;
1405 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
1406
1407 napi_wrap(env, nativeValue, &context.canvas, [](napi_env, void*, void*) {}, nullptr, nullptr);
1408 JSRef<JSObject> customSpanOptionsObj = objectTemplate->NewInstance();
1409 customSpanOptionsObj->SetProperty<float>("x", customSpanOptions.x);
1410 customSpanOptionsObj->SetProperty<float>("lineTop", customSpanOptions.lineTop);
1411 customSpanOptionsObj->SetProperty<float>("lineBottom", customSpanOptions.lineBottom);
1412 customSpanOptionsObj->SetProperty<float>("baseline", customSpanOptions.baseline);
1413 auto customSpanOptionsVal = JSRef<JSVal>::Cast(customSpanOptionsObj);
1414 JSRef<JSVal> params[] = { jsVal, customSpanOptionsVal };
1415 func->ExecuteJS(2, params);
1416 if (unwrapCanvas) {
1417 unwrapCanvas->RestoreCanvas();
1418 unwrapCanvas->ResetCanvas();
1419 }
1420 };
1421 return drawCallback;
1422 }
1423
JSBind(BindingTarget globalObj)1424 void JSLineHeightSpan::JSBind(BindingTarget globalObj)
1425 {
1426 JSClass<JSLineHeightSpan>::Declare("LineHeightStyle");
1427 JSClass<JSLineHeightSpan>::CustomProperty(
1428 "lineHeight", &JSLineHeightSpan::GetLineHeight, &JSLineHeightSpan::SetLineHeight);
1429 JSClass<JSLineHeightSpan>::Bind(globalObj, JSLineHeightSpan::Constructor, JSLineHeightSpan::Destructor);
1430 }
1431
Constructor(const JSCallbackInfo & args)1432 void JSLineHeightSpan::Constructor(const JSCallbackInfo& args)
1433 {
1434 auto lineHeightSpan = Referenced::MakeRefPtr<JSLineHeightSpan>();
1435 lineHeightSpan->IncRefCount();
1436
1437 RefPtr<LineHeightSpan> span;
1438 if (args.Length() <= 0 || !args[0]->IsObject()) {
1439 span = AceType::MakeRefPtr<LineHeightSpan>();
1440 } else {
1441 span = JSLineHeightSpan::ParseJSLineHeightSpan(JSRef<JSObject>::Cast(args[0]));
1442 }
1443 lineHeightSpan->lineHeightSpan_ = span;
1444 args.SetReturnValue(Referenced::RawPtr(lineHeightSpan));
1445 }
1446
Destructor(JSLineHeightSpan * lineHeightSpan)1447 void JSLineHeightSpan::Destructor(JSLineHeightSpan* lineHeightSpan)
1448 {
1449 if (lineHeightSpan != nullptr) {
1450 lineHeightSpan->DecRefCount();
1451 }
1452 }
1453
ParseJSLineHeightSpan(const JSRef<JSObject> & obj)1454 RefPtr<LineHeightSpan> JSLineHeightSpan::ParseJSLineHeightSpan(const JSRef<JSObject>& obj)
1455 {
1456 if (obj->IsUndefined()) {
1457 return AceType::MakeRefPtr<LineHeightSpan>(CalcDimension(0, DimensionUnit::VP));
1458 }
1459 return AceType::MakeRefPtr<LineHeightSpan>(ParseLengthMetrics(obj));
1460 }
1461
GetLineHeight(const JSCallbackInfo & info)1462 void JSLineHeightSpan::GetLineHeight(const JSCallbackInfo& info)
1463 {
1464 CHECK_NULL_VOID(lineHeightSpan_);
1465 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(lineHeightSpan_->GetLineHeight().ConvertToVp())));
1466 info.SetReturnValue(ret);
1467 }
1468
SetLineHeight(const JSCallbackInfo & info)1469 void JSLineHeightSpan::SetLineHeight(const JSCallbackInfo& info) {}
1470
GetLineHeightSpan()1471 RefPtr<LineHeightSpan>& JSLineHeightSpan::GetLineHeightSpan()
1472 {
1473 return lineHeightSpan_;
1474 }
1475
SetLineHeightSpan(const RefPtr<LineHeightSpan> & lineHeightSpan)1476 void JSLineHeightSpan::SetLineHeightSpan(const RefPtr<LineHeightSpan>& lineHeightSpan)
1477 {
1478 lineHeightSpan_ = lineHeightSpan;
1479 }
1480
JSBind(BindingTarget globalObj)1481 void JSParagraphStyleSpan::JSBind(BindingTarget globalObj)
1482 {
1483 JSClass<JSParagraphStyleSpan>::Declare("ParagraphStyle");
1484 JSClass<JSParagraphStyleSpan>::CustomProperty(
1485 "textAlign", &JSParagraphStyleSpan::GetTextAlign, &JSParagraphStyleSpan::SetTextAlign);
1486 JSClass<JSParagraphStyleSpan>::CustomProperty(
1487 "textVerticalAlign", &JSParagraphStyleSpan::GetTextVerticalAlign, &JSParagraphStyleSpan::SetTextVerticalAlign);
1488 JSClass<JSParagraphStyleSpan>::CustomProperty(
1489 "textIndent", &JSParagraphStyleSpan::GetTextIndent, &JSParagraphStyleSpan::SetTextIndent);
1490 JSClass<JSParagraphStyleSpan>::CustomProperty(
1491 "maxLines", &JSParagraphStyleSpan::GetMaxLines, &JSParagraphStyleSpan::SetMaxLines);
1492 JSClass<JSParagraphStyleSpan>::CustomProperty(
1493 "overflow", &JSParagraphStyleSpan::GetOverflow, &JSParagraphStyleSpan::SetOverflow);
1494 JSClass<JSParagraphStyleSpan>::CustomProperty(
1495 "wordBreak", &JSParagraphStyleSpan::GetWordBreak, &JSParagraphStyleSpan::SetWordBreak);
1496 JSClass<JSParagraphStyleSpan>::CustomProperty(
1497 "leadingMargin", &JSParagraphStyleSpan::GetLeadingMargin, &JSParagraphStyleSpan::SetLeadingMargin);
1498 JSClass<JSParagraphStyleSpan>::CustomProperty(
1499 "paragraphSpacing", &JSParagraphStyleSpan::GetParagraphSpacing, &JSParagraphStyleSpan::SetParagraphSpacing);
1500 JSClass<JSParagraphStyleSpan>::Bind(globalObj, JSParagraphStyleSpan::Constructor, JSParagraphStyleSpan::Destructor);
1501 }
1502
Constructor(const JSCallbackInfo & args)1503 void JSParagraphStyleSpan::Constructor(const JSCallbackInfo& args)
1504 {
1505 auto paragraphSpan = Referenced::MakeRefPtr<JSParagraphStyleSpan>();
1506 paragraphSpan->IncRefCount();
1507
1508 RefPtr<ParagraphStyleSpan> span;
1509 if (args.Length() <= 0 || !args[0]->IsObject()) {
1510 SpanParagraphStyle paragraphStyle;
1511 span = AceType::MakeRefPtr<ParagraphStyleSpan>(paragraphStyle);
1512 } else {
1513 span = JSParagraphStyleSpan::ParseJsParagraphStyleSpan(JSRef<JSObject>::Cast(args[0]));
1514 }
1515 paragraphSpan->paragraphStyleSpan_ = span;
1516 args.SetReturnValue(Referenced::RawPtr(paragraphSpan));
1517 }
1518
Destructor(JSParagraphStyleSpan * paragragrahSpan)1519 void JSParagraphStyleSpan::Destructor(JSParagraphStyleSpan* paragragrahSpan)
1520 {
1521 if (paragragrahSpan != nullptr) {
1522 paragragrahSpan->DecRefCount();
1523 }
1524 }
1525
ParseJsParagraphStyleSpan(const JSRef<JSObject> & obj)1526 RefPtr<ParagraphStyleSpan> JSParagraphStyleSpan::ParseJsParagraphStyleSpan(const JSRef<JSObject>& obj)
1527 {
1528 SpanParagraphStyle paragraphStyle;
1529 ParseJsTextAlign(obj, paragraphStyle);
1530 ParseJsTextVerticalAlign(obj, paragraphStyle);
1531 ParseJsTextIndent(obj, paragraphStyle);
1532 ParseJsMaxLines(obj, paragraphStyle);
1533 ParseJsTextOverflow(obj, paragraphStyle);
1534 ParseJsWordBreak(obj, paragraphStyle);
1535 ParseJsLeadingMargin(obj, paragraphStyle);
1536 ParseParagraphSpacing(obj, paragraphStyle);
1537 return AceType::MakeRefPtr<ParagraphStyleSpan>(paragraphStyle);
1538 }
1539
ParseJsTextAlign(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1540 void JSParagraphStyleSpan::ParseJsTextAlign(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1541 {
1542 if (!obj->HasProperty("textAlign")) {
1543 return;
1544 }
1545 auto textAlignObj = obj->GetProperty("textAlign");
1546 int32_t value = 0;
1547 if (!textAlignObj->IsNull() && textAlignObj->IsNumber()) {
1548 value = textAlignObj->ToNumber<int32_t>();
1549 }
1550 if (value < 0 || value >= static_cast<int32_t>(TEXT_ALIGNS.size())) {
1551 value = 0;
1552 }
1553 paragraphStyle.align = TEXT_ALIGNS[value];
1554 }
1555
ParseJsTextVerticalAlign(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1556 void JSParagraphStyleSpan::ParseJsTextVerticalAlign(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1557 {
1558 if (!obj->HasProperty("textVerticalAlign")) {
1559 return;
1560 }
1561 auto textVerticalAlignObj = obj->GetProperty("textVerticalAlign");
1562 int32_t value = 0;
1563 if (!textVerticalAlignObj->IsNull() && textVerticalAlignObj->IsNumber()) {
1564 value = textVerticalAlignObj->ToNumber<int32_t>();
1565 }
1566 if (value < 0 || value >= static_cast<int32_t>(TEXT_VERTICAL_ALIGNS.size())) {
1567 value = 0;
1568 }
1569 paragraphStyle.textVerticalAlign = TEXT_VERTICAL_ALIGNS[value];
1570 }
1571
ParseJsTextIndent(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1572 void JSParagraphStyleSpan::ParseJsTextIndent(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1573 {
1574 if (!obj->HasProperty("textIndent")) {
1575 return;
1576 }
1577 auto textIndent = obj->GetProperty("textIndent");
1578 CalcDimension size;
1579 if (!textIndent->IsNull() && textIndent->IsObject()) {
1580 auto textIndentObj = JSRef<JSObject>::Cast(textIndent);
1581 auto value = 0.0;
1582 auto textIndentVal = textIndentObj->GetProperty("value");
1583 if (!textIndentVal->IsNull() && textIndentVal->IsNumber()) {
1584 value = textIndentVal->ToNumber<float>();
1585 }
1586 auto unit = DimensionUnit::VP;
1587 auto textIndentUnit = textIndentObj->GetProperty("unit");
1588 if (!textIndentUnit->IsNull() && textIndentUnit->IsNumber()) {
1589 unit = static_cast<DimensionUnit>(textIndentUnit->ToNumber<int32_t>());
1590 }
1591 if (value >= 0 && unit != DimensionUnit::PERCENT) {
1592 size = CalcDimension(value, unit);
1593 }
1594 }
1595 paragraphStyle.textIndent = size;
1596 }
1597
ParseJsMaxLines(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1598 void JSParagraphStyleSpan::ParseJsMaxLines(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1599 {
1600 if (!obj->HasProperty("maxLines")) {
1601 return;
1602 }
1603 JSRef<JSVal> args = obj->GetProperty("maxLines");
1604 int32_t value = Infinity<int32_t>();
1605 if (args->ToString() != "Infinity") {
1606 JSContainerBase::ParseJsInt32(args, value);
1607 }
1608 if (!args->IsUndefined()) {
1609 paragraphStyle.maxLines = value;
1610 }
1611 }
1612
ParseJsTextOverflow(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1613 void JSParagraphStyleSpan::ParseJsTextOverflow(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1614 {
1615 if (!obj->HasProperty("overflow")) {
1616 return;
1617 }
1618 int32_t overflow = 0;
1619 JSRef<JSVal> overflowValue = obj->GetProperty("overflow");
1620 if (overflowValue->IsNumber()) {
1621 overflow = overflowValue->ToNumber<int32_t>();
1622 }
1623 if (overflowValue->IsUndefined() || overflow < 0 || overflow >= static_cast<int32_t>(TEXT_OVERFLOWS.size())) {
1624 overflow = 0;
1625 }
1626 paragraphStyle.textOverflow = TEXT_OVERFLOWS[overflow];
1627 }
ParseJsWordBreak(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1628 void JSParagraphStyleSpan::ParseJsWordBreak(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1629 {
1630 if (!obj->HasProperty("wordBreak")) {
1631 return;
1632 }
1633 JSRef<JSVal> args = obj->GetProperty("wordBreak");
1634 int32_t index = WORD_BREAK_TYPES_DEFAULT;
1635 if (args->IsNumber()) {
1636 index = args->ToNumber<int32_t>();
1637 }
1638 if (index < 0 || index >= static_cast<int32_t>(WORD_BREAK_TYPES.size())) {
1639 index = 0;
1640 }
1641 paragraphStyle.wordBreak = WORD_BREAK_TYPES[index];
1642 }
1643
IsPixelMap(const JSRef<JSVal> & jsValue)1644 bool JSParagraphStyleSpan::IsPixelMap(const JSRef<JSVal>& jsValue)
1645 {
1646 if (!jsValue->IsObject()) {
1647 return false;
1648 }
1649 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
1650 if (jsObj->IsUndefined()) {
1651 return false;
1652 }
1653 JSRef<JSVal> func = jsObj->GetProperty("readPixelsToBuffer");
1654 return (!func->IsNull() && func->IsFunction());
1655 }
1656
ParseJsLeadingMargin(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1657 void JSParagraphStyleSpan::ParseJsLeadingMargin(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1658 {
1659 if (!obj->HasProperty("leadingMargin")) {
1660 return;
1661 }
1662 auto margin = std::make_optional<NG::LeadingMargin>();
1663 auto leadingMargin = obj->GetProperty("leadingMargin");
1664 if (!leadingMargin->IsNull() && leadingMargin->IsObject()) {
1665 JSRef<JSObject> leadingMarginObject = JSRef<JSObject>::Cast(leadingMargin);
1666 // LeadingMarginPlaceholder
1667 if (leadingMarginObject->HasProperty("pixelMap")) {
1668 ParseLeadingMarginPixelMap(leadingMarginObject, margin, leadingMargin);
1669 } else { // LengthMetrics
1670 CalcDimension width;
1671 auto value = 0.0;
1672 auto widthVal = leadingMarginObject->GetProperty("value");
1673 if (!widthVal->IsNull() && widthVal->IsNumber()) {
1674 value = widthVal->ToNumber<float>();
1675 }
1676 auto unit = DimensionUnit::VP;
1677 auto widthUnit = leadingMarginObject->GetProperty("unit");
1678 if (!widthUnit->IsNull() && widthUnit->IsNumber()) {
1679 unit = static_cast<DimensionUnit>(widthUnit->ToNumber<int32_t>());
1680 }
1681 if (value >= 0 && unit != DimensionUnit::PERCENT) {
1682 width = CalcDimension(value, unit);
1683 }
1684 margin->size = NG::LeadingMarginSize(width, Dimension(0.0, width.Unit()));
1685 }
1686 }
1687 paragraphStyle.leadingMargin = margin;
1688 }
1689
ParseParagraphSpacing(const JSRef<JSObject> & obj,SpanParagraphStyle & paragraphStyle)1690 void JSParagraphStyleSpan::ParseParagraphSpacing(const JSRef<JSObject>& obj, SpanParagraphStyle& paragraphStyle)
1691 {
1692 if (!obj->HasProperty("paragraphSpacing")) {
1693 return;
1694 }
1695 auto paragraphSpacing = obj->GetProperty("paragraphSpacing");
1696 CalcDimension size;
1697 if (!paragraphSpacing->IsNull() && paragraphSpacing->IsObject()) {
1698 auto paragraphSpacingObj = JSRef<JSObject>::Cast(paragraphSpacing);
1699 auto value = 0.0;
1700 auto paragraphSpacingVal = paragraphSpacingObj->GetProperty("value");
1701 if (!paragraphSpacingVal->IsNull() && paragraphSpacingVal->IsNumber()) {
1702 value = paragraphSpacingVal->ToNumber<float>();
1703 }
1704 auto unit = DimensionUnit::VP;
1705 auto paragraphSpacingUnit = paragraphSpacingObj->GetProperty("unit");
1706 if (!paragraphSpacingUnit->IsNull() && paragraphSpacingUnit->IsNumber()) {
1707 unit = static_cast<DimensionUnit>(paragraphSpacingUnit->ToNumber<int32_t>());
1708 }
1709 if (value >= 0 && unit != DimensionUnit::PERCENT) {
1710 size = CalcDimension(value, unit);
1711 }
1712 }
1713 paragraphStyle.paragraphSpacing = size;
1714 }
1715
ParseLeadingMarginPixelMap(const JSRef<JSObject> & leadingMarginObject,std::optional<NG::LeadingMargin> & margin,const JsiRef<JsiValue> & leadingMargin)1716 void JSParagraphStyleSpan::ParseLeadingMarginPixelMap(const JSRef<JSObject>& leadingMarginObject,
1717 std::optional<NG::LeadingMargin>& margin, const JsiRef<JsiValue>& leadingMargin)
1718 {
1719 JSRef<JSVal> placeholder = leadingMarginObject->GetProperty("pixelMap");
1720 if (IsPixelMap(placeholder)) {
1721 #if defined(PIXEL_MAP_SUPPORTED)
1722 auto pixelMap = CreatePixelMapFromNapiValue(placeholder);
1723 margin->pixmap = pixelMap;
1724 #endif
1725 }
1726 JSRef<JSVal> sizeVal = leadingMarginObject->GetProperty("size");
1727 if (!sizeVal->IsUndefined() && sizeVal->IsArray()) {
1728 auto rangeArray = JSRef<JSArray>::Cast(sizeVal);
1729 JSRef<JSVal> widthVal = rangeArray->GetValueAt(0);
1730 JSRef<JSVal> heightVal = rangeArray->GetValueAt(1);
1731 CalcDimension width;
1732 CalcDimension height;
1733 JSContainerBase::ParseJsDimensionVp(widthVal, width);
1734 JSContainerBase::ParseJsDimensionVp(heightVal, height);
1735 if (LessNotEqual(width.Value(), 0.0)) {
1736 width = Dimension(0.0, width.Unit());
1737 }
1738 if (LessNotEqual(height.Value(), 0.0)) {
1739 height = Dimension(0.0, height.Unit());
1740 }
1741 margin->size = NG::LeadingMarginSize(width, height);
1742 } else if (sizeVal->IsUndefined()) {
1743 std::string resWidthStr;
1744 if (JSContainerBase::ParseJsString(leadingMargin, resWidthStr)) {
1745 CalcDimension width;
1746 JSContainerBase::ParseJsDimensionVp(leadingMargin, width);
1747 margin->size = NG::LeadingMarginSize(width, Dimension(0.0, width.Unit()));
1748 }
1749 }
1750 }
1751
GetTextAlign(const JSCallbackInfo & info)1752 void JSParagraphStyleSpan::GetTextAlign(const JSCallbackInfo& info)
1753 {
1754 CHECK_NULL_VOID(paragraphStyleSpan_);
1755 if (!paragraphStyleSpan_->GetParagraphStyle().align.has_value()) {
1756 return;
1757 }
1758 auto ret = JSRef<JSVal>::Make(
1759 JSVal(ToJSValue(static_cast<int32_t>(paragraphStyleSpan_->GetParagraphStyle().align.value()))));
1760 info.SetReturnValue(ret);
1761 }
1762
SetTextAlign(const JSCallbackInfo & info)1763 void JSParagraphStyleSpan::SetTextAlign(const JSCallbackInfo& info) {}
1764
GetTextVerticalAlign(const JSCallbackInfo & info)1765 void JSParagraphStyleSpan::GetTextVerticalAlign(const JSCallbackInfo& info)
1766 {
1767 CHECK_NULL_VOID(paragraphStyleSpan_);
1768 if (!paragraphStyleSpan_->GetParagraphStyle().textVerticalAlign.has_value()) {
1769 return;
1770 }
1771 auto ret = JSRef<JSVal>::Make(
1772 JSVal(ToJSValue(static_cast<int32_t>(paragraphStyleSpan_->GetParagraphStyle().textVerticalAlign.value()))));
1773 info.SetReturnValue(ret);
1774 }
1775
SetTextVerticalAlign(const JSCallbackInfo & info)1776 void JSParagraphStyleSpan::SetTextVerticalAlign(const JSCallbackInfo& info) {}
1777
GetTextIndent(const JSCallbackInfo & info)1778 void JSParagraphStyleSpan::GetTextIndent(const JSCallbackInfo& info)
1779 {
1780 CHECK_NULL_VOID(paragraphStyleSpan_);
1781 if (!paragraphStyleSpan_->GetParagraphStyle().textIndent.has_value()) {
1782 return;
1783 }
1784 auto ret =
1785 JSRef<JSVal>::Make(JSVal(ToJSValue(paragraphStyleSpan_->GetParagraphStyle().textIndent.value().ConvertToVp())));
1786 info.SetReturnValue(ret);
1787 }
1788
SetTextIndent(const JSCallbackInfo & info)1789 void JSParagraphStyleSpan::SetTextIndent(const JSCallbackInfo& info) {}
1790
GetMaxLines(const JSCallbackInfo & info)1791 void JSParagraphStyleSpan::GetMaxLines(const JSCallbackInfo& info)
1792 {
1793 CHECK_NULL_VOID(paragraphStyleSpan_);
1794 if (!paragraphStyleSpan_->GetParagraphStyle().maxLines.has_value()) {
1795 return;
1796 }
1797 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(paragraphStyleSpan_->GetParagraphStyle().maxLines.value())));
1798 info.SetReturnValue(ret);
1799 }
SetMaxLines(const JSCallbackInfo & info)1800 void JSParagraphStyleSpan::SetMaxLines(const JSCallbackInfo& info) {}
1801
GetOverflow(const JSCallbackInfo & info)1802 void JSParagraphStyleSpan::GetOverflow(const JSCallbackInfo& info)
1803 {
1804 CHECK_NULL_VOID(paragraphStyleSpan_);
1805 if (!paragraphStyleSpan_->GetParagraphStyle().textOverflow.has_value()) {
1806 return;
1807 }
1808 auto ret = JSRef<JSVal>::Make(
1809 JSVal(ToJSValue(static_cast<int32_t>(paragraphStyleSpan_->GetParagraphStyle().textOverflow.value()))));
1810 info.SetReturnValue(ret);
1811 }
SetOverflow(const JSCallbackInfo & info)1812 void JSParagraphStyleSpan::SetOverflow(const JSCallbackInfo& info) {}
1813
GetWordBreak(const JSCallbackInfo & info)1814 void JSParagraphStyleSpan::GetWordBreak(const JSCallbackInfo& info)
1815 {
1816 CHECK_NULL_VOID(paragraphStyleSpan_);
1817 if (!paragraphStyleSpan_->GetParagraphStyle().wordBreak.has_value()) {
1818 return;
1819 }
1820 auto ret = JSRef<JSVal>::Make(
1821 JSVal(ToJSValue(static_cast<int32_t>(paragraphStyleSpan_->GetParagraphStyle().wordBreak.value()))));
1822 info.SetReturnValue(ret);
1823 }
SetWordBreak(const JSCallbackInfo & info)1824 void JSParagraphStyleSpan::SetWordBreak(const JSCallbackInfo& info) {}
1825
GetLeadingMargin(const JSCallbackInfo & info)1826 void JSParagraphStyleSpan::GetLeadingMargin(const JSCallbackInfo& info)
1827 {
1828 CHECK_NULL_VOID(paragraphStyleSpan_);
1829 if (!paragraphStyleSpan_->GetParagraphStyle().leadingMargin.has_value()) {
1830 return;
1831 }
1832 auto leadingMargin = paragraphStyleSpan_->GetParagraphStyle().leadingMargin.value();
1833 JSRef<JSVal> ret;
1834 #ifdef PIXEL_MAP_SUPPORTED
1835 if (leadingMargin.pixmap) {
1836 auto lmObj = JSRef<JSObject>::New();
1837 auto size = JSRef<JSArray>::New();
1838 size->SetValueAt(0, JSRef<JSVal>::Make(ToJSValue(Dimension(leadingMargin.size.Width()).ConvertToVp())));
1839 size->SetValueAt(1, JSRef<JSVal>::Make(ToJSValue(Dimension(leadingMargin.size.Height()).ConvertToVp())));
1840 lmObj->SetPropertyObject("pixelMap", ConvertPixmap(leadingMargin.pixmap));
1841 lmObj->SetPropertyObject("size", size);
1842 ret = JSRef<JSVal>::Cast(lmObj);
1843 } else {
1844 ret = JSRef<JSVal>::Make(JSVal(ToJSValue(Dimension(leadingMargin.size.Width()).ConvertToVp())));
1845 }
1846 #else
1847 ret = JSRef<JSVal>::Make(JSVal(ToJSValue(Dimension(leadingMargin.size.Width()).ConvertToVp())));
1848 #endif
1849 info.SetReturnValue(ret);
1850 }
1851
SetLeadingMargin(const JSCallbackInfo & info)1852 void JSParagraphStyleSpan::SetLeadingMargin(const JSCallbackInfo& info) {}
1853
GetParagraphSpacing(const JSCallbackInfo & info)1854 void JSParagraphStyleSpan::GetParagraphSpacing(const JSCallbackInfo& info)
1855 {
1856 CHECK_NULL_VOID(paragraphStyleSpan_);
1857 auto paragraphSpacing = paragraphStyleSpan_->GetParagraphStyle().paragraphSpacing;
1858 CHECK_EQUAL_VOID(paragraphSpacing.has_value(), false);
1859 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(paragraphSpacing.value().ConvertToVp())));
1860 info.SetReturnValue(ret);
1861 }
1862
SetParagraphSpacing(const JSCallbackInfo & info)1863 void JSParagraphStyleSpan::SetParagraphSpacing(const JSCallbackInfo& info) {}
1864
GetParagraphStyleSpan()1865 RefPtr<ParagraphStyleSpan>& JSParagraphStyleSpan::GetParagraphStyleSpan()
1866 {
1867 return paragraphStyleSpan_;
1868 }
1869
SetParagraphStyleSpan(const RefPtr<ParagraphStyleSpan> & paragraphStyleSpan)1870 void JSParagraphStyleSpan::SetParagraphStyleSpan(const RefPtr<ParagraphStyleSpan>& paragraphStyleSpan)
1871 {
1872 paragraphStyleSpan_ = paragraphStyleSpan;
1873 }
1874
1875 // JSExtSpan
JSExtSpan(JSRef<JSObject> extSpanObj)1876 JSExtSpan::JSExtSpan(JSRef<JSObject> extSpanObj) : extSpanObj_(extSpanObj) {}
1877
JSExtSpan(JSRef<JSObject> extSpanObj,int32_t start,int32_t end)1878 JSExtSpan::JSExtSpan(JSRef<JSObject> extSpanObj, int32_t start, int32_t end)
1879 : ExtSpan(start, end), extSpanObj_(extSpanObj)
1880 {}
1881
GetSubSpan(int32_t start,int32_t end)1882 RefPtr<SpanBase> JSExtSpan::GetSubSpan(int32_t start, int32_t end)
1883 {
1884 RefPtr<SpanBase> spanBase = MakeRefPtr<JSExtSpan>(extSpanObj_, start, end);
1885 return spanBase;
1886 }
1887
IsAttributesEqual(const RefPtr<SpanBase> & other) const1888 bool JSExtSpan::IsAttributesEqual(const RefPtr<SpanBase>& other) const
1889 {
1890 auto extSpan = DynamicCast<JSExtSpan>(other);
1891 if (!extSpan) {
1892 return false;
1893 }
1894 return (extSpan->extSpanObj_)
1895 ->GetLocalHandle()
1896 ->IsStrictEquals(extSpanObj_->GetEcmaVM(), extSpanObj_->GetLocalHandle());
1897 }
1898
SetJsExtSpanObject(const JSRef<JSObject> & extSpanObj)1899 void JSExtSpan::SetJsExtSpanObject(const JSRef<JSObject>& extSpanObj)
1900 {
1901 extSpanObj_ = extSpanObj;
1902 }
1903
GetJsExtSpanObject()1904 JSRef<JSObject>& JSExtSpan::GetJsExtSpanObject()
1905 {
1906 return extSpanObj_;
1907 }
1908
JSBind(BindingTarget globalObj)1909 void JSBackgroundColorSpan::JSBind(BindingTarget globalObj)
1910 {
1911 JSClass<JSBackgroundColorSpan>::Declare("BackgroundColorStyle");
1912 JSClass<JSBackgroundColorSpan>::CustomProperty(
1913 "textBackgroundStyle", &JSBackgroundColorSpan::GetBackgroundColor, &JSBackgroundColorSpan::SetBackgroundColor);
1914 JSClass<JSBackgroundColorSpan>::Bind(
1915 globalObj, JSBackgroundColorSpan::Constructor, JSBackgroundColorSpan::Destructor);
1916 }
1917
Constructor(const JSCallbackInfo & args)1918 void JSBackgroundColorSpan::Constructor(const JSCallbackInfo& args)
1919 {
1920 auto backgroundColor = Referenced::MakeRefPtr<JSBackgroundColorSpan>();
1921 CHECK_NULL_VOID(backgroundColor);
1922 backgroundColor->IncRefCount();
1923 RefPtr<BackgroundColorSpan> span;
1924 if (args.Length() <= 0 || !args[0]->IsObject()) {
1925 span = AceType::MakeRefPtr<BackgroundColorSpan>();
1926 } else {
1927 span = JSBackgroundColorSpan::ParseJSBackgroundColorSpan(args);
1928 }
1929 CHECK_NULL_VOID(span);
1930 backgroundColor->backgroundColorSpan_ = span;
1931 args.SetReturnValue(Referenced::RawPtr(backgroundColor));
1932 }
1933
Destructor(JSBackgroundColorSpan * backgroundColor)1934 void JSBackgroundColorSpan::Destructor(JSBackgroundColorSpan* backgroundColor)
1935 {
1936 if (backgroundColor != nullptr) {
1937 backgroundColor->DecRefCount();
1938 }
1939 }
1940
ParseJSBackgroundColorSpan(const JSCallbackInfo & info)1941 RefPtr<BackgroundColorSpan> JSBackgroundColorSpan::ParseJSBackgroundColorSpan(const JSCallbackInfo& info)
1942 {
1943 auto textBackgroundValue = JSContainerSpan::ParseTextBackgroundStyle(info);
1944 return AceType::MakeRefPtr<BackgroundColorSpan>(textBackgroundValue);
1945 }
1946
GetBackgroundColor(const JSCallbackInfo & info)1947 void JSBackgroundColorSpan::GetBackgroundColor(const JSCallbackInfo& info)
1948 {
1949 CHECK_NULL_VOID(backgroundColorSpan_);
1950 auto backgroundColorStyle = backgroundColorSpan_->GetBackgroundColor();
1951 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
1952 objectTemplate->SetInternalFieldCount(1);
1953 JSRef<JSObject> backgroundColorObj = objectTemplate->NewInstance();
1954 backgroundColorObj->SetProperty<std::string>("color", backgroundColorStyle.backgroundColor->ColorToString());
1955 backgroundColorObj->SetProperty<std::string>(
1956 "BorderRadiusProperty", backgroundColorStyle.backgroundRadius->ToString());
1957 info.SetReturnValue(backgroundColorObj);
1958 }
1959
SetBackgroundColor(const JSCallbackInfo & info)1960 void JSBackgroundColorSpan::SetBackgroundColor(const JSCallbackInfo& info) {};
1961
GetBackgroundColorSpan()1962 RefPtr<BackgroundColorSpan>& JSBackgroundColorSpan::GetBackgroundColorSpan()
1963 {
1964 return backgroundColorSpan_;
1965 }
1966
SetBackgroundColorSpan(const RefPtr<BackgroundColorSpan> & backgroundColorSpan)1967 void JSBackgroundColorSpan::SetBackgroundColorSpan(const RefPtr<BackgroundColorSpan>& backgroundColorSpan)
1968 {
1969 backgroundColorSpan_ = backgroundColorSpan;
1970 }
1971
1972 // JSUrlSpan
JSBind(BindingTarget globalObj)1973 void JSUrlSpan::JSBind(BindingTarget globalObj)
1974 {
1975 JSClass<JSUrlSpan>::Declare("UrlStyle");
1976 JSClass<JSUrlSpan>::CustomProperty(
1977 "url", &JSUrlSpan::GetUrlContext, &JSUrlSpan::SetUrlContext);
1978 JSClass<JSUrlSpan>::Bind(globalObj, JSUrlSpan::Constructor, JSUrlSpan::Destructor);
1979 }
1980
Constructor(const JSCallbackInfo & args)1981 void JSUrlSpan::Constructor(const JSCallbackInfo& args)
1982 {
1983 auto urlSpan = Referenced::MakeRefPtr<JSUrlSpan>();
1984 urlSpan->IncRefCount();
1985 RefPtr<UrlSpan> span;
1986 if (args.Length() > 0 && args[0]->IsString()) {
1987 auto address = args[0]->ToString();
1988 span = AceType::MakeRefPtr<UrlSpan>(address);
1989 } else {
1990 span = AceType::MakeRefPtr<UrlSpan>();
1991 }
1992 CHECK_NULL_VOID(span);
1993 urlSpan->urlContextSpan_ = span;
1994 args.SetReturnValue(Referenced::RawPtr(urlSpan));
1995 }
1996
Destructor(JSUrlSpan * urlSpan)1997 void JSUrlSpan::Destructor(JSUrlSpan* urlSpan)
1998 {
1999 if (urlSpan != nullptr) {
2000 urlSpan->DecRefCount();
2001 }
2002 }
2003
GetUrlContext(const JSCallbackInfo & info)2004 void JSUrlSpan::GetUrlContext(const JSCallbackInfo& info)
2005 {
2006 CHECK_NULL_VOID(urlContextSpan_);
2007 auto ret = JSRef<JSVal>::Make(JSVal(ToJSValue(urlContextSpan_->GetUrlSpanAddress())));
2008 info.SetReturnValue(ret);
2009 }
2010
SetUrlContext(const JSCallbackInfo & info)2011 void JSUrlSpan::SetUrlContext(const JSCallbackInfo& info) {}
2012
GetUrlSpan()2013 const RefPtr<UrlSpan>& JSUrlSpan::GetUrlSpan()
2014 {
2015 return urlContextSpan_;
2016 }
2017
SetUrlSpan(const RefPtr<UrlSpan> & urlSpan)2018 void JSUrlSpan::SetUrlSpan(const RefPtr<UrlSpan>& urlSpan)
2019 {
2020 urlContextSpan_ = urlSpan;
2021 }
2022 } // namespace OHOS::Ace::Framework