• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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