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_SVG_PARSE_SVG_GRAPHIC_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_GRAPHIC_H
18 
19 #include "include/core/SkMaskFilter.h"
20 
21 #include "base/utils/utils.h"
22 #include "core/components/common/properties/decoration.h"
23 #include "core/components_ng/render/drawing_forward.h"
24 #ifndef USE_ROSEN_DRAWING
25 #include "include/core/SkPaint.h"
26 #else
27 #include "core/components_ng/render/drawing.h"
28 #endif
29 
30 #include "frameworks/core/components_ng/svg/parse/svg_node.h"
31 
32 namespace OHOS::Ace::NG {
33 
34 class SvgGraphic : public SvgNode {
35     DECLARE_ACE_TYPE(SvgGraphic, SvgNode);
36 
37 public:
SvgGraphic()38     SvgGraphic() : SvgNode()
39     {
40         InitGraphicFlag();
41     }
42     ~SvgGraphic() override = default;
43 
44     void OnDraw(RSCanvas& canvas, const Size& layout, const std::optional<Color>& color) override;
45 protected:
OnGraphicFill()46     void OnGraphicFill()
47     {
48 #ifndef USE_ROSEN_DRAWING
49         if (skCanvas_) {
50             auto smoothEdge = GetSmoothEdge();
51             if (GreatNotEqual(smoothEdge, 0.0f)) {
52                 auto filter = SkMaskFilter::MakeBlur(SkBlurStyle::kNormal_SkBlurStyle, smoothEdge, false);
53                 auto tmpFillPaint = fillPaint_;
54                 tmpFillPaint.setMaskFilter(filter);
55                 skCanvas_->drawPath(path_, tmpFillPaint);
56                 tmpFillPaint.setMaskFilter(nullptr);
57             } else {
58                 skCanvas_->drawPath(path_, fillPaint_);
59             }
60         }
61 #else
62         if (rsCanvas_) {
63             auto smoothEdge = GetSmoothEdge();
64             if (SystemProperties::GetDebugEnabled()) {
65                 TAG_LOGD(AceLogTag::ACE_IMAGE, "svg path:%{public}s, smoothEdge = %{public}f",
66                     path_.ConvertToSVGString().c_str(), smoothEdge);
67             }
68             if (!path_.IsValid()) {
69                 TAG_LOGW(AceLogTag::ACE_IMAGE, "svg path is invalid");
70             }
71             if (GreatNotEqual(smoothEdge, 0.0f)) {
72                 RSFilter filter;
73                 filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter(
74                     RSBlurType::NORMAL, static_cast<double>(smoothEdge), false
75                 ));
76                 auto tmpFillBrush = fillBrush_;
77                 tmpFillBrush.SetFilter(filter);
78                 rsCanvas_->AttachBrush(tmpFillBrush);
79                 rsCanvas_->DrawPath(path_);
80                 rsCanvas_->DetachBrush();
81             } else {
82                 rsCanvas_->AttachBrush(fillBrush_);
83                 rsCanvas_->DrawPath(path_);
84                 rsCanvas_->DetachBrush();
85             }
86         }
87 #endif
88     }
89 
OnGraphicStroke()90     void OnGraphicStroke()
91     {
92 #ifndef USE_ROSEN_DRAWING
93         if (skCanvas_) {
94             auto smoothEdge = GetSmoothEdge();
95             if (GreatNotEqual(smoothEdge, 0.0f)) {
96                 auto filter = SkMaskFilter::MakeBlur(SkBlurStyle::kNormal_SkBlurStyle, smoothEdge, false);
97                 auto tmpStrokePaint = strokePaint_;
98                 tmpStrokePaint.setMaskFilter(filter);
99                 skCanvas_->drawPath(path_, tmpStrokePaint);
100                 tmpStrokePaint.setMaskFilter(nullptr);
101             } else {
102                 skCanvas_->drawPath(path_, strokePaint_);
103             }
104         }
105 #else
106         if (rsCanvas_) {
107             auto smoothEdge = GetSmoothEdge();
108             if (SystemProperties::GetDebugEnabled()) {
109                 TAG_LOGD(AceLogTag::ACE_IMAGE, "svg path:%{public}s, smoothEdge = %{public}f",
110                     path_.ConvertToSVGString().c_str(), smoothEdge);
111             }
112             if (!path_.IsValid()) {
113                 TAG_LOGW(AceLogTag::ACE_IMAGE, "svg path is invalid");
114             }
115             if (GreatNotEqual(smoothEdge, 0.0f)) {
116                 RSFilter filter;
117                 filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter(
118                     RSBlurType::NORMAL, static_cast<double>(smoothEdge), false
119                 ));
120                 auto tmpStrokePen = strokePen_;
121                 tmpStrokePen.SetFilter(filter);
122                 rsCanvas_->AttachPen(tmpStrokePen);
123                 rsCanvas_->DrawPath(path_);
124                 rsCanvas_->DetachPen();
125             } else {
126                 rsCanvas_->AttachPen(strokePen_);
127                 rsCanvas_->DrawPath(path_);
128                 rsCanvas_->DetachPen();
129             }
130         }
131 #endif
132     }
133 
134     // rect line polygon path circle ellipse
InitGraphicFlag()135     void InitGraphicFlag()
136     {
137         hrefFill_ = true;
138         hrefRender_ = true;
139         passStyle_ = false;
140         inheritStyle_ = true;
141         drawTraversed_ = true;
142     }
143 
144     // Update fillStates & strokeStates
145     void UpdateFillGradient(const Size& viewPort);
146     void UpdateStrokeGradient(const Size& viewPort);
147     bool UpdateFillStyle(const std::optional<Color>& color, bool antiAlias = true);
148     bool UpdateStrokeStyle(bool antiAlias = true);
149     void SetStrokeGradientStyle(double opacity);
150     bool SetGradientStyle(double opacity);
151     void UpdateLineDash();
152     void SetLinearGradient(const Size& viewPort, Gradient& gradient);
153     void SetRadialGradient(const Size& viewPort, Gradient& gradient);
154 
155 #ifndef USE_ROSEN_DRAWING
156     SkPath path_;
157     SkPaint fillPaint_;
158     SkPaint strokePaint_;
159 #else
160     RSRecordingPath path_;
161     RSBrush fillBrush_;
162     RSPen strokePen_;
163 #endif
164     FillState fillState_;
165 
166 private:
167     void UpdateColorFilter(RSFilter& filter);
168 };
169 
170 } // namespace OHOS::Ace::NG
171 
172 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_GRAPHIC_H