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