1 /*
2  * Copyright (c) 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_NG_IMAGE_PROVIDER_SVG_DOM_BASE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_SVG_DOM_BASE_H
18 
19 #include <optional>
20 
21 #include "base/geometry/ng/size_t.h"
22 #include "base/geometry/size.h"
23 #include "base/memory/ace_type.h"
24 #include "core/components/common/layout/constants.h"
25 #include "core/components/common/properties/color.h"
26 #include "core/components_ng/render/canvas_image.h"
27 
28 namespace OHOS::Ace::NG {
29 
30 class SvgDomBase : public AceType {
31     DECLARE_ACE_TYPE(SvgDomBase, AceType);
32 
33 public:
34     virtual SizeF GetContainerSize() const = 0;
35     virtual void SetContainerSize(const SizeF& containerSize) = 0;
SetFillColor(const std::optional<Color> & color)36     virtual void SetFillColor(const std::optional<Color>& color) {}
SetSmoothEdge(float value)37     virtual void SetSmoothEdge(float value) {}
SetColorFilter(const std::optional<ImageColorFilter> & colorFilter)38     virtual void SetColorFilter(const std::optional<ImageColorFilter>& colorFilter) {}
GetDumpInfo()39     virtual std::string GetDumpInfo() { return ""; }
SetRadius(const BorderRadiusArray & radiusXY)40     void SetRadius(const BorderRadiusArray& radiusXY)
41     {
42         if (!radius_) {
43             radius_ = std::make_unique<BorderRadiusArray>(radiusXY);
44         } else {
45             *radius_ = radiusXY;
46         }
47     }
48 
IsStatic()49     virtual bool IsStatic()
50     {
51         return true;
52     }
53 
SetAnimationCallback(std::function<void ()> && funcAnimateFlush,const WeakPtr<CanvasImage> & imagePtr)54     virtual void SetAnimationCallback(std::function<void()>&& funcAnimateFlush, const WeakPtr<CanvasImage>& imagePtr) {}
SetAnimationOnFinishCallback(const std::function<void ()> & onFinishCallback)55     virtual void SetAnimationOnFinishCallback(const std::function<void()>& onFinishCallback) {}
ControlAnimation(bool play)56     virtual void ControlAnimation(bool play) {}
57 
58     virtual void DrawImage(
59         RSCanvas& canvas, const ImageFit& imageFit, const Size& layout) = 0;
60 
ApplyImageFit(ImageFit imageFit,double & scaleX,double & scaleY)61     void ApplyImageFit(ImageFit imageFit, double& scaleX, double& scaleY)
62     {
63         switch (imageFit) {
64             case ImageFit::FILL:
65                 ApplyFill(scaleX, scaleY);
66                 break;
67             case ImageFit::NONE:
68                 break;
69             case ImageFit::COVER:
70                 ApplyCover(scaleX, scaleY);
71                 break;
72             case ImageFit::CONTAIN:
73                 ApplyContain(scaleX, scaleY);
74                 break;
75             case ImageFit::SCALE_DOWN:
76                 if (svgSize_ > layout_ || svgSize_ == layout_) {
77                     ApplyContain(scaleX, scaleY);
78                 }
79                 break;
80             default:
81                 break;
82         }
83     }
84 
ApplyFill(double & scaleX,double & scaleY)85     void ApplyFill(double& scaleX, double& scaleY)
86     {
87         if (!svgSize_.IsValid()) {
88             return;
89         }
90         scaleX = layout_.Width() / svgSize_.Width();
91         scaleY = layout_.Height() / svgSize_.Height();
92     }
93 
ApplyContain(double & scaleX,double & scaleY)94     void ApplyContain(double& scaleX, double& scaleY)
95     {
96         if (!svgSize_.IsValid()) {
97             return;
98         }
99         if (Size::CalcRatio(svgSize_) > Size::CalcRatio(layout_)) {
100             scaleX = layout_.Width() / svgSize_.Width();
101             scaleY = scaleX;
102         } else {
103             scaleX = layout_.Height() / svgSize_.Height();
104             scaleY = scaleX;
105         }
106     }
107 
ApplyCover(double & scaleX,double & scaleY)108     void ApplyCover(double& scaleX, double& scaleY)
109     {
110         if (!svgSize_.IsValid()) {
111             return;
112         }
113         if (Size::CalcRatio(svgSize_) > Size::CalcRatio(layout_)) {
114             scaleX = layout_.Height() / svgSize_.Height();
115             scaleY = scaleX;
116         } else {
117             scaleX = layout_.Width() / svgSize_.Width();
118             scaleY = scaleX;
119         }
120     }
121 
122     Size layout_;  // layout size set by Image Component
123     Size svgSize_; // self size specified in SVG file
124     std::unique_ptr<BorderRadiusArray> radius_;
125 };
126 
127 } // namespace OHOS::Ace::NG
128 
129 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_SVG_DOM_BASE_H
130