1 /*
2 * Copyright (c) 2021-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
16 #include "frameworks/bridge/common/utils/utils.h"
17
18 #include <unordered_set>
19
20 #include "base/utils/string_utils.h"
21 #include "frameworks/bridge/js_frontend/engine/common/js_constants.h"
22
23 namespace OHOS::Ace::Framework {
24
25 namespace {
26
27 using CustomCurveCreator = RefPtr<Curve> (*)(const std::vector<std::string>&);
28
29 const size_t STEPS_PARAMS_SIZE = 2;
30 const size_t CUBIC_PARAMS_SIZE = 4;
31 const size_t SPRING_PARAMS_SIZE = 4;
32 constexpr size_t RESPONSIVE_SPRING_MOTION_PARAMS_SIZE = 3;
33 constexpr size_t INTERPOLATING_SPRING_PARAMS_SIZE = 4;
34
35 static const std::unordered_set<std::string> HORIZON_SET = {
36 DOM_BACKGROUND_IMAGE_POSITION_LEFT,
37 DOM_BACKGROUND_IMAGE_POSITION_RIGHT,
38 };
39 static const std::unordered_set<std::string> VERTICAL_SET = {
40 DOM_BACKGROUND_IMAGE_POSITION_TOP,
41 DOM_BACKGROUND_IMAGE_POSITION_BOTTOM,
42 };
43 static const std::unordered_set<std::string> OBJECT_HORIZON_SET = {
44 DOM_IMAGE_POSITION_LEFT,
45 DOM_IMAGE_POSITION_RIGHT,
46 };
47 static const std::unordered_set<std::string> OBJECT_VERTICAL_SET = {
48 DOM_IMAGE_POSITION_TOP,
49 DOM_IMAGE_POSITION_BOTTOM,
50 };
51
StepsCurveCreator(const std::vector<std::string> & params)52 RefPtr<Curve> StepsCurveCreator(const std::vector<std::string>& params)
53 {
54 if (params.empty() || params.size() > STEPS_PARAMS_SIZE) {
55 LOGE("steps curve accept 1 or 2 parameter(s), current size is %zu.", params.size());
56 return nullptr;
57 }
58 auto step = StringUtils::StringToInt(params.front());
59 if (step <= 0) {
60 LOGE("step number is illegal: %{public}d", step);
61 return nullptr;
62 }
63 StepsCurvePosition position = StepsCurvePosition::END;
64 if (params.size() > 1) {
65 if (params.back() == "start") {
66 position = StepsCurvePosition::START;
67 } else if (params.back() == "end") {
68 position = StepsCurvePosition::END;
69 } else {
70 LOGE("step position is illegal: %{public}s", params.back().c_str());
71 return nullptr;
72 }
73 }
74 return AceType::MakeRefPtr<StepsCurve>(step, position);
75 }
76
CubicCurveCreator(const std::vector<std::string> & params)77 RefPtr<Curve> CubicCurveCreator(const std::vector<std::string>& params)
78 {
79 if (params.size() != CUBIC_PARAMS_SIZE) {
80 LOGE("cubic curve accept 4 parameters");
81 return nullptr;
82 }
83 double x1 = StringToDouble(params.at(0));
84 double y1 = StringToDouble(params.at(1));
85 double x2 = StringToDouble(params.at(2));
86 double y2 = StringToDouble(params.at(3));
87 return AceType::MakeRefPtr<CubicCurve>(x1, y1, x2, y2);
88 }
89
SpringCurveCreator(const std::vector<std::string> & params)90 RefPtr<Curve> SpringCurveCreator(const std::vector<std::string>& params)
91 {
92 if (params.size() != SPRING_PARAMS_SIZE) {
93 LOGE("spring curve accept 4 parameters");
94 return nullptr;
95 }
96 double velocity = StringToDouble(params.at(0));
97 double mass = StringToDouble(params.at(1));
98 double stiffness = StringToDouble(params.at(2));
99 double damping = StringToDouble(params.at(3));
100 return AceType::MakeRefPtr<SpringCurve>(velocity, mass, stiffness, damping);
101 }
102
InterpolatingSpringCreator(const std::vector<std::string> & params)103 RefPtr<Curve> InterpolatingSpringCreator(const std::vector<std::string>& params)
104 {
105 if (params.size() != INTERPOLATING_SPRING_PARAMS_SIZE) {
106 LOGE("interpolating spring accept 4 parameters");
107 return nullptr;
108 }
109 double velocity = StringToDouble(params.at(0));
110 double mass = StringToDouble(params.at(1));
111 double stiffness = StringToDouble(params.at(2));
112 double damping = StringToDouble(params.at(3));
113 return AceType::MakeRefPtr<InterpolatingSpring>(velocity, mass, stiffness, damping);
114 }
115
SpringMotionCreator(const std::vector<std::string> & params)116 RefPtr<Curve> SpringMotionCreator(const std::vector<std::string>& params)
117 {
118 if (params.size() > RESPONSIVE_SPRING_MOTION_PARAMS_SIZE) {
119 LOGW("spring motion accept at most 3 params");
120 return nullptr;
121 }
122 size_t paramSize = params.size();
123 float response = paramSize > 0 ? StringUtils::StringToFloat(params[0])
124 : ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_RESPONSE;
125 float dampingRatio = paramSize > 1 ? StringUtils::StringToFloat(params[1])
126 : ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_DAMPING_RATIO;
127 float blendDuration = paramSize > 2 ? StringUtils::StringToFloat(params[2])
128 : ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_BLEND_DURATION;
129 return AceType::MakeRefPtr<ResponsiveSpringMotion>(response, dampingRatio, blendDuration);
130 }
131
ResponsiveSpringMotionCreator(const std::vector<std::string> & params)132 RefPtr<Curve> ResponsiveSpringMotionCreator(const std::vector<std::string>& params)
133 {
134 if (params.size() > RESPONSIVE_SPRING_MOTION_PARAMS_SIZE) {
135 LOGW("responsive spring motion accept at most 3 params");
136 return nullptr;
137 }
138 size_t paramSize = params.size();
139 float response = paramSize > 0 ? StringUtils::StringToFloat(params[0])
140 : ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_RESPONSE;
141 float dampingRatio = paramSize > 1 ? StringUtils::StringToFloat(params[1])
142 : ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_DAMPING_RATIO;
143 float blendDuration = paramSize > 2 ? StringUtils::StringToFloat(params[2])
144 : ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_BLEND_DURATION;
145 return AceType::MakeRefPtr<ResponsiveSpringMotion>(response, dampingRatio, blendDuration);
146 }
147 #ifndef FUZZTEST
SetBgImgPositionX(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)148 void SetBgImgPositionX(
149 const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
150 {
151 bgImgPosition.SetSizeTypeX(type);
152 bgImgPosition.SetSizeValueX(value);
153 }
154
SetBgImgPositionY(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)155 void SetBgImgPositionY(
156 const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
157 {
158 bgImgPosition.SetSizeTypeY(type);
159 bgImgPosition.SetSizeValueY(value);
160 }
161
SetBgImgPosition(const BackgroundImagePositionType type,const double value,BackgroundImagePosition & bgImgPosition)162 void SetBgImgPosition(
163 const BackgroundImagePositionType type, const double value, BackgroundImagePosition& bgImgPosition)
164 {
165 SetBgImgPositionX(type, value, bgImgPosition);
166 SetBgImgPositionY(type, value, bgImgPosition);
167 }
168
GetOffsetValue(std::vector<std::string> offsets,std::string & posX,std::string & posY)169 void GetOffsetValue(std::vector<std::string> offsets, std::string& posX, std::string& posY)
170 {
171 if (offsets.size() == 1) {
172 posX = offsets.front();
173 if (VERTICAL_SET.find(posX) != VERTICAL_SET.end()) {
174 posY = offsets.front();
175 posX = DOM_BACKGROUND_IMAGE_POSITION_CENTER;
176 } else {
177 posY = DOM_BACKGROUND_IMAGE_POSITION_CENTER;
178 }
179 } else {
180 posX = offsets.front();
181 posY = offsets.back();
182 if (VERTICAL_SET.find(posX) != VERTICAL_SET.end() && HORIZON_SET.find(posY) != HORIZON_SET.end()) {
183 posY = offsets.front();
184 posX = offsets.back();
185 }
186 }
187 }
188
189 // object-position check msg number
GetOffsetValueObjectPosition(std::vector<std::string> offsets,std::string & posX,std::string & posY)190 void GetOffsetValueObjectPosition(std::vector<std::string> offsets, std::string& posX, std::string& posY)
191 {
192 if (offsets.size() == 1) {
193 posX = offsets.front();
194 if (OBJECT_VERTICAL_SET.find(posX) != OBJECT_VERTICAL_SET.end()) {
195 posY = offsets.front();
196 posX = DOM_IMAGE_POSITION_CENTER;
197 } else {
198 posY = DOM_IMAGE_POSITION_CENTER;
199 }
200 } else {
201 posX = offsets.front();
202 posY = offsets.back();
203 if (OBJECT_VERTICAL_SET.find(posX) != OBJECT_VERTICAL_SET.end()
204 && OBJECT_HORIZON_SET.find(posY) != OBJECT_HORIZON_SET.end()) {
205 posY = offsets.front();
206 posX = offsets.back();
207 }
208 }
209 }
210
BgImgPositionIsValid(const std::string & posX,const std::string & posY)211 bool BgImgPositionIsValid(const std::string& posX, const std::string& posY)
212 {
213 if ((posX == DOM_BACKGROUND_IMAGE_POSITION_CENTER) || (posY == DOM_BACKGROUND_IMAGE_POSITION_CENTER)) {
214 return true;
215 }
216 // posX and posY are not strictly corresponding to horizontal or vertical, but they must not conflict,
217 // for example both of them are "top" is invalid.
218 if (posX.find("px") != std::string::npos || posX.find('%') != std::string::npos ||
219 HORIZON_SET.find(posX) != HORIZON_SET.end()) {
220 if (posY.find("px") != std::string::npos || posY.find('%') != std::string::npos ||
221 VERTICAL_SET.find(posY) != VERTICAL_SET.end()) {
222 return true;
223 }
224 }
225 return VERTICAL_SET.find(posX) != VERTICAL_SET.end() && HORIZON_SET.find(posY) != HORIZON_SET.end();
226 }
227
228 // objectPosition
ObjectImgPositionIsValid(const std::string & posX,const std::string & posY)229 bool ObjectImgPositionIsValid(const std::string& posX, const std::string& posY)
230 {
231 if (posX.find("px") != std::string::npos || posX.find('%') != std::string::npos ||
232 OBJECT_HORIZON_SET.find(posX) != OBJECT_HORIZON_SET.end() || posX != DOM_IMAGE_POSITION_CENTER) {
233 if (posY.find("px") != std::string::npos || posY.find('%') != std::string::npos ||
234 OBJECT_VERTICAL_SET.find(posY) != OBJECT_VERTICAL_SET.end() || posY != DOM_IMAGE_POSITION_CENTER) {
235 return true;
236 }
237 }
238 return false;
239 }
240
SetBgImgSizeX(BackgroundImageSizeType type,double value,BackgroundImageSize & bgImgSize)241 void SetBgImgSizeX(BackgroundImageSizeType type, double value, BackgroundImageSize& bgImgSize)
242 {
243 bgImgSize.SetSizeTypeX(type);
244 bgImgSize.SetSizeValueX(value);
245 }
246
SetBgImgSizeY(BackgroundImageSizeType type,double value,BackgroundImageSize & bgImgSize)247 void SetBgImgSizeY(BackgroundImageSizeType type, double value, BackgroundImageSize& bgImgSize)
248 {
249 bgImgSize.SetSizeTypeY(type);
250 bgImgSize.SetSizeValueY(value);
251 }
252 #endif
253 } // namespace
254
CreateBuiltinCurve(const std::string & aniTimFunc)255 RefPtr<Curve> CreateBuiltinCurve(const std::string& aniTimFunc)
256 {
257 // this map should be sorted by key
258 static const LinearMapNode<RefPtr<Curve>> aniTimFuncMap[] = {
259 { DOM_ANIMATION_TIMING_FUNCTION_EASE, Curves::EASE },
260 { DOM_ANIMATION_TIMING_FUNCTION_EASE_IN, Curves::EASE_IN },
261 { DOM_ANIMATION_TIMING_FUNCTION_EASE_IN_OUT, Curves::EASE_IN_OUT },
262 { DOM_ANIMATION_TIMING_FUNCTION_EASE_OUT, Curves::EASE_OUT },
263 { DOM_ANIMATION_TIMING_FUNCTION_EXTREME_DECELERATION, Curves::EXTREME_DECELERATION },
264 { DOM_ANIMATION_TIMING_FUNCTION_FAST_OUT_LINEAR_IN, Curves::FAST_OUT_LINEAR_IN },
265 { DOM_ANIMATION_TIMING_FUNCTION_FAST_OUT_SLOW_IN, Curves::FAST_OUT_SLOW_IN },
266 { DOM_ANIMATION_TIMING_FUNCTION_FRICTION, Curves::FRICTION },
267 { DOM_ANIMATION_TIMING_FUNCTION_LINEAR, Curves::LINEAR },
268 { DOM_ANIMATION_TIMING_FUNCTION_LINEAR_OUT_SLOW_IN, Curves::LINEAR_OUT_SLOW_IN },
269 { DOM_ANIMATION_TIMING_FUNCTION_RHYTHM, Curves::RHYTHM },
270 { DOM_ANIMATION_TIMING_FUNCTION_SHARP, Curves::SHARP },
271 { DOM_ANIMATION_TIMING_FUNCTION_SMOOTH, Curves::SMOOTH },
272 };
273 auto index = BinarySearchFindIndex(aniTimFuncMap, ArraySize(aniTimFuncMap), aniTimFunc.c_str());
274 return index < 0 ? nullptr : aniTimFuncMap[index].value;
275 }
276
CreateCustomCurve(const std::string & aniTimFunc)277 RefPtr<Curve> CreateCustomCurve(const std::string& aniTimFunc)
278 {
279 if (aniTimFunc.back() != ')') {
280 LOGE("last character must be right embrace.");
281 return nullptr;
282 }
283 std::string::size_type leftEmbracePosition = aniTimFunc.find_last_of('(');
284 if (leftEmbracePosition == std::string::npos) {
285 LOGE("left embrace not found.");
286 return nullptr;
287 }
288 auto aniTimFuncName = aniTimFunc.substr(0, leftEmbracePosition);
289 auto params = aniTimFunc.substr(leftEmbracePosition + 1, aniTimFunc.length() - leftEmbracePosition - 2);
290 if (aniTimFuncName.empty() || params.empty()) {
291 LOGE("no easing function name, or no parameters.");
292 return nullptr;
293 }
294 std::vector<std::string> paramsVector;
295 StringUtils::StringSplitter(params, ',', paramsVector);
296 for (auto& param : paramsVector) {
297 RemoveHeadTailSpace(param);
298 }
299 static const LinearMapNode<CustomCurveCreator> customCurveMap[] = {
300 { DOM_ANIMATION_TIMING_FUNCTION_CUBIC_BEZIER, CubicCurveCreator },
301 { DOM_ANIMATION_TIMING_FUNCTION_INTERPOLATING_SPRING, InterpolatingSpringCreator },
302 { DOM_ANIMATION_TIMING_FUNCTION_RESPONSIVE_SPRING_MOTION, ResponsiveSpringMotionCreator },
303 { DOM_ANIMATION_TIMING_FUNCTION_SPRING, SpringCurveCreator },
304 { DOM_ANIMATION_TIMING_FUNCTION_SPRING_MOTION, SpringMotionCreator },
305 { DOM_ANIMATION_TIMING_FUNCTION_STEPS, StepsCurveCreator },
306 };
307 int64_t index = BinarySearchFindIndex(customCurveMap, ArraySize(customCurveMap), aniTimFuncName.c_str());
308 if (index < 0) {
309 LOGE("no valid creator found for easing function: %{public}s", aniTimFuncName.c_str());
310 return nullptr;
311 }
312 return customCurveMap[index].value(paramsVector);
313 }
CreateCurve(const std::function<float (float)> & jsFunc)314 RefPtr<Curve> CreateCurve(const std::function<float(float)>& jsFunc)
315 {
316 if (jsFunc) {
317 return AceType::MakeRefPtr<CustomCurve>(jsFunc);
318 }
319 return Curves::EASE_IN_OUT;
320 }
321
CreateCurve(const std::string & aniTimFunc,bool useDefault)322 RefPtr<Curve> CreateCurve(const std::string& aniTimFunc, bool useDefault)
323 {
324 auto curve = CreateBuiltinCurve(aniTimFunc);
325 if (curve) {
326 return curve;
327 }
328 curve = CreateCustomCurve(aniTimFunc);
329 if (curve) {
330 return curve;
331 }
332 return useDefault? Curves::EASE_IN_OUT : nullptr;
333 }
334
335 // used for declarative only
ParseTransitionType(const std::string & transitionType)336 TransitionType ParseTransitionType(const std::string& transitionType)
337 {
338 if (transitionType == "All") {
339 return TransitionType::ALL;
340 } else if (transitionType == "Insert") {
341 return TransitionType::APPEARING;
342 } else if (transitionType == "Delete") {
343 return TransitionType::DISAPPEARING;
344 } else {
345 return TransitionType::ALL;
346 }
347 }
348 #ifndef FUZZTEST
349 // Support keyword values / percentage/px values. Do not support multiple images and edge offsets values.
ParseBackgroundImagePosition(const std::string & value,BackgroundImagePosition & backgroundImagePosition)350 bool ParseBackgroundImagePosition(const std::string& value, BackgroundImagePosition& backgroundImagePosition)
351 {
352 static const LinearMapNode<void (*)(BackgroundImagePosition&)> backGroundPositionOperators[] = {
353 { DOM_BACKGROUND_IMAGE_POSITION_BOTTOM,
354 [](BackgroundImagePosition& backgroundImagePosition) {
355 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 100.0, backgroundImagePosition);
356 } },
357 { DOM_BACKGROUND_IMAGE_POSITION_LEFT,
358 [](BackgroundImagePosition& backgroundImagePosition) {
359 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 0.0, backgroundImagePosition);
360 } },
361 { DOM_BACKGROUND_IMAGE_POSITION_RIGHT,
362 [](BackgroundImagePosition& backgroundImagePosition) {
363 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 100.0, backgroundImagePosition);
364 } },
365 { DOM_BACKGROUND_IMAGE_POSITION_TOP,
366 [](BackgroundImagePosition& backgroundImagePosition) {
367 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 0.0, backgroundImagePosition);
368 } },
369 };
370
371 std::vector<std::string> offsets;
372 StringUtils::StringSplitter(value, ' ', offsets);
373 if (!offsets.empty()) {
374 std::string valueX = "";
375 std::string valueY = "";
376 GetOffsetValue(offsets, valueX, valueY);
377 if (!BgImgPositionIsValid(valueX, valueY)) {
378 return false;
379 }
380 // The input is valid,so set the default is (center,center),
381 // if the value is different, the default value is overwritten.
382 // the center value is 50%.
383 SetBgImgPosition(BackgroundImagePositionType::PERCENT, 50.0, backgroundImagePosition);
384 if (valueX.find("px") != std::string::npos) {
385 SetBgImgPositionX(BackgroundImagePositionType::PX, StringToDouble(valueX), backgroundImagePosition);
386 } else if (valueX.find('%') != std::string::npos) {
387 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, StringToDouble(valueX), backgroundImagePosition);
388 } else {
389 auto operatorIterX = BinarySearchFindIndex(
390 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueX.c_str());
391 if (operatorIterX != -1) {
392 backGroundPositionOperators[operatorIterX].value(backgroundImagePosition);
393 }
394 }
395 if (valueY.find("px") != std::string::npos) {
396 SetBgImgPositionY(BackgroundImagePositionType::PX, StringToDouble(valueY), backgroundImagePosition);
397 } else if (valueY.find('%') != std::string::npos) {
398 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, StringToDouble(valueY), backgroundImagePosition);
399 } else {
400 auto operatorIterY = BinarySearchFindIndex(
401 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueY.c_str());
402 if (operatorIterY != -1) {
403 backGroundPositionOperators[operatorIterY].value(backgroundImagePosition);
404 }
405 }
406 } else {
407 SetBgImgPosition(BackgroundImagePositionType::PERCENT, 50.0, backgroundImagePosition);
408 if (value.find("px") != std::string::npos) {
409 SetBgImgPositionX(BackgroundImagePositionType::PX, StringToDouble(value), backgroundImagePosition);
410 } else if (value.find('%') != std::string::npos) {
411 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, StringToDouble(value), backgroundImagePosition);
412 } else {
413 auto operatorIter = BinarySearchFindIndex(
414 backGroundPositionOperators, ArraySize(backGroundPositionOperators), value.c_str());
415 if (operatorIter != -1) {
416 backGroundPositionOperators[operatorIter].value(backgroundImagePosition);
417 }
418 }
419 }
420 return true;
421 }
422
ParseBackgroundImageSize(const std::string & value,BackgroundImageSize & bgImgSize)423 bool ParseBackgroundImageSize(const std::string& value, BackgroundImageSize& bgImgSize)
424 {
425 static const LinearMapNode<BackgroundImageSizeType> bgImageSizeType[] = {
426 { DOM_BACKGROUND_IMAGE_SIZE_AUTO, BackgroundImageSizeType::AUTO },
427 { DOM_BACKGROUND_IMAGE_SIZE_CONTAIN, BackgroundImageSizeType::CONTAIN },
428 { DOM_BACKGROUND_IMAGE_SIZE_COVER, BackgroundImageSizeType::COVER },
429 };
430 auto spaceIndex = value.find(' ', 0);
431 if (spaceIndex != std::string::npos) {
432 std::string valueX = value.substr(0, spaceIndex);
433 std::string valueY = value.substr(spaceIndex + 1, value.size() - spaceIndex - 1);
434 if (valueX.find("px") != std::string::npos) {
435 SetBgImgSizeX(BackgroundImageSizeType::LENGTH, StringToDouble(valueX), bgImgSize);
436 } else if (valueX.find('%') != std::string::npos) {
437 SetBgImgSizeX(BackgroundImageSizeType::PERCENT, StringToDouble(valueX), bgImgSize);
438 } else {
439 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
440 }
441 if (valueY.find("px") != std::string::npos) {
442 SetBgImgSizeY(BackgroundImageSizeType::LENGTH, StringToDouble(valueY), bgImgSize);
443 } else if (valueY.find('%') != std::string::npos) {
444 SetBgImgSizeY(BackgroundImageSizeType::PERCENT, StringToDouble(valueY), bgImgSize);
445 } else {
446 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
447 }
448 } else {
449 auto sizeTypeIter = BinarySearchFindIndex(bgImageSizeType, ArraySize(bgImageSizeType), value.c_str());
450 if (sizeTypeIter != -1) {
451 bgImgSize.SetSizeTypeX(bgImageSizeType[sizeTypeIter].value);
452 bgImgSize.SetSizeTypeY(bgImageSizeType[sizeTypeIter].value);
453 } else if (value.find("px") != std::string::npos) {
454 SetBgImgSizeX(BackgroundImageSizeType::LENGTH, StringToDouble(value), bgImgSize);
455 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
456 } else if (value.find('%') != std::string::npos) {
457 SetBgImgSizeX(BackgroundImageSizeType::PERCENT, StringToDouble(value), bgImgSize);
458 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
459 } else {
460 bgImgSize.SetSizeTypeX(BackgroundImageSizeType::AUTO);
461 bgImgSize.SetSizeTypeY(BackgroundImageSizeType::AUTO);
462 }
463 }
464 return true;
465 }
466 #endif
CreateClipPath(const std::string & value)467 RefPtr<ClipPath> CreateClipPath(const std::string& value)
468 {
469 if (value.empty()) {
470 return nullptr;
471 }
472 auto clipPath = ClipPath::CreateShape(value);
473 GeometryBoxType geometryBoxType = ClipPath::GetGeometryBoxType(value);
474 if (geometryBoxType != GeometryBoxType::NONE) {
475 if (!clipPath) {
476 clipPath = AceType::MakeRefPtr<ClipPath>();
477 }
478 }
479 if (clipPath) {
480 clipPath->SetGeometryBoxType(geometryBoxType);
481 }
482 return clipPath;
483 }
484
ParseRadialGradientSize(const std::string & value)485 std::optional<RadialSizeType> ParseRadialGradientSize(const std::string& value)
486 {
487 const static std::unordered_map<std::string, RadialSizeType> sizeTypes = {
488 { DOM_GRADIENT_SIZE_CLOSEST_CORNER, RadialSizeType::CLOSEST_CORNER },
489 { DOM_GRADIENT_SIZE_CLOSEST_SIDE, RadialSizeType::CLOSEST_SIDE },
490 { DOM_GRADIENT_SIZE_FARTHEST_CORNER, RadialSizeType::FARTHEST_CORNER },
491 { DOM_GRADIENT_SIZE_FARTHEST_SIDE, RadialSizeType::FARTHEST_SIDE },
492 };
493 if (!value.empty()) {
494 auto pos = sizeTypes.find(value);
495 if (pos != sizeTypes.end()) {
496 return std::make_optional(pos->second);
497 }
498 }
499 return std::nullopt;
500 }
501 #ifndef FUZZTEST
502 // ObjectPosition
ParseImageObjectPosition(const std::string & value)503 ImageObjectPosition ParseImageObjectPosition(const std::string& value)
504 {
505 ImageObjectPosition imageObjectPosition;
506 static const LinearMapNode<void (*)(ImageObjectPosition&)> backGroundPositionOperators[] = {
507 { DOM_IMAGE_POSITION_BOTTOM,
508 [](ImageObjectPosition& imageObjectPosition) {
509 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 100.0, imageObjectPosition);
510 } },
511 { DOM_IMAGE_POSITION_LEFT,
512 [](ImageObjectPosition& imageObjectPosition) {
513 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 0.0, imageObjectPosition);
514 } },
515 { DOM_IMAGE_POSITION_RIGHT,
516 [](ImageObjectPosition& imageObjectPosition) {
517 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, 100.0, imageObjectPosition);
518 } },
519 { DOM_IMAGE_POSITION_TOP,
520 [](ImageObjectPosition& imageObjectPosition) {
521 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, 0.0, imageObjectPosition);
522 } },
523 };
524
525 std::vector<std::string> offsets;
526 StringUtils::StringSplitter(value, ' ', offsets);
527 if (!offsets.empty()) {
528 std::string valueX = "";
529 std::string valueY = "";
530 GetOffsetValueObjectPosition(offsets, valueX, valueY);
531 SetBgImgPosition(BackgroundImagePositionType::PERCENT, 50.0, imageObjectPosition);
532 if (ObjectImgPositionIsValid(valueX, valueY)) {
533 if (valueX.find("px") != std::string::npos) {
534 SetBgImgPositionX(BackgroundImagePositionType::PX, StringToDouble(valueX), imageObjectPosition);
535 } else if (valueX.find('%') != std::string::npos) {
536 SetBgImgPositionX(BackgroundImagePositionType::PERCENT, StringToDouble(valueX), imageObjectPosition);
537 } else {
538 auto operatorIterX = BinarySearchFindIndex(
539 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueX.c_str());
540 if (operatorIterX != -1) {
541 backGroundPositionOperators[operatorIterX].value(imageObjectPosition);
542 }
543 }
544 if (valueY.find("px") != std::string::npos) {
545 SetBgImgPositionY(BackgroundImagePositionType::PX, StringToDouble(valueY), imageObjectPosition);
546 } else if (valueY.find('%') != std::string::npos) {
547 SetBgImgPositionY(BackgroundImagePositionType::PERCENT, StringToDouble(valueY), imageObjectPosition);
548 } else {
549 auto operatorIterY = BinarySearchFindIndex(
550 backGroundPositionOperators, ArraySize(backGroundPositionOperators), valueY.c_str());
551 if (operatorIterY != -1) {
552 backGroundPositionOperators[operatorIterY].value(imageObjectPosition);
553 }
554 }
555 }
556 }
557
558 return imageObjectPosition;
559 }
560 #endif
561
562 } // namespace OHOS::Ace::Framework