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