1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/pipeline/layers/clip_layer.h"
17
18 #include "base/log/dump_log.h"
19
20 namespace OHOS::Ace::Flutter {
21
AddToScene(SceneBuilder & builder,double x,double y)22 void ClipLayer::AddToScene(SceneBuilder& builder, double x, double y)
23 {
24 if (isPath_) {
25 fml::RefPtr<flutter::CanvasPath> path = flutter::CanvasPath::Create();
26 path->addPath(canvasPath_.get(), x + x_, y + y_);
27 builder.PushClipPath(path.get(), static_cast<int32_t>(clipBehavior_));
28 } else {
29 flutter::RRect rrect;
30 rrect.sk_rrect = rrect_.sk_rrect.makeOffset(x + x_, y + y_);
31 builder.PushClipRRect(rrect, static_cast<int32_t>(clipBehavior_));
32 }
33
34 if (isMask_) {
35 if (isSvgMask_) {
36 builder.PushSvgMask(svgDom_, svgX_, svgY_, scaleX_, scaleY_);
37 } else if (isGradientMask_) {
38 builder.PushGradientColorMask(maskPaint_);
39 } else if (isPathMask_) {
40 builder.PushPathMask(maskPaint_, maskPath_);
41 }
42 }
43
44 AddChildToScene(builder, x + x_, y + y_);
45 if (isMask_) {
46 builder.Pop();
47 }
48 builder.Pop();
49 }
50
SetClip(double left,double right,double top,double bottom,Clip clipBehavior)51 void ClipLayer::SetClip(double left, double right, double top, double bottom, Clip clipBehavior)
52 {
53 rrect_.sk_rrect = SkRRect::MakeRect(SkRect::MakeLTRB(static_cast<SkScalar>(left), static_cast<SkScalar>(top),
54 static_cast<SkScalar>(right), static_cast<SkScalar>(bottom)));
55 clipBehavior_ = clipBehavior;
56 isPath_ = false;
57 }
58
SetClipRRect(const RRect & rrect,Clip clipBehavior)59 void ClipLayer::SetClipRRect(const RRect& rrect, Clip clipBehavior)
60 {
61 Rect rect = rrect.GetRect();
62 SkVector radii[4] = { { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } };
63 radii[SkRRect::kUpperLeft_Corner] = GetSkRadii(rrect.GetCorner().topLeftRadius);
64 radii[SkRRect::kUpperRight_Corner] = GetSkRadii(rrect.GetCorner().topRightRadius);
65 radii[SkRRect::kLowerLeft_Corner] = GetSkRadii(rrect.GetCorner().bottomLeftRadius);
66 radii[SkRRect::kLowerRight_Corner] = GetSkRadii(rrect.GetCorner().bottomRightRadius);
67 rrect_.sk_rrect.setRectRadii(SkRect::MakeXYWH(rect.Left(), rect.Top(), rect.Width(), rect.Height()), radii);
68 clipBehavior_ = clipBehavior;
69 isPath_ = false;
70 }
71
SetClipRRect(const Rect & rect,double x,double y,Clip clipBehavior)72 void ClipLayer::SetClipRRect(const Rect& rect, double x, double y, Clip clipBehavior)
73 {
74 rrect_.sk_rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(rect.Left(), rect.Top(), rect.Width(), rect.Height()),
75 SkDoubleToScalar(x), SkDoubleToScalar(y));
76 clipBehavior_ = clipBehavior;
77 isPath_ = false;
78 }
79
SetClipRRect(const flutter::RRect & rrect)80 void ClipLayer::SetClipRRect(const flutter::RRect& rrect)
81 {
82 rrect_.sk_rrect = rrect.sk_rrect;
83 isPath_ = false;
84 }
85
SetClipPath(const fml::RefPtr<flutter::CanvasPath> & canvasPath,Clip clipBehavior)86 void ClipLayer::SetClipPath(const fml::RefPtr<flutter::CanvasPath>& canvasPath, Clip clipBehavior)
87 {
88 canvasPath_ = canvasPath;
89 clipBehavior_ = clipBehavior;
90 isPath_ = true;
91 }
92
SetClipPath(const fml::RefPtr<flutter::CanvasPath> & canvasPath)93 void ClipLayer::SetClipPath(const fml::RefPtr<flutter::CanvasPath>& canvasPath)
94 {
95 canvasPath_ = canvasPath;
96 isPath_ = true;
97 }
98
GetSkRadii(const Radius & radius)99 SkVector ClipLayer::GetSkRadii(const Radius& radius)
100 {
101 SkVector fRadii;
102 fRadii.set(
103 SkDoubleToScalar(std::max(radius.GetX().Value(), 0.0)), SkDoubleToScalar(std::max(radius.GetY().Value(), 0.0)));
104 return fRadii;
105 }
106
CancelMask()107 void ClipLayer::CancelMask()
108 {
109 isMask_ = false;
110 }
111
SetSvgMask(const sk_sp<SkSVGDOM> & svgDom,double x,double y,double scaleX,double scaleY)112 void ClipLayer::SetSvgMask(const sk_sp<SkSVGDOM>& svgDom, double x, double y, double scaleX, double scaleY)
113 {
114 isMask_ = true;
115 isSvgMask_ = true;
116 isGradientMask_ = false;
117 isPathMask_ = false;
118
119 svgX_ = x;
120 svgY_ = y;
121 scaleX_ = scaleX;
122 scaleY_ = scaleY;
123 svgDom_ = svgDom;
124 }
125
SetColorMask(const SkPaint & maskPaint)126 void ClipLayer::SetColorMask(const SkPaint& maskPaint)
127 {
128 isMask_ = true;
129 isSvgMask_ = false;
130 isGradientMask_ = true;
131 isPathMask_ = false;
132 maskPaint_ = maskPaint;
133 }
134
SetPathMask(const SkPaint & maskPaint,const SkPath & path)135 void ClipLayer::SetPathMask(const SkPaint& maskPaint, const SkPath& path)
136 {
137 isMask_ = true;
138 isSvgMask_ = false;
139 isGradientMask_ = false;
140 isPathMask_ = true;
141 maskPaint_ = maskPaint;
142 maskPath_ = path;
143 }
144
Dump()145 void ClipLayer::Dump()
146 {
147 OffsetLayer::Dump();
148 if (DumpLog::GetInstance().GetDumpFile()) {
149 SkRect rect = rrect_.sk_rrect.getBounds();
150 DumpLog::GetInstance().AddDesc(
151 "ClipRect: (", rect.left(), ",", rect.top(), ") -", rect.width(), "x", rect.height());
152 SkVector leftTop = rrect_.sk_rrect.radii(SkRRect::Corner::kUpperLeft_Corner);
153 SkVector rightTop = rrect_.sk_rrect.radii(SkRRect::Corner::kUpperRight_Corner);
154 SkVector leftBottom = rrect_.sk_rrect.radii(SkRRect::Corner::kLowerLeft_Corner);
155 SkVector rightBottom = rrect_.sk_rrect.radii(SkRRect::Corner::kLowerRight_Corner);
156 DumpLog::GetInstance().AddDesc("leftTopCorner: (", leftTop.fX, ",", leftTop.fY, ")", "rightTopCorner: (",
157 rightTop.fX, ",", rightTop.fY, ")");
158 DumpLog::GetInstance().AddDesc("leftBottomCorner: (", leftBottom.fX, ",", leftBottom.fY, ")",
159 "rightBottomCorner: (", rightBottom.fX, ",", rightBottom.fY, ")");
160 }
161 }
162
163 } // namespace OHOS::Ace::Flutter
164