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