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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_DECORATION_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_DECORATION_H
18 
19 #include <memory>
20 #include <optional>
21 #include <regex>
22 #include <vector>
23 
24 #include "base/geometry/dimension.h"
25 #include "base/geometry/rect.h"
26 #include "base/json/json_util.h"
27 #include "base/memory/ace_type.h"
28 #include "base/utils/macros.h"
29 #include "base/utils/utils.h"
30 #include "core/components/common/properties/alignment.h"
31 #include "core/components/common/properties/animatable_color.h"
32 #include "core/components/common/properties/blend_mode.h"
33 #include "core/components/common/properties/border.h"
34 #include "core/components/common/properties/border_image.h"
35 #include "core/components/common/properties/color.h"
36 #include "core/components/common/properties/common_decoration.h"
37 #include "core/components/common/properties/edge.h"
38 #include "core/components/common/properties/invert.h"
39 #include "core/components/common/properties/outline_style.h"
40 #include "core/components/common/properties/shadow.h"
41 #include "core/components/theme/theme_utils.h"
42 #include "core/components_ng/base/inspector_filter.h"
43 #include "core/pipeline/pipeline_context.h"
44 
45 namespace OHOS::Ace {
46 
47 constexpr double CENTER_OFFSET = 50.0;
48 constexpr double FULL_IMG_SIZE = 100.0;
49 constexpr double BOX_BEGIN_SIZE = 0.0;
50 constexpr double BOX_END_SIZE = 100.0;
51 constexpr double PERCENT_TRANSLATE = 100.0;
52 
53 enum class GradientDirection {
54     LEFT = 0,
55     TOP,
56     RIGHT,
57     BOTTOM,
58     LEFT_TOP,
59     LEFT_BOTTOM,
60     RIGHT_TOP,
61     RIGHT_BOTTOM,
62     NONE,
63     START_TO_END,
64     END_TO_START,
65 };
66 
67 enum class GradientType {
68     LINEAR,
69     RADIAL,
70     SWEEP,
71     CONIC,
72 };
73 
74 enum class RadialSizeType {
75     CLOSEST_SIDE,
76     CLOSEST_CORNER,
77     FARTHEST_SIDE,
78     FARTHEST_CORNER,
79     NONE,
80 };
81 
82 enum class RadialShapeType {
83     CIRCLE,
84     ELLIPSE,
85     NONE,
86 };
87 
88 enum class SpreadMethod {
89     PAD,
90     REFLECT,
91     REPEAT,
92 };
93 
94 
95 enum class ThemeColorMode {
96     SYSTEM = 0,
97     LIGHT,
98     DARK,
99 };
100 
101 struct MotionBlurAnchor {
102     float x = 0.0f;
103     float y = 0.0f;
104     bool operator==(const MotionBlurAnchor& other) const
105     {
106         return NearEqual(x, other.x) && NearEqual(y, other.y);
107     }
108     bool operator!=(const MotionBlurAnchor& other) const
109     {
110         return !operator==(other);
111     }
112 };
113 
114 struct MotionBlurOption {
115     float radius = 0.0f;
116     MotionBlurAnchor anchor;
117     bool operator==(const MotionBlurOption& other) const
118     {
119         return NearEqual(radius, other.radius) && anchor == other.anchor;
120     }
121     bool operator!=(const MotionBlurOption& other) const
122     {
123         return !operator==(other);
124     }
125 };
126 
127 struct BlurStyleOption {
128     BlurStyle blurStyle = BlurStyle::NO_MATERIAL;
129     ThemeColorMode colorMode = ThemeColorMode::SYSTEM;
130     AdaptiveColor adaptiveColor = AdaptiveColor::DEFAULT;
131     double scale = 1.0;
132     BlurOption blurOption;
133     BlurStyleActivePolicy policy = BlurStyleActivePolicy::ALWAYS_ACTIVE;
134     BlurType blurType = BlurType::WITHIN_WINDOW;
135     Color inactiveColor { Color::TRANSPARENT };
136     bool isValidColor = false;
137     bool isWindowFocused = true;
138     bool operator==(const BlurStyleOption& other) const
139     {
140         return blurStyle == other.blurStyle && colorMode == other.colorMode && adaptiveColor == other.adaptiveColor &&
141                NearEqual(scale, other.scale) && policy == other.policy && blurType == other.blurType &&
142                inactiveColor == other.inactiveColor && isValidColor == other.isValidColor &&
143                isWindowFocused == other.isWindowFocused;
144     }
ToJsonValueBlurStyleOption145     void ToJsonValue(std::unique_ptr<JsonValue>& json, const NG::InspectorFilter& filter) const
146     {
147         /* no fixed attr below, just return */
148         if (filter.IsFastFilter()) {
149             return;
150         }
151         static const char* STYLE[] = { "BlurStyle.NONE", "BlurStyle.Thin", "BlurStyle.Regular", "BlurStyle.Thick",
152             "BlurStyle.BACKGROUND_THIN", "BlurStyle.BACKGROUND_REGULAR", "BlurStyle.BACKGROUND_THICK",
153             "BlurStyle.BACKGROUND_ULTRA_THICK", "BlurStyle.COMPONENT_ULTRA_THIN", "BlurStyle.COMPONENT_THIN",
154             "BlurStyle.COMPONENT_REGULAR", "BlurStyle.COMPONENT_THICK", "BlurStyle.COMPONENT_ULTRA_THICK" };
155         static const char* COLOR_MODE[] = { "ThemeColorMode.System", "ThemeColorMode.Light", "ThemeColorMode.Dark" };
156         static const char* ADAPTIVE_COLOR[] = { "AdaptiveColor.Default", "AdaptiveColor.Average" };
157         static const char* POLICY[] = { "BlurStyleActivePolicy.FOLLOWS_WINDOW_ACTIVE_STATE",
158             "BlurStyleActivePolicy.ALWAYS_ACTIVE", "BlurStyleActivePolicy.ALWAYS_INACTIVE" };
159         static const char* BLUR_TYPE[] = { "BlurType.WITHIN_WINDOW", "BlurType.BEHIND_WINDOW" };
160         auto jsonBlurStyle = JsonUtil::Create(true);
161         jsonBlurStyle->Put("value", STYLE[static_cast<int>(blurStyle)]);
162         auto jsonBlurStyleOption = JsonUtil::Create(true);
163         jsonBlurStyleOption->Put("colorMode", COLOR_MODE[static_cast<int>(colorMode)]);
164         jsonBlurStyleOption->Put("adaptiveColor", ADAPTIVE_COLOR[static_cast<int>(adaptiveColor)]);
165         jsonBlurStyleOption->Put("policy", POLICY[static_cast<int>(policy)]);
166         jsonBlurStyleOption->Put("type", BLUR_TYPE[static_cast<int>(blurType)]);
167         jsonBlurStyleOption->Put("inactiveColor", inactiveColor.ColorToString().c_str());
168         jsonBlurStyleOption->Put("scale", scale);
169         jsonBlurStyle->Put("options", jsonBlurStyleOption);
170 
171         json->PutExtAttr("backgroundBlurStyle", jsonBlurStyle, filter);
172     }
173 };
174 
175 struct MenuPreviewAnimationOptions {
176     float scaleFrom { -1.0f };
177     float scaleTo { -1.0f };
178 };
179 
180 
181 
182 struct BrightnessOption {
183     double rate { 1.0f };
184     double lightUpDegree { 0.0f };
185     double cubicCoeff { 0.0f };
186     double quadCoeff { 0.0f };
187     double saturation { 1.0f };
188     std::vector<float> posRGB = { 0.0f, 0.0f, 0.0f };
189     std::vector<float> negRGB = { 0.0f, 0.0f, 0.0f };
190     double fraction { 1.0f };
191     bool operator==(const BrightnessOption& other) const
192     {
193         return NearEqual(rate, other.rate) && NearEqual(lightUpDegree, other.lightUpDegree) &&
194                NearEqual(cubicCoeff, other.cubicCoeff) && NearEqual(quadCoeff, other.quadCoeff) &&
195                NearEqual(saturation, other.saturation) && posRGB == other.posRGB && negRGB == other.negRGB &&
196                NearEqual(fraction, other.fraction);
197     }
ToJsonValueBrightnessOption198     void ToJsonValue(std::unique_ptr<JsonValue>& json, const NG::InspectorFilter& filter) const
199     {
200         /* no fixed attr below, just return */
201         if (filter.IsFastFilter()) {
202             return;
203         }
204         auto jsonBrightnessOption = JsonUtil::Create(true);
205         jsonBrightnessOption->Put("rate", rate);
206         jsonBrightnessOption->Put("lightUpDegree", lightUpDegree);
207         jsonBrightnessOption->Put("cubicCoeff", cubicCoeff);
208         jsonBrightnessOption->Put("quadCoeff", quadCoeff);
209         std::string posRGBstr = "[0.0,0.0,0.0]";
210         if (posRGB.size() > 1) {
211             posRGBstr =
212                 ("[" + std::to_string(posRGB[0]) + "," + std::to_string(posRGB[1]) + "," +
213                 std::to_string(posRGB[2]) + "]").c_str();
214         }
215         jsonBrightnessOption->Put("posRGB", posRGBstr.c_str());
216         std::string negRGBstr = "[0.0,0.0,0.0]";
217         if (negRGB.size() > 1) {
218             negRGBstr =
219                 ("[" + std::to_string(negRGB[0]) + "," + std::to_string(negRGB[1]) + "," +
220                 std::to_string(negRGB[2]) + "]").c_str();
221         }
222         jsonBrightnessOption->Put("negRGB", negRGBstr.c_str());
223         jsonBrightnessOption->Put("fraction", fraction);
224         json->PutExtAttr("brightnessEffect", jsonBrightnessOption, filter);
225     }
226 };
227 
228 struct PixStretchEffectOption {
229     Dimension left;
230     Dimension top;
231     Dimension right;
232     Dimension bottom;
233     bool operator==(const PixStretchEffectOption& other) const
234     {
235         return left == other.left && top == other.top && right == other.right && bottom == other.bottom;
236     }
237 
IsPercentOptionPixStretchEffectOption238     bool IsPercentOption() const
239     {
240         return (left.Unit() == DimensionUnit::PERCENT && top.Unit() == DimensionUnit::PERCENT &&
241                 right.Unit() == DimensionUnit::PERCENT && bottom.Unit() == DimensionUnit::PERCENT);
242     }
243 
ResetValuePixStretchEffectOption244     void ResetValue()
245     {
246         left = Dimension(0.0f);
247         top = Dimension(0.0f);
248         right = Dimension(0.0f);
249         bottom = Dimension(0.0f);
250     }
251 
ToStringPixStretchEffectOption252     std::string ToString() const
253     {
254         return std::string("PixStretchEffectOption (")
255             .append(left.ToString())
256             .append(",")
257             .append(top.ToString())
258             .append(",")
259             .append(right.ToString())
260             .append(",")
261             .append(bottom.ToString())
262             .append(")");
263     }
264 };
265 
266 struct LinearGradientInfo {
267     double x1 = 0.0;
268     double x2 = 0.0;
269     double y1 = 0.0;
270     double y2 = 0.0;
271 };
272 
273 struct RadialGradientInfo {
274     double r = 0.0;
275     double cx = 0.0;
276     double cy = 0.0;
277     double fx = 0.0;
278     double fy = 0.0;
279 };
280 
281 class GradientColor final {
282 public:
283     GradientColor() = default;
284     ~GradientColor() = default;
285 
GradientColor(const Color & color)286     explicit GradientColor(const Color& color)
287     {
288         color_ = color;
289     }
290 
291     void SetDimension(double value, DimensionUnit unit = DimensionUnit::PERCENT)
292     {
293         if (value < 0.0) {
294             return;
295         }
296         if (unit == DimensionUnit::PERCENT && value > BOX_END_SIZE) {
297             return;
298         }
299         dimension_ = Dimension(value, unit);
300     }
301 
SetDimension(const Dimension & dimension)302     void SetDimension(const Dimension& dimension)
303     {
304         if (dimension.Value() < 0.0) {
305             return;
306         }
307         if (dimension.Unit() == DimensionUnit::PERCENT && dimension.Value() > BOX_END_SIZE) {
308             return;
309         }
310         dimension_ = dimension;
311     }
312 
SetHasValue(bool hasValue)313     void SetHasValue(bool hasValue)
314     {
315         hasValue_ = hasValue;
316     }
317 
SetColor(const Color & color)318     void SetColor(const Color& color)
319     {
320         color_ = color;
321     }
322 
GetColor()323     const Color& GetColor() const
324     {
325         return color_;
326     }
327 
GetDimension()328     const Dimension& GetDimension() const
329     {
330         return dimension_;
331     }
332 
GetHasValue()333     bool GetHasValue() const
334     {
335         return hasValue_;
336     }
337 
SetOpacity(double opacity)338     void SetOpacity(double opacity)
339     {
340         opacity_ = opacity;
341     }
342 
GetOpacity()343     double GetOpacity() const
344     {
345         return opacity_;
346     }
347 
348 private:
349     bool hasValue_ = true;
350     Color color_ { Color::TRANSPARENT };
351     Dimension dimension_ { BOX_END_SIZE, DimensionUnit::PERCENT };
352     double opacity_ = 1.0;
353 };
354 
355 struct ACE_EXPORT RadialGradient {
356     // size type
357     std::optional<RadialSizeType> radialSizeType;
358     // shape circle or ellipse
359     std::optional<RadialShapeType> radialShape;
360     // size in x-axis
361     std::optional<AnimatableDimension> radialHorizontalSize;
362     // size in y-axis
363     std::optional<AnimatableDimension> radialVerticalSize;
364     // center of shape
365     std::optional<AnimatableDimension> radialCenterX;
366     std::optional<AnimatableDimension> radialCenterY;
367 
368     std::optional<Dimension> fRadialCenterX;
369     std::optional<Dimension> fRadialCenterY;
370 };
371 
372 struct ACE_EXPORT LinearGradient {
373     // direction in x-axis
374     std::optional<GradientDirection> linearX;
375     // direction in y-axis
376     std::optional<GradientDirection> linearY;
377     // angle of gradient line in bearing angle
378     std::optional<AnimatableDimension> angle;
379 
380     std::optional<Dimension> x1;
381     std::optional<Dimension> y1;
382     std::optional<Dimension> x2;
383     std::optional<Dimension> y2;
384 
385     // is direction in x-axis
IsXAxisLinearGradient386     static bool IsXAxis(GradientDirection direction)
387     {
388         return (direction == GradientDirection::LEFT || direction == GradientDirection::RIGHT ||
389                 direction == GradientDirection::START_TO_END || direction == GradientDirection::END_TO_START);
390     }
391 };
392 
393 struct ACE_EXPORT SweepGradient {
394     // center of x-axis
395     std::optional<AnimatableDimension> centerX;
396     // center of y-axis
397     std::optional<AnimatableDimension> centerY;
398     // startAngle in degree
399     std::optional<AnimatableDimension> startAngle;
400     // endAngle in degree
401     std::optional<AnimatableDimension> endAngle;
402     // rotation in degree
403     std::optional<AnimatableDimension> rotation;
404 };
405 
406 struct ACE_EXPORT ConicGradient {
407     // center of x-axis
408     std::optional<AnimatableDimension> centerX;
409     // center of y-axis
410     std::optional<AnimatableDimension> centerY;
411     // startAngle in radian
412     std::optional<AnimatableDimension> startAngle;
413 };
414 
415 class ACE_FORCE_EXPORT Gradient final {
416 public:
417     void AddColor(const GradientColor& color);
418 
419     void ClearColors();
420 
IsSweepGradientValid()421     bool IsSweepGradientValid() const
422     {
423         if (sweepGradient_.startAngle.has_value() && sweepGradient_.endAngle.has_value()) {
424             return LessOrEqual(sweepGradient_.startAngle.value().Value(), sweepGradient_.endAngle.value().Value());
425         }
426         if (sweepGradient_.startAngle.has_value() && !sweepGradient_.endAngle.has_value()) {
427             return LessOrEqual(sweepGradient_.startAngle.value().Value(), 0.0);
428         }
429         if (!sweepGradient_.startAngle.has_value() && sweepGradient_.endAngle.has_value()) {
430             return LessOrEqual(0.0, sweepGradient_.endAngle.value().Value());
431         }
432         return true;
433     }
434 
IsValid()435     bool IsValid() const
436     {
437         if (GetType() == GradientType::SWEEP) {
438             return IsSweepGradientValid() && colors_.size() > 1;
439         }
440         return colors_.size() > 1;
441     }
442 
SetRepeat(bool repeat)443     void SetRepeat(bool repeat)
444     {
445         repeat_ = repeat;
446     }
447 
GetRepeat()448     bool GetRepeat() const
449     {
450         return repeat_;
451     }
452 
GetColors()453     const std::vector<GradientColor>& GetColors() const
454     {
455         return colors_;
456     }
457 
GetBeginOffset()458     const Offset& GetBeginOffset() const
459     {
460         return beginOffset_;
461     }
462 
SetBeginOffset(const Offset & beginOffset)463     void SetBeginOffset(const Offset& beginOffset)
464     {
465         beginOffset_ = beginOffset;
466     }
467 
GetEndOffset()468     const Offset& GetEndOffset() const
469     {
470         return endOffset_;
471     }
472 
SetEndOffset(const Offset & endOffset)473     void SetEndOffset(const Offset& endOffset)
474     {
475         endOffset_ = endOffset;
476     }
477 
GetInnerRadius()478     double GetInnerRadius() const
479     {
480         return innerRadius_;
481     }
482 
SetInnerRadius(double innerRadius)483     void SetInnerRadius(double innerRadius)
484     {
485         innerRadius_ = innerRadius;
486     }
487 
GetOuterRadius()488     double GetOuterRadius() const
489     {
490         return outerRadius_;
491     }
492 
SetOuterRadius(double outerRadius)493     void SetOuterRadius(double outerRadius)
494     {
495         outerRadius_ = outerRadius;
496     }
497 
GetType()498     GradientType GetType() const
499     {
500         return type_;
501     }
502 
SetType(GradientType type)503     void SetType(GradientType type)
504     {
505         type_ = type;
506     }
507 
ToString()508     std::string ToString() const
509     {
510         return std::string("Gradient (")
511             .append(beginOffset_.ToString())
512             .append(",")
513             .append(std::to_string(innerRadius_))
514             .append(" --- ")
515             .append(endOffset_.ToString())
516             .append(",")
517             .append(std::to_string(outerRadius_))
518             .append(")");
519     }
520 
GetSweepGradient()521     SweepGradient& GetSweepGradient()
522     {
523         return sweepGradient_;
524     }
525 
GetSweepGradient()526     const SweepGradient& GetSweepGradient() const
527     {
528         return sweepGradient_;
529     }
530 
SetSweepGradient(const SweepGradient & sweepGradient)531     void SetSweepGradient(const SweepGradient& sweepGradient)
532     {
533         sweepGradient_ = sweepGradient;
534     }
535 
GetConicGradient()536     ConicGradient& GetConicGradient()
537     {
538         return conicGradient_;
539     }
540 
GetConicGradient()541     const ConicGradient& GetConicGradient() const
542     {
543         return conicGradient_;
544     }
545 
SetConicGradient(const ConicGradient & conicGradient)546     void SetConicGradient(const ConicGradient& conicGradient)
547     {
548         conicGradient_ = conicGradient;
549     }
550 
GetRadialGradient()551     RadialGradient& GetRadialGradient()
552     {
553         return radialGradient_;
554     }
555 
GetRadialGradient()556     const RadialGradient& GetRadialGradient() const
557     {
558         return radialGradient_;
559     }
560 
SetRadialGradient(const RadialGradient & radialGradient)561     void SetRadialGradient(const RadialGradient& radialGradient)
562     {
563         radialGradient_ = radialGradient;
564     }
565 
GetLinearGradient()566     LinearGradient& GetLinearGradient()
567     {
568         return linearGradient_;
569     }
570 
GetLinearGradient()571     const LinearGradient& GetLinearGradient() const
572     {
573         return linearGradient_;
574     }
575 
SetLinearGradient(const LinearGradient & linearGradient)576     void SetLinearGradient(const LinearGradient& linearGradient)
577     {
578         linearGradient_ = linearGradient;
579     }
580 
SetDirection(const GradientDirection & direction)581     void SetDirection(const GradientDirection& direction)
582     {
583         if (LinearGradient::IsXAxis(direction)) {
584             linearGradient_.linearX = direction;
585         } else {
586             linearGradient_.linearY = direction;
587         }
588     }
589 
SetSpreadMethod(SpreadMethod spreadMethod)590     void SetSpreadMethod(SpreadMethod spreadMethod)
591     {
592         spreadMethod_ = spreadMethod;
593     }
594 
SetGradientTransform(const std::string & gradientTransform)595     void SetGradientTransform(const std::string& gradientTransform)
596     {
597         gradientTransform_ = gradientTransform;
598     }
599 
GetSpreadMethod()600     SpreadMethod GetSpreadMethod() const
601     {
602         return spreadMethod_;
603     }
604 
GetGradientTransform()605     const std::string& GetGradientTransform() const
606     {
607         return gradientTransform_;
608     }
609 
GetRadialGradientInfo()610     const RadialGradientInfo& GetRadialGradientInfo() const
611     {
612         return radialGradientInfo_;
613     }
614 
SetRadialGradientInfo(const RadialGradientInfo & radialGradientInfo)615     void SetRadialGradientInfo(const RadialGradientInfo& radialGradientInfo)
616     {
617         radialGradientInfo_ = radialGradientInfo;
618     }
619 
GetLinearGradientInfo()620     const LinearGradientInfo& GetLinearGradientInfo() const
621     {
622         return linearGradientInfo_;
623     }
624 
SetLinearGradientInfo(const LinearGradientInfo & linearGradientInfo)625     void SetLinearGradientInfo(const LinearGradientInfo& linearGradientInfo)
626     {
627         linearGradientInfo_ = linearGradientInfo;
628     }
629 
630 private:
631     GradientType type_ = GradientType::LINEAR;
632     bool repeat_ = false;
633     std::vector<GradientColor> colors_;
634     // for RadialGradient
635     RadialGradient radialGradient_;
636     // for LinearGradient
637     LinearGradient linearGradient_;
638     // for SweepGradient
639     SweepGradient sweepGradient_;
640     // for ConicGradient
641     ConicGradient conicGradient_;
642     // used for CanvasLinearGradient
643     Offset beginOffset_;
644     Offset endOffset_;
645     // used for CanvasRadialGradient
646     double innerRadius_ = 0.0;
647     double outerRadius_ = 0.0;
648     SpreadMethod spreadMethod_ = SpreadMethod::PAD;
649     std::string gradientTransform_;
650     LinearGradientInfo linearGradientInfo_;
651     RadialGradientInfo radialGradientInfo_;
652 };
653 
654 enum class ACE_EXPORT BackgroundImageSizeType {
655     CONTAIN = 0,
656     COVER,
657     AUTO,
658     FILL,
659     LENGTH,
660     PERCENT,
661 };
662 
663 enum class ACE_EXPORT ClickEffectLevel {
664     UNDEFINED = -1,
665     LIGHT = 0,
666     MIDDLE,
667     HEAVY,
668 };
669 
670 struct ClickEffectInfo {
671     ClickEffectLevel level = ClickEffectLevel::LIGHT;
672     float scaleNumber = 0.0f;
673     bool operator==(const ClickEffectInfo& other) const
674     {
675         return level == other.level && NearEqual(scaleNumber, other.scaleNumber);
676     }
677 };
678 
679 class ACE_FORCE_EXPORT BackgroundImageSize final {
680 public:
681     BackgroundImageSize() = default;
BackgroundImageSize(BackgroundImageSizeType type,double value)682     BackgroundImageSize(BackgroundImageSizeType type, double value) : typeX_(type), valueX_(value) {}
BackgroundImageSize(BackgroundImageSizeType typeX,double valueX,BackgroundImageSizeType typeY,double valueY)683     BackgroundImageSize(BackgroundImageSizeType typeX, double valueX, BackgroundImageSizeType typeY, double valueY)
684         : typeX_(typeX), valueX_(valueX), typeY_(typeY), valueY_(valueY)
685     {}
686     ~BackgroundImageSize() = default;
687 
688     void SetSizeTypeX(BackgroundImageSizeType type);
689     void SetSizeTypeY(BackgroundImageSizeType type);
690     void SetSizeValueX(double value);
691     void SetSizeValueY(double value);
692     bool IsValid() const;
693     BackgroundImageSizeType GetSizeTypeX() const;
694     BackgroundImageSizeType GetSizeTypeY() const;
695     double GetSizeValueX() const;
696     double GetSizeValueY() const;
697 
698     BackgroundImageSize operator+(const BackgroundImageSize& size) const;
699     BackgroundImageSize operator-(const BackgroundImageSize& size) const;
700     BackgroundImageSize operator*(double value) const;
701 
702     bool operator==(const BackgroundImageSize& size) const;
703     bool operator!=(const BackgroundImageSize& size) const;
704 
705     std::string ToString() const;
706 
707 private:
708     BackgroundImageSizeType typeX_ { BackgroundImageSizeType::AUTO };
709     double valueX_ = 0.0;
710     BackgroundImageSizeType typeY_ { BackgroundImageSizeType::AUTO };
711     double valueY_ = 0.0;
712 };
713 
714 enum class ACE_EXPORT BackgroundImagePositionType {
715     PERCENT = 0,
716     PX,
717 };
718 
719 class ACE_EXPORT BackgroundImagePosition {
720 public:
721     BackgroundImagePosition() = default;
722     ~BackgroundImagePosition() = default;
BackgroundImagePosition(BackgroundImagePositionType typeX,double valueX,BackgroundImagePositionType typeY,double valueY)723     BackgroundImagePosition(
724         BackgroundImagePositionType typeX, double valueX, BackgroundImagePositionType typeY, double valueY)
725         : typeX_(typeX), typeY_(typeY), valueX_(AnimatableDimension(valueX)), valueY_(AnimatableDimension(valueY))
726     {}
727 
SetContextAndCallback(const WeakPtr<PipelineContext> & context,const RenderNodeAnimationCallback & callback)728     void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback)
729     {
730         valueX_.SetContextAndCallback(context, callback);
731         valueY_.SetContextAndCallback(context, callback);
732     }
733 
SetSizeTypeX(BackgroundImagePositionType type)734     void SetSizeTypeX(BackgroundImagePositionType type)
735     {
736         typeX_ = type;
737     }
738 
SetSizeX(const AnimatableDimension & sizeX)739     void SetSizeX(const AnimatableDimension& sizeX)
740     {
741         if (sizeX.Unit() == DimensionUnit::PERCENT) {
742             typeX_ = BackgroundImagePositionType::PERCENT;
743         } else {
744             typeX_ = BackgroundImagePositionType::PX;
745         }
746         valueX_ = sizeX;
747     }
748 
SetSizeTypeY(BackgroundImagePositionType type)749     void SetSizeTypeY(BackgroundImagePositionType type)
750     {
751         typeY_ = type;
752     }
753 
SetSizeY(const AnimatableDimension & sizeY)754     void SetSizeY(const AnimatableDimension& sizeY)
755     {
756         if (sizeY.Unit() == DimensionUnit::PERCENT) {
757             typeY_ = BackgroundImagePositionType::PERCENT;
758         } else {
759             typeY_ = BackgroundImagePositionType::PX;
760         }
761         valueY_ = sizeY;
762     }
763 
SetSizeValueX(double value)764     void SetSizeValueX(double value)
765     {
766         valueX_ = AnimatableDimension(value);
767     }
768 
SetSizeValueY(double value)769     void SetSizeValueY(double value)
770     {
771         valueY_ = AnimatableDimension(value);
772     }
773 
SetIsAlign(bool isAlign)774     void SetIsAlign(bool isAlign)
775     {
776         isAlign_ = isAlign;
777     }
778 
GetSizeTypeX()779     BackgroundImagePositionType GetSizeTypeX() const
780     {
781         return typeX_;
782     }
783 
GetSizeTypeY()784     BackgroundImagePositionType GetSizeTypeY() const
785     {
786         return typeY_;
787     }
788 
GetSizeX()789     const AnimatableDimension& GetSizeX() const
790     {
791         return valueX_;
792     }
793 
GetSizeY()794     const AnimatableDimension& GetSizeY() const
795     {
796         return valueY_;
797     }
798 
GetSizeValueX()799     double GetSizeValueX() const
800     {
801         return valueX_.Value();
802     }
803 
GetSizeValueY()804     double GetSizeValueY() const
805     {
806         return valueY_.Value();
807     }
808 
IsAlign()809     bool IsAlign() const
810     {
811         return isAlign_;
812     }
813 
814     BackgroundImagePosition operator+(const BackgroundImagePosition& position) const;
815 
816     BackgroundImagePosition operator-(const BackgroundImagePosition& position) const;
817 
818     BackgroundImagePosition operator*(double value) const;
819 
820     bool operator==(const BackgroundImagePosition& backgroundImagePosition) const;
821 
822     bool operator!=(const BackgroundImagePosition& backgroundImagePosition) const;
823 
824     std::string ToString() const;
825 
826 private:
827     BackgroundImagePositionType typeX_ { BackgroundImagePositionType::PX };
828     BackgroundImagePositionType typeY_ { BackgroundImagePositionType::PX };
829     AnimatableDimension valueX_ = AnimatableDimension(-1.0);
830     AnimatableDimension valueY_ = AnimatableDimension(0.0);
831     bool isAlign_ = false;
832 };
833 
834 class ImageObjectPosition final : public BackgroundImagePosition {};
835 
836 class BackgroundImage final : public AceType {
837     DECLARE_ACE_TYPE(BackgroundImage, AceType);
838 
839 public:
840     BackgroundImage() = default;
841     ~BackgroundImage() override = default;
842 
GetImageSize()843     const BackgroundImageSize& GetImageSize() const
844     {
845         return imageSize_;
846     }
847 
GetImagePosition()848     const BackgroundImagePosition& GetImagePosition() const
849     {
850         return imagePosition_;
851     }
852 
GetImageRepeat()853     ImageRepeat GetImageRepeat() const
854     {
855         return imageRepeat_;
856     }
857 
GetSrc()858     const std::string& GetSrc() const
859     {
860         return src_;
861     }
862 
SetImageSize(BackgroundImageSize imageSize)863     void SetImageSize(BackgroundImageSize imageSize)
864     {
865         imageSize_ = imageSize;
866     }
867 
868     void SetImageSize(BackgroundImageSizeType type, double value = FULL_IMG_SIZE)
869     {
870         imageSize_ = BackgroundImageSize(type, value);
871     }
872 
SetImageSize(BackgroundImageSizeType typeX,double valueX,BackgroundImageSizeType typeY,double valueY)873     void SetImageSize(BackgroundImageSizeType typeX, double valueX, BackgroundImageSizeType typeY, double valueY)
874     {
875         imageSize_ = BackgroundImageSize(typeX, valueX, typeY, valueY);
876     }
877 
SetImagePosition(const BackgroundImagePosition & imagePosition)878     void SetImagePosition(const BackgroundImagePosition& imagePosition)
879     {
880         imagePosition_ = imagePosition;
881     }
882 
SetImagePosition(BackgroundImagePositionType typeX,double valueX,BackgroundImagePositionType typeY,double valueY)883     void SetImagePosition(
884         BackgroundImagePositionType typeX, double valueX, BackgroundImagePositionType typeY, double valueY)
885     {
886         imagePosition_ = BackgroundImagePosition(typeX, valueX, typeY, valueY);
887     }
888 
SetImageRepeat(const ImageRepeat & imageRepeat)889     void SetImageRepeat(const ImageRepeat& imageRepeat)
890     {
891         imageRepeat_ = imageRepeat;
892     }
893 
SetSrc(const std::string & src,const RefPtr<ThemeConstants> & themeConstants)894     void SetSrc(const std::string& src, const RefPtr<ThemeConstants>& themeConstants)
895     {
896         // If match the regex, src with the outer "url()" removed is returned.
897         // Otherwise return a copy of src directly.
898         auto imgSrc = std::regex_replace(src, std::regex(R"(^url\(\s*['"]?\s*([^()]+?)\s*['"]?\s*\)$)"), "$1");
899         src_ = ThemeUtils::ProcessImageSource(imgSrc, themeConstants);
900     }
901 
902     void SetParsedSrc(const std::string& src)
903     {
904         // src is processed by ParseJsMedia function
905         src_ = src;
906     }
907 
908     bool operator==(const BackgroundImage& image) const
909     {
910         bool fileName = src_ == image.GetSrc();
911         bool size = imageSize_ == image.GetImageSize();
912         bool position = imagePosition_ == image.GetImagePosition();
913         bool repeat = imageRepeat_ == image.GetImageRepeat();
914         return fileName && size && position && repeat;
915     }
916 
917     bool operator!=(const BackgroundImage& image) const
918     {
919         return !operator==(image);
920     }
921 
922 private:
923     std::string src_;
924     BackgroundImageSize imageSize_;
925     BackgroundImagePosition imagePosition_;
926     ImageRepeat imageRepeat_ { ImageRepeat::REPEAT };
927 };
928 
929 class ArcBackground final : public AceType {
930     DECLARE_ACE_TYPE(ArcBackground, AceType);
931 
932 public:
933     ~ArcBackground() override = default;
934     ArcBackground(Point center, double radius)
935     {
936         SetCenter(center);
937         SetRadius(radius);
938     }
939 
940     const Point& GetCenter() const
941     {
942         return center_;
943     }
944 
945     double GetRadius() const
946     {
947         return radius_;
948     }
949 
950     void SetCenter(const Point& center)
951     {
952         center_ = center;
953     }
954 
955     void SetRadius(double radius)
956     {
957         radius_ = radius;
958     }
959 
960     void SetColor(const Color& color)
961     {
962         color_ = color;
963     }
964 
965     const Color& GetColor() const
966     {
967         return color_;
968     }
969 
970 private:
971     Point center_;
972     double radius_ = 0.0;
973     Color color_;
974 };
975 
976 class Decoration final : public AceType {
977     DECLARE_ACE_TYPE(Decoration, AceType);
978 
979 public:
980     Decoration() = default;
981     ~Decoration() override = default;
982 
983     void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback);
984 
985     void AddShadow(const Shadow& shadow);
986 
987     void ClearAllShadow();
988 
989     void SetBackgroundColor(const Color& backgroundColor, const AnimationOption& option = AnimationOption())
990     {
991         backgroundColor_ = AnimatableColor(backgroundColor, option);
992     }
993 
994     void SetBackgroundColor(const AnimatableColor& backgroundColor)
995     {
996         backgroundColor_ = backgroundColor;
997     }
998 
999     void SetAnimationColor(const Color& animationColor)
1000     {
1001         animationColor_ = animationColor;
1002     }
1003 
1004     void SetGradient(const Gradient& gradient, const WeakPtr<PipelineContext>& context = nullptr,
1005         const RenderNodeAnimationCallback& callback = nullptr)
1006     {
1007         gradient_ = gradient;
1008         if (callback) {
1009             switch (gradient_.GetType()) {
1010                 case GradientType::LINEAR:
1011                     if (gradient_.GetLinearGradient().angle) {
1012                         gradient_.GetLinearGradient().angle->SetContextAndCallbackAfterFirstAssign(context, callback);
1013                     }
1014                     break;
1015                 case GradientType::SWEEP:
1016                     if (gradient_.GetSweepGradient().centerX) {
1017                         gradient_.GetSweepGradient().centerX->SetContextAndCallbackAfterFirstAssign(context, callback);
1018                     }
1019                     if (gradient_.GetSweepGradient().centerY) {
1020                         gradient_.GetSweepGradient().centerY->SetContextAndCallbackAfterFirstAssign(context, callback);
1021                     }
1022                     if (gradient_.GetSweepGradient().startAngle) {
1023                         gradient_.GetSweepGradient().startAngle->SetContextAndCallbackAfterFirstAssign(
1024                             context, callback);
1025                     }
1026                     if (gradient_.GetSweepGradient().endAngle) {
1027                         gradient_.GetSweepGradient().endAngle->SetContextAndCallbackAfterFirstAssign(context, callback);
1028                     }
1029                     if (gradient_.GetSweepGradient().rotation) {
1030                         gradient_.GetSweepGradient().rotation->SetContextAndCallbackAfterFirstAssign(context, callback);
1031                     }
1032                     break;
1033                 case GradientType::RADIAL:
1034                     if (gradient_.GetRadialGradient().radialHorizontalSize) {
1035                         gradient_.GetRadialGradient().radialHorizontalSize->SetContextAndCallbackAfterFirstAssign(
1036                             context, callback);
1037                     }
1038                     if (gradient_.GetRadialGradient().radialVerticalSize) {
1039                         gradient_.GetRadialGradient().radialVerticalSize->SetContextAndCallbackAfterFirstAssign(
1040                             context, callback);
1041                     }
1042                     if (gradient_.GetRadialGradient().radialCenterX) {
1043                         gradient_.GetRadialGradient().radialCenterX->SetContextAndCallbackAfterFirstAssign(
1044                             context, callback);
1045                     }
1046                     if (gradient_.GetRadialGradient().radialCenterY) {
1047                         gradient_.GetRadialGradient().radialCenterY->SetContextAndCallbackAfterFirstAssign(
1048                             context, callback);
1049                     }
1050                     break;
1051                 default:
1052                     break;
1053             }
1054         }
1055     }
1056 
1057     void SetBorderImageGradient(const Gradient& gradient)
1058     {
1059         gradientBorderImage_ = gradient;
1060     }
1061     void SetImage(const RefPtr<BackgroundImage>& image)
1062     {
1063         image_ = image;
1064     }
1065 
1066     void SetBorderImage(const RefPtr<BorderImage>& borderImage)
1067     {
1068         borderImage_ = borderImage;
1069     }
1070 
1071     void SetHasBorderImageSource(const bool tag)
1072     {
1073         hasBorderImageSource_ = tag;
1074     }
1075 
1076     void SetHasBorderImageSlice(const bool tag)
1077     {
1078         hasBorderImageSlice_ = tag;
1079     }
1080 
1081     void SetHasBorderImageWidth(const bool tag)
1082     {
1083         hasBorderImageWidth_ = tag;
1084     }
1085 
1086     void SetHasBorderImageOutset(const bool tag)
1087     {
1088         hasBorderImageOutset_ = tag;
1089     }
1090 
1091     void SetHasBorderImageRepeat(const bool tag)
1092     {
1093         hasBorderImageRepeat_ = tag;
1094     }
1095 
1096     void SetHasBorderImageGradient(const bool tag)
1097     {
1098         hasBorderImageGradient_ = tag;
1099     }
1100 
1101     void SetPadding(const Edge& padding)
1102     {
1103         padding_ = padding;
1104     }
1105 
1106     void SetBorderRadius(const Radius& radius)
1107     {
1108         border_.SetBorderRadius(radius);
1109     }
1110 
1111     void SetBorder(const Border& border)
1112     {
1113         border_ = border;
1114     }
1115 
1116     void SetArcBackground(const RefPtr<ArcBackground>& arcBG)
1117     {
1118         arcBG_ = arcBG;
1119     }
1120 
1121     void SetBlurRadius(const Dimension& radius)
1122     {
1123         blurRadius_ = radius;
1124     }
1125 
1126     void SetBlurRadius(const AnimatableDimension& radius)
1127     {
1128         blurRadius_ = radius;
1129     }
1130 
1131     const Color& GetColorBlend(void) const
1132     {
1133         return colorBlend;
1134     }
1135 
1136     void SetColorBlend(const Color& color)
1137     {
1138         colorBlend = color;
1139     }
1140 
1141     void SetWindowBlurProgress(float progress)
1142     {
1143         windowBlurProgress_ = progress;
1144     }
1145 
1146     void SetWindowBlurStyle(WindowBlurStyle style)
1147     {
1148         windowBlurStyle_ = style;
1149     }
1150 
1151     void SetBlurStyle(const BlurStyleOption& style)
1152     {
1153         blurStyle_ = style;
1154     }
1155 
1156     const Border& GetBorder() const
1157     {
1158         return border_;
1159     }
1160 
1161     const Edge& GetPadding() const
1162     {
1163         return padding_;
1164     }
1165 
1166     const RefPtr<BackgroundImage>& GetImage() const
1167     {
1168         return image_;
1169     }
1170 
1171     const RefPtr<BorderImage>& GetBorderImage() const
1172     {
1173         return borderImage_;
1174     }
1175 
1176     const Gradient& GetGradient() const
1177     {
1178         return gradient_;
1179     }
1180 
1181     const Gradient& GetBorderImageGradient() const
1182     {
1183         return gradientBorderImage_;
1184     }
1185 
1186     bool GetHasBorderImageSource()
1187     {
1188         return hasBorderImageSource_;
1189     }
1190 
1191     bool GetHasBorderImageSlice()
1192     {
1193         return hasBorderImageSlice_;
1194     }
1195 
1196     bool GetHasBorderImageWidth()
1197     {
1198         return hasBorderImageWidth_;
1199     }
1200 
1201     bool GetHasBorderImageOutset()
1202     {
1203         return hasBorderImageOutset_;
1204     }
1205 
1206     bool GetHasBorderImageRepeat()
1207     {
1208         return hasBorderImageRepeat_;
1209     }
1210 
1211     bool GetHasBorderImageGradient()
1212     {
1213         return hasBorderImageGradient_;
1214     }
1215 
1216     const AnimatableColor& GetBackgroundColor() const
1217     {
1218         return backgroundColor_;
1219     }
1220 
1221     const Color& GetAnimationColor() const
1222     {
1223         return animationColor_;
1224     }
1225 
1226     const std::vector<Shadow>& GetShadows() const
1227     {
1228         return shadows_;
1229     }
1230 
1231     void SetShadows(const std::vector<Shadow>& shadows)
1232     {
1233         shadows_.assign(shadows.begin(), shadows.end());
1234     }
1235 
1236     BlendMode GetBlendMode() const
1237     {
1238         return blendMode_;
1239     }
1240 
1241     void SetBlendMode(BlendMode blendMode)
1242     {
1243         blendMode_ = blendMode;
1244     }
1245 
1246     BlendApplyType GetBlendApplyType() const
1247     {
1248         return blendApplyType_;
1249     }
1250 
1251     void SetBlendApplyType(BlendApplyType blendApplyType)
1252     {
1253         blendApplyType_ = blendApplyType;
1254     }
1255 
1256     const Dimension& GetGrayScale(void) const
1257     {
1258         return grayScale_;
1259     }
1260 
1261     void SetGrayScale(const Dimension& grayScale)
1262     {
1263         grayScale_ = grayScale;
1264     }
1265 
1266     void SetBrightness(const Dimension& brightness)
1267     {
1268         brightness_ = brightness;
1269     }
1270 
1271     const Dimension& GetBrightness() const
1272     {
1273         return brightness_;
1274     }
1275 
1276     const Dimension& GetContrast(void) const
1277     {
1278         return contrast_;
1279     }
1280 
1281     void SetContrast(const Dimension& contrast)
1282     {
1283         contrast_ = contrast;
1284     }
1285 
1286     const Dimension& GetSaturate(void) const
1287     {
1288         return saturate_;
1289     }
1290 
1291     void SetSaturate(const Dimension& saturate)
1292     {
1293         saturate_ = saturate;
1294     }
1295 
1296     const Dimension& GetSepia(void) const
1297     {
1298         return sepia_;
1299     }
1300 
1301     void SetSepia(const Dimension& sepia)
1302     {
1303         sepia_ = sepia;
1304     }
1305 
1306     void SetInvert(const Dimension& invert)
1307     {
1308         invert_ = invert;
1309     }
1310 
1311     const Dimension& GetInvert(void) const
1312     {
1313         return invert_;
1314     }
1315 
1316     float GetHueRotate(void) const
1317     {
1318         return hueRotate_;
1319     }
1320 
1321     void SetHueRotate(const float& hueRotate)
1322     {
1323         hueRotate_ = hueRotate;
1324     }
1325 
1326     const RefPtr<ArcBackground>& GetArcBackground() const
1327     {
1328         return arcBG_;
1329     }
1330 
1331     bool NeedReloadImage(const RefPtr<Decoration>& lastDecoration) const
1332     {
1333         if (!image_) {
1334             return false;
1335         }
1336 
1337         if (!lastDecoration || !(lastDecoration->GetImage())) {
1338             return true;
1339         }
1340 
1341         return (*image_) != (*(lastDecoration->GetImage()));
1342     }
1343 
1344     const AnimatableDimension& GetBlurRadius() const
1345     {
1346         return blurRadius_;
1347     }
1348 
1349     float GetWindowBlurProgress() const
1350     {
1351         return windowBlurProgress_;
1352     }
1353 
1354     WindowBlurStyle GetWindowBlurStyle() const
1355     {
1356         return windowBlurStyle_;
1357     }
1358 
1359     const BlurStyleOption& GetBlurStyle() const
1360     {
1361         return blurStyle_;
1362     }
1363 
1364     // Indicate how much size the decoration taken, excluding the content size.
1365     Size GetOccupiedSize(double dipScale) const;
1366     double HorizontalSpaceOccupied(double dipScale) const;
1367     double VerticalSpaceOccupied(double dipScale) const;
1368 
1369     Offset GetOffset(double dipScale) const;
1370 
1371 private:
1372     bool hasBorderImageSource_ = false;
1373     bool hasBorderImageSlice_ = false;
1374     bool hasBorderImageWidth_ = false;
1375     bool hasBorderImageOutset_ = false;
1376     bool hasBorderImageRepeat_ = false;
1377     bool hasBorderImageGradient_ = false;
1378 
1379     // padding is zero
1380     Edge padding_;
1381     // border contains black color and 1.0f thickness as default
1382     Border border_;
1383     // shadow vector is empty
1384     std::vector<Shadow> shadows_;
1385     // blendMode
1386     BlendMode blendMode_ = BlendMode::NONE;
1387     BlendApplyType blendApplyType_ = BlendApplyType::FAST;
1388     Dimension grayScale_;
1389     // Brightness (1.0 as default), range = (0, 2)
1390     Dimension brightness_ = 1.0_px;
1391     // hueRotate
1392     float hueRotate_ = 0.0f;
1393     // Contrast (1.0 as default), complete gray at 0
1394     Dimension contrast_ = 1.0_px;
1395     // Saturate
1396     Dimension saturate_ = 1.0_px;
1397     // Sepia
1398     Dimension sepia_;
1399     // invert
1400     Dimension invert_;
1401     // color is transparent
1402     AnimatableColor backgroundColor_ { Color::TRANSPARENT };
1403     Color animationColor_ = Color::TRANSPARENT;
1404     // Gradient is not implemented
1405     Gradient gradient_ = Gradient();
1406     Gradient gradientBorderImage_ = Gradient();
1407     RefPtr<BackgroundImage> image_;
1408     RefPtr<BorderImage> borderImage_;
1409     RefPtr<ArcBackground> arcBG_;
1410     // Blur radius
1411     AnimatableDimension blurRadius_;
1412     // window blur progress
1413     float windowBlurProgress_ = 0.0f;
1414     // window blur style;
1415     WindowBlurStyle windowBlurStyle_ = WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT;
1416     Color colorBlend;
1417     // blur from rosen
1418     BlurStyleOption blurStyle_;
1419 };
1420 
1421 class Pattern final : std::enable_shared_from_this<Pattern> {
1422 public:
1423     bool IsValid() const
1424     {
1425         return (!imgSrc_.empty() || pixelMap_);
1426     }
1427 
1428     const std::string& GetImgSrc() const
1429     {
1430         return imgSrc_;
1431     }
1432 
1433     void SetImgSrc(const std::string& imgSrc)
1434     {
1435         imgSrc_ = imgSrc;
1436     }
1437 
1438     const std::string& GetRepetition() const
1439     {
1440         return repetition_;
1441     }
1442 
1443     void SetRepetition(const std::string& repetition)
1444     {
1445         repetition_ = repetition;
1446     }
1447 
1448     double GetImageWidth() const
1449     {
1450         return imageWidth_;
1451     }
1452 
1453     void SetImageWidth(double imageWidth)
1454     {
1455         imageWidth_ = imageWidth;
1456     }
1457 
1458     double GetImageHeight() const
1459     {
1460         return imageHeight_;
1461     }
1462 
1463     void SetImageHeight(double imageHeight)
1464     {
1465         imageHeight_ = imageHeight;
1466     }
1467 
1468     double GetScaleX() const
1469     {
1470         return scaleX_;
1471     }
1472 
1473     void SetScaleX(double scaleX)
1474     {
1475         transformable_ = true;
1476         scaleX_ = scaleX;
1477     }
1478 
1479     double GetScaleY() const
1480     {
1481         return scaleY_;
1482     }
1483 
1484     void SetScaleY(double scaleY)
1485     {
1486         transformable_ = true;
1487         scaleY_ = scaleY;
1488     }
1489 
1490     double GetSkewX() const
1491     {
1492         return skewX_;
1493     }
1494 
1495     void SetSkewX(double skewX)
1496     {
1497         transformable_ = true;
1498         skewX_ = skewX;
1499     }
1500 
1501     double GetSkewY() const
1502     {
1503         return skewY_;
1504     }
1505 
1506     void SetSkewY(double skewY)
1507     {
1508         transformable_ = true;
1509         skewY_ = skewY;
1510     }
1511 
1512     double GetTranslateX() const
1513     {
1514         return translateX_;
1515     }
1516 
1517     void SetTranslateX(double translateX)
1518     {
1519         transformable_ = true;
1520         translateX_ = translateX;
1521     }
1522 
1523     double GetTranslateY() const
1524     {
1525         return translateY_;
1526     }
1527 
1528     void SetTranslateY(double translateY)
1529     {
1530         transformable_ = true;
1531         translateY_ = translateY;
1532     }
1533 
1534     bool IsTransformable() const
1535     {
1536         return transformable_;
1537     }
1538 
1539     void SetPixelMap(const RefPtr<PixelMap>& pixelMap)
1540     {
1541         pixelMap_ = pixelMap;
1542     }
1543 
1544     RefPtr<PixelMap> GetPixelMap() const
1545     {
1546         return pixelMap_;
1547     }
1548 
1549 private:
1550     double imageWidth_ = 0.0;
1551     double imageHeight_ = 0.0;
1552     double scaleX_ = 0.0;
1553     double skewX_ = 0.0;
1554     double skewY_ = 0.0;
1555     double scaleY_ = 0.0;
1556     double translateX_ = 0.0;
1557     double translateY_ = 0.0;
1558     bool transformable_ = false;
1559     std::string imgSrc_;
1560     std::string repetition_;
1561     RefPtr<PixelMap> pixelMap_;
1562 };
1563 
1564 enum class PathCmd {
1565     CMDS,
1566     TRANSFORM,
1567     MOVE_TO,
1568     LINE_TO,
1569     ARC,
1570     ARC_TO,
1571     QUADRATIC_CURVE_TO,
1572     BEZIER_CURVE_TO,
1573     ELLIPSE,
1574     RECT,
1575     CLOSE_PATH,
1576 };
1577 
1578 struct PathArgs {
1579     std::string cmds;
1580     double para1 = 0.0;
1581     double para2 = 0.0;
1582     double para3 = 0.0;
1583     double para4 = 0.0;
1584     double para5 = 0.0;
1585     double para6 = 0.0;
1586     double para7 = 0.0;
1587     double para8 = 0.0;
1588 };
1589 
1590 class ACE_FORCE_EXPORT CanvasPath2D : virtual public AceType {
1591     DECLARE_ACE_TYPE(CanvasPath2D, AceType)
1592 public:
1593     CanvasPath2D() = default;
1594     ~CanvasPath2D() = default;
1595     explicit CanvasPath2D(const std::string& cmds);
1596     explicit CanvasPath2D(const RefPtr<CanvasPath2D>& path);
1597     void AddPath(const RefPtr<CanvasPath2D>& path);
1598     void SetTransform(double a, double b, double c, double d, double e, double f);
1599     void MoveTo(double x, double y);
1600     void LineTo(double x, double y);
1601     void Arc(double x, double y, double radius, double startAngle, double endAngle, double ccw);
1602     void ArcTo(double x1, double y1, double x2, double y2, double radius);
1603     void QuadraticCurveTo(double cpx, double cpy, double x, double y);
1604     void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y);
1605     void Ellipse(double x, double y, double radiusX, double radiusY, double rotation, double startAngle,
1606         double endAngle, double ccw);
1607     void Rect(double x, double y, double width, double height);
1608     void ClosePath();
1609     const std::vector<std::pair<PathCmd, PathArgs>>& GetCaches() const;
1610     std::string ToString() const;
1611 
1612 private:
1613     std::vector<std::pair<PathCmd, PathArgs>> caches_;
1614 };
1615 
1616 } // namespace OHOS::Ace
1617 
1618 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_DECORATION_H
1619