1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "core/interfaces/native/node/node_image_span_modifier.h"
16
17 #include "core/components/image/image_component.h"
18 #include "core/components_ng/pattern/image/image_model_ng.h"
19 #include "core/components_ng/pattern/text/image_span_view.h"
20
21 namespace OHOS::Ace::NG {
22 namespace {
23 constexpr int NUM_0 = 0;
24 constexpr int NUM_1 = 1;
25 constexpr int NUM_2 = 2;
26 constexpr int NUM_3 = 3;
27 constexpr int DEFAULT_LENGTH = 4;
28 constexpr int32_t LOAD_ERROR_CODE = 401;
29 constexpr int32_t IMAGE_LOAD_STATUS_INDEX = 0;
30 constexpr int32_t IMAGE_WIDTH_INDEX = 1;
31 constexpr int32_t IMAGE_HEIGHT_INDEX = 2;
32 constexpr int32_t IMAGE_COMPONENT_WIDTH_INDEX = 3;
33 constexpr int32_t IMAGE_COMPONENT_HEIGHT_INDEX = 4;
34 constexpr int32_t IMAGE_CONTENT_OFFSET_X_INDEX = 5;
35 constexpr int32_t IMAGE_CONTENT_OFFSET_Y_INDEX = 6;
36 constexpr int32_t IMAGE_CONTENT_WIDTH_INDEX = 7;
37 constexpr int32_t IMAGE_CONTENT_HEIGHT_INDEX = 8;
38 constexpr VerticalAlign DEFAULT_VERTICAL_ALIGN = VerticalAlign::BOTTOM;
39 constexpr ImageFit DEFAULT_OBJECT_FIT = ImageFit::COVER;
40 constexpr Dimension DEFAULT_BASELINE_OFFSET { 0.0, DimensionUnit::FP };
41 const std::vector<float> DEFAULT_COLOR_FILTER = {
42 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
43 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
44 };
45
SetImageSpanVerticalAlign(ArkUINodeHandle node,int32_t value)46 void SetImageSpanVerticalAlign(ArkUINodeHandle node, int32_t value)
47 {
48 auto* frameNode = reinterpret_cast<FrameNode*>(node);
49 CHECK_NULL_VOID(frameNode);
50 ImageSpanView::SetVerticalAlign(frameNode, static_cast<VerticalAlign>(value));
51 }
52
GetImageSpanVerticalAlign(ArkUINodeHandle node)53 int32_t GetImageSpanVerticalAlign(ArkUINodeHandle node)
54 {
55 auto* frameNode = reinterpret_cast<FrameNode*>(node);
56 CHECK_NULL_RETURN(frameNode, static_cast<int32_t>(DEFAULT_VERTICAL_ALIGN));
57 return static_cast<int32_t>(ImageSpanView::GetVerticalAlign(frameNode));
58 }
59
ResetImageSpanVerticalAlign(ArkUINodeHandle node)60 void ResetImageSpanVerticalAlign(ArkUINodeHandle node)
61 {
62 auto* frameNode = reinterpret_cast<FrameNode*>(node);
63 CHECK_NULL_VOID(frameNode);
64 ImageSpanView::SetVerticalAlign(frameNode, DEFAULT_VERTICAL_ALIGN);
65 }
66
SetImageSpanObjectFit(ArkUINodeHandle node,int32_t value)67 void SetImageSpanObjectFit(ArkUINodeHandle node, int32_t value)
68 {
69 auto* frameNode = reinterpret_cast<FrameNode*>(node);
70 CHECK_NULL_VOID(frameNode);
71 ImageModelNG::SetImageFit(frameNode, static_cast<ImageFit>(value));
72 }
73
GetImageSpanObjectFit(ArkUINodeHandle node)74 int32_t GetImageSpanObjectFit(ArkUINodeHandle node)
75 {
76 int32_t defaultObjectFit = static_cast<int32_t>(DEFAULT_OBJECT_FIT);
77 auto* frameNode = reinterpret_cast<FrameNode*>(node);
78 CHECK_NULL_RETURN(frameNode, defaultObjectFit);
79 return static_cast<int32_t>(ImageModelNG::GetObjectFit(frameNode));
80 }
81
ResetImageSpanObjectFit(ArkUINodeHandle node)82 void ResetImageSpanObjectFit(ArkUINodeHandle node)
83 {
84 auto* frameNode = reinterpret_cast<FrameNode*>(node);
85 CHECK_NULL_VOID(frameNode);
86 ImageModelNG::SetImageFit(frameNode, DEFAULT_OBJECT_FIT);
87 }
88
SetImageSpanTextBackgroundStyle(ArkUINodeHandle node,ArkUI_Uint32 color,const ArkUI_Float32 * values,const ArkUI_Int32 * units,ArkUI_Int32 length,void * style)89 void SetImageSpanTextBackgroundStyle(
90 ArkUINodeHandle node, ArkUI_Uint32 color, const ArkUI_Float32* values, const ArkUI_Int32* units, ArkUI_Int32 length,
91 void* style)
92 {
93 auto* frameNode = reinterpret_cast<FrameNode*>(node);
94 CHECK_NULL_VOID(frameNode);
95 if (length != DEFAULT_LENGTH) {
96 return;
97 }
98 if (SystemProperties::ConfigChangePerform() && style) {
99 auto textBackgroundStyle = reinterpret_cast<TextBackgroundStyle*>(style);
100 ImageSpanView::SetPlaceHolderStyle(frameNode, *textBackgroundStyle);
101 return;
102 }
103 TextBackgroundStyle font;
104 NG::BorderRadiusProperty borderRadius;
105 borderRadius.radiusTopLeft = Dimension(values[NUM_0], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_0]));
106 borderRadius.radiusTopRight = Dimension(values[NUM_1], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_1]));
107 borderRadius.radiusBottomLeft = Dimension(values[NUM_2], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_2]));
108 borderRadius.radiusBottomRight = Dimension(values[NUM_3], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_3]));
109 font.backgroundColor = Color(color);
110 font.backgroundRadius = borderRadius;
111 font.backgroundRadius->multiValued = true;
112 ImageSpanView::SetPlaceHolderStyle(frameNode, font);
113 }
114
ResetImageSpanTextBackgroundStyle(ArkUINodeHandle node)115 void ResetImageSpanTextBackgroundStyle(ArkUINodeHandle node)
116 {
117 auto* frameNode = reinterpret_cast<FrameNode*>(node);
118 CHECK_NULL_VOID(frameNode);
119 TextBackgroundStyle font;
120 NG::BorderRadiusProperty borderRadius;
121 borderRadius.radiusTopLeft = Dimension(0, OHOS::Ace::DimensionUnit::VP);
122 borderRadius.radiusTopRight = Dimension(0, OHOS::Ace::DimensionUnit::VP);
123 borderRadius.radiusBottomLeft = Dimension(0, OHOS::Ace::DimensionUnit::VP);
124 borderRadius.radiusBottomRight = Dimension(0, OHOS::Ace::DimensionUnit::VP);
125 font.backgroundColor = Color(0x00000000);
126 font.backgroundRadius = borderRadius;
127 font.backgroundRadius->multiValued = true;
128 ImageSpanView::SetPlaceHolderStyle(frameNode, font);
129 }
130
GetImageSpanTextBackgroundStyle(ArkUINodeHandle node,ArkUITextBackgroundStyleOptions * options)131 void GetImageSpanTextBackgroundStyle(ArkUINodeHandle node, ArkUITextBackgroundStyleOptions* options)
132 {
133 auto* frameNode = reinterpret_cast<FrameNode*>(node);
134 CHECK_NULL_VOID(frameNode);
135 auto styleOptions = ImageSpanView::GetSpanTextBackgroundStyle(frameNode);
136 options->color = styleOptions.backgroundColor->GetValue();
137 options->topLeft = styleOptions.backgroundRadius->radiusTopLeft->Value();
138 options->topRight = styleOptions.backgroundRadius->radiusTopRight->Value();
139 options->bottomLeft = styleOptions.backgroundRadius->radiusBottomLeft->Value();
140 options->bottomRight = styleOptions.backgroundRadius->radiusBottomRight->Value();
141 }
142
SetImageSpanBaselineOffset(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit)143 void SetImageSpanBaselineOffset(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit)
144 {
145 auto* frameNode = reinterpret_cast<FrameNode*>(node);
146 CHECK_NULL_VOID(frameNode);
147 ImageSpanView::SetBaselineOffset(frameNode, CalcDimension(value, (DimensionUnit)unit));
148 }
149
ResetImageSpanBaselineOffset(ArkUINodeHandle node)150 void ResetImageSpanBaselineOffset(ArkUINodeHandle node)
151 {
152 auto* frameNode = reinterpret_cast<FrameNode*>(node);
153 CHECK_NULL_VOID(frameNode);
154 ImageSpanView::SetBaselineOffset(frameNode, DEFAULT_BASELINE_OFFSET);
155 }
156
GetImageSpanBaselineOffset(ArkUINodeHandle node,ArkUI_Int32 unit)157 float GetImageSpanBaselineOffset(ArkUINodeHandle node, ArkUI_Int32 unit)
158 {
159 auto* frameNode = reinterpret_cast<FrameNode*>(node);
160 CHECK_NULL_RETURN(frameNode, 0.0f);
161 return ImageSpanView::GetBaselineOffset(frameNode, unit);
162 }
163
SetImageSpanOnComplete(ArkUINodeHandle node,void * callback)164 void SetImageSpanOnComplete(ArkUINodeHandle node, void *callback)
165 {
166 auto* frameNode = reinterpret_cast<FrameNode*>(node);
167 CHECK_NULL_VOID(frameNode);
168 if (callback) {
169 auto onComplete = reinterpret_cast<std::function<void(const LoadImageSuccessEvent&)>*>(callback);
170 ImageSpanView::SetOnComplete(frameNode, std::move(*onComplete));
171 } else {
172 ImageSpanView::SetOnComplete(frameNode, nullptr);
173 }
174 }
175
ResetImageSpanOnComplete(ArkUINodeHandle node)176 void ResetImageSpanOnComplete(ArkUINodeHandle node)
177 {
178 auto* frameNode = reinterpret_cast<FrameNode*>(node);
179 CHECK_NULL_VOID(frameNode);
180 ImageSpanView::SetOnComplete(frameNode, nullptr);
181 }
182
SetImageSpanOnError(ArkUINodeHandle node,void * callback)183 void SetImageSpanOnError(ArkUINodeHandle node, void *callback)
184 {
185 auto* frameNode = reinterpret_cast<FrameNode*>(node);
186 CHECK_NULL_VOID(frameNode);
187 if (callback) {
188 auto onError = reinterpret_cast<std::function<void(const LoadImageFailEvent&)>*>(callback);
189 ImageSpanView::SetOnError(frameNode, std::move(*onError));
190 } else {
191 ImageSpanView::SetOnError(frameNode, nullptr);
192 }
193 }
194
ResetImageSpanOnError(ArkUINodeHandle node)195 void ResetImageSpanOnError(ArkUINodeHandle node)
196 {
197 auto* frameNode = reinterpret_cast<FrameNode*>(node);
198 CHECK_NULL_VOID(frameNode);
199 ImageSpanView::SetOnError(frameNode, nullptr);
200 }
201
202 /**
203 * @param values radius values
204 * value[0] : radius value for TopLeft,value[1] : radius value for TopRight
205 * value[2] : radius value for BottomLeft,value[3] : radius value for BottomRight
206 * @param units radius units
207 * units[0]: radius unit for TopLeft ,units[1] : radius unit for TopRight
208 * units[2]: radius unit for BottomLeft, units[3] : radius unit for TopRight
209 */
SetImageSpanBorderRadius(ArkUINodeHandle node,const ArkUI_Float32 * values,const ArkUI_Int32 * units,ArkUI_Int32 length)210 void SetImageSpanBorderRadius(ArkUINodeHandle node, const ArkUI_Float32* values,
211 const ArkUI_Int32* units, ArkUI_Int32 length)
212 {
213 auto* frameNode = reinterpret_cast<FrameNode*>(node);
214 CHECK_NULL_VOID(frameNode);
215 if (length != DEFAULT_LENGTH) {
216 return;
217 }
218 NG::BorderRadiusProperty borderRadius;
219 borderRadius.radiusTopLeft = Dimension(values[NUM_0], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_0]));
220 borderRadius.radiusTopRight = Dimension(values[NUM_1], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_1]));
221 borderRadius.radiusBottomLeft = Dimension(values[NUM_2], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_2]));
222 borderRadius.radiusBottomRight = Dimension(values[NUM_3], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_3]));
223 borderRadius.multiValued = true;
224 ImageSpanView::SetBorderRadius(frameNode, borderRadius);
225 }
226
ResetImageSpanBorderRadius(ArkUINodeHandle node)227 void ResetImageSpanBorderRadius(ArkUINodeHandle node)
228 {
229 auto* frameNode = reinterpret_cast<FrameNode*>(node);
230 CHECK_NULL_VOID(frameNode);
231 ImageSpanView::ResetBorderRadius(frameNode);
232 }
233
SetImageSpanColorFilter(ArkUINodeHandle node,const ArkUI_Float32 * array,int length)234 void SetImageSpanColorFilter(ArkUINodeHandle node, const ArkUI_Float32* array, int length)
235 {
236 CHECK_NULL_VOID(array);
237 if (length != COLOR_FILTER_MATRIX_SIZE) {
238 return;
239 }
240 auto* frameNode = reinterpret_cast<FrameNode*>(node);
241 CHECK_NULL_VOID(frameNode);
242 ImageModelNG::SetColorFilterMatrix(frameNode, std::vector<float>(array, array + length));
243 }
244
ResetImageSpanColorFilter(ArkUINodeHandle node)245 void ResetImageSpanColorFilter(ArkUINodeHandle node)
246 {
247 auto* frameNode = reinterpret_cast<FrameNode*>(node);
248 CHECK_NULL_VOID(frameNode);
249 ImageModelNG::SetColorFilterMatrix(frameNode, DEFAULT_COLOR_FILTER);
250 }
251
SetImageSpanSrc(ArkUINodeHandle node,ArkUI_CharPtr src,ArkUI_CharPtr bundleName,ArkUI_CharPtr moduleName,ArkUI_Bool isUriPureNumber)252 void SetImageSpanSrc(ArkUINodeHandle node, ArkUI_CharPtr src, ArkUI_CharPtr bundleName, ArkUI_CharPtr moduleName,
253 ArkUI_Bool isUriPureNumber)
254 {
255 auto* frameNode = reinterpret_cast<FrameNode*>(node);
256 CHECK_NULL_VOID(frameNode);
257 ImageSpanView::SetSrc(frameNode, src, bundleName, moduleName, isUriPureNumber);
258 }
259 } // namespace
260
261 namespace NodeModifier {
GetImageSpanModifier()262 const ArkUIImageSpanModifier* GetImageSpanModifier()
263 {
264 CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
265 static const ArkUIImageSpanModifier modifier = {
266 .setImageSpanVerticalAlign = SetImageSpanVerticalAlign,
267 .resetImageSpanVerticalAlign = ResetImageSpanVerticalAlign,
268 .setImageSpanObjectFit = SetImageSpanObjectFit,
269 .resetImageSpanObjectFit = ResetImageSpanObjectFit,
270 .getImageSpanVerticalAlign = GetImageSpanVerticalAlign,
271 .getImageSpanObjectFit = GetImageSpanObjectFit,
272 .setImageSpanTextBackgroundStyle = SetImageSpanTextBackgroundStyle,
273 .resetImageSpanTextBackgroundStyle = ResetImageSpanTextBackgroundStyle,
274 .getImageSpanTextBackgroundStyle = GetImageSpanTextBackgroundStyle,
275 .setImageSpanBaselineOffset = SetImageSpanBaselineOffset,
276 .resetImageSpanBaselineOffset = ResetImageSpanBaselineOffset,
277 .setImageSpanOnComplete = SetImageSpanOnComplete,
278 .resetImageSpanOnComplete = ResetImageSpanOnComplete,
279 .setImageSpanOnError = SetImageSpanOnError,
280 .resetImageSpanOnError = ResetImageSpanOnError,
281 .setImageSpanBorderRadius = SetImageSpanBorderRadius,
282 .resetImageSpanBorderRadius = ResetImageSpanBorderRadius,
283 .setImageSpanColorFilter = SetImageSpanColorFilter,
284 .resetImageSpanColorFilter = ResetImageSpanColorFilter,
285 .getImageSpanBaselineOffset = GetImageSpanBaselineOffset,
286 .setImageSpanSrc = SetImageSpanSrc,
287 };
288 CHECK_INITIALIZED_FIELDS_END(modifier, 0, 0, 0); // don't move this line
289 return &modifier;
290 }
291
GetCJUIImageSpanModifier()292 const CJUIImageSpanModifier* GetCJUIImageSpanModifier()
293 {
294 CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
295 static const CJUIImageSpanModifier modifier = {
296 .setImageSpanVerticalAlign = SetImageSpanVerticalAlign,
297 .resetImageSpanVerticalAlign = ResetImageSpanVerticalAlign,
298 .setImageSpanObjectFit = SetImageSpanObjectFit,
299 .resetImageSpanObjectFit = ResetImageSpanObjectFit,
300 .getImageSpanVerticalAlign = GetImageSpanVerticalAlign,
301 .getImageSpanObjectFit = GetImageSpanObjectFit,
302 .setImageSpanTextBackgroundStyle = SetImageSpanTextBackgroundStyle,
303 .resetImageSpanTextBackgroundStyle = ResetImageSpanTextBackgroundStyle,
304 .getImageSpanTextBackgroundStyle = GetImageSpanTextBackgroundStyle,
305 .setImageSpanBaselineOffset = SetImageSpanBaselineOffset,
306 .resetImageSpanBaselineOffset = ResetImageSpanBaselineOffset,
307 .setImageSpanOnComplete = SetImageSpanOnComplete,
308 .resetImageSpanOnComplete = ResetImageSpanOnComplete,
309 .setImageSpanOnError = SetImageSpanOnError,
310 .resetImageSpanOnError = ResetImageSpanOnError,
311 .setImageSpanSrc = SetImageSpanSrc,
312 };
313 CHECK_INITIALIZED_FIELDS_END(modifier, 0, 0, 0); // don't move this line
314 return &modifier;
315 }
316
SetImageSpanOnCompleteEvent(ArkUINodeHandle node,void * extraParam)317 void SetImageSpanOnCompleteEvent(ArkUINodeHandle node, void* extraParam)
318 {
319 auto* frameNode = reinterpret_cast<FrameNode*>(node);
320 CHECK_NULL_VOID(frameNode);
321 auto onEvent = [node, extraParam](const LoadImageSuccessEvent& info) {
322 ArkUINodeEvent event;
323 event.kind = COMPONENT_ASYNC_EVENT;
324 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
325 event.componentAsyncEvent.subKind = ON_IMAGE_SPAN_COMPLETE;
326 event.componentAsyncEvent.data[IMAGE_LOAD_STATUS_INDEX].i32 = info.GetLoadingStatus();
327 event.componentAsyncEvent.data[IMAGE_WIDTH_INDEX].f32 = info.GetWidth();
328 event.componentAsyncEvent.data[IMAGE_HEIGHT_INDEX].f32 = info.GetHeight();
329 event.componentAsyncEvent.data[IMAGE_COMPONENT_WIDTH_INDEX].f32 = info.GetComponentWidth();
330 event.componentAsyncEvent.data[IMAGE_COMPONENT_HEIGHT_INDEX].f32 = info.GetComponentHeight();
331 event.componentAsyncEvent.data[IMAGE_CONTENT_OFFSET_X_INDEX].f32 = info.GetContentOffsetX();
332 event.componentAsyncEvent.data[IMAGE_CONTENT_OFFSET_Y_INDEX].f32 = info.GetContentOffsetY();
333 event.componentAsyncEvent.data[IMAGE_CONTENT_WIDTH_INDEX].f32 = info.GetContentWidth();
334 event.componentAsyncEvent.data[IMAGE_CONTENT_HEIGHT_INDEX].f32 = info.GetContentHeight();
335 SendArkUISyncEvent(&event);
336 };
337 ImageSpanView::SetOnComplete(frameNode, std::move(onEvent));
338 }
339
SetImageSpanOnErrorEvent(ArkUINodeHandle node,void * extraParam)340 void SetImageSpanOnErrorEvent(ArkUINodeHandle node, void* extraParam)
341 {
342 auto* frameNode = reinterpret_cast<FrameNode*>(node);
343 CHECK_NULL_VOID(frameNode);
344 auto onEvent = [node, extraParam](const LoadImageFailEvent& info) {
345 ArkUINodeEvent event;
346 event.kind = COMPONENT_ASYNC_EVENT;
347 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
348 event.componentAsyncEvent.subKind = ON_IMAGE_SPAN_ERROR;
349 event.componentAsyncEvent.data[0].i32 = LOAD_ERROR_CODE;
350 SendArkUISyncEvent(&event);
351 };
352 ImageSpanView::SetOnError(frameNode, std::move(onEvent));
353 }
354 } // namespace NodeModifier
355 } // namespace OHOS::Ace::NG
356