• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "render/rs_mask.h"
17 
18 #include "include/core/SkPictureRecorder.h"
19 #include "recording/recording_handle.h"
20 #include "draw/pen.h"
21 
22 #ifdef USE_ROSEN_DRAWING
23 #include "recording/mask_cmd_list.h"
24 #include "recording/cmd_list_helper.h"
25 #include "effect/shader_effect.h"
26 #endif
27 #include "platform/common/rs_log.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 #ifndef USE_ROSEN_DRAWING
CreateGradientMask(const SkPaint & maskPaint)32 std::shared_ptr<RSMask> RSMask::CreateGradientMask(const SkPaint& maskPaint)
33 #else
34 std::shared_ptr<RSMask> RSMask::CreateGradientMask(const Drawing::Brush& maskBrush)
35 #endif
36 {
37     auto mask = std::make_shared<RSMask>();
38     if (mask) {
39 #ifndef USE_ROSEN_DRAWING
40         mask->SetMaskPaint(maskPaint);
41 #else
42         mask->SetMaskBrush(maskBrush);
43 #endif
44         mask->SetMaskType(MaskType::GRADIENT);
45     }
46     return mask;
47 }
48 
49 #ifndef USE_ROSEN_DRAWING
CreatePathMask(const SkPath & maskPath,const SkPaint & maskPaint)50 std::shared_ptr<RSMask> RSMask::CreatePathMask(const SkPath& maskPath, const SkPaint& maskPaint)
51 #else
52 std::shared_ptr<RSMask> RSMask::CreatePathMask(const Drawing::Path& maskPath, const Drawing::Brush& maskBrush)
53 #endif
54 {
55     auto mask = std::make_shared<RSMask>();
56     if (mask) {
57         mask->SetMaskPath(maskPath);
58 #ifndef USE_ROSEN_DRAWING
59         mask->SetMaskPaint(maskPaint);
60 #else
61         mask->SetMaskBrush(maskBrush);
62 #endif
63         mask->SetMaskType(MaskType::PATH);
64     }
65     return mask;
66 }
67 
CreatePathMask(const Drawing::Path & maskPath,const Drawing::Pen & maskPen,const Drawing::Brush & maskBrush)68 std::shared_ptr<RSMask> RSMask::CreatePathMask(
69     const Drawing::Path& maskPath, const Drawing::Pen& maskPen, const Drawing::Brush& maskBrush)
70 {
71     auto mask = std::make_shared<RSMask>();
72     if (mask) {
73         mask->SetMaskPath(maskPath);
74         mask->SetMaskPen(maskPen);
75         mask->SetMaskBrush(maskBrush);
76         mask->SetMaskType(MaskType::PATH);
77     }
78     return mask;
79 }
80 
CreateSVGMask(double x,double y,double scaleX,double scaleY,const sk_sp<SkSVGDOM> & svgDom)81 std::shared_ptr<RSMask> RSMask::CreateSVGMask(double x, double y, double scaleX, double scaleY,
82     const sk_sp<SkSVGDOM>& svgDom)
83 {
84     auto mask = std::make_shared<RSMask>();
85     if (mask) {
86         mask->SetSvgX(x);
87         mask->SetSvgY(y);
88         mask->SetScaleX(scaleX);
89         mask->SetScaleY(scaleY);
90         mask->SetSvgDom(svgDom);
91         mask->SetMaskType(MaskType::SVG);
92     }
93     return mask;
94 }
95 
RSMask()96 RSMask::RSMask()
97 {
98 #ifdef USE_ROSEN_DRAWING
99     maskPath_ = std::make_shared<Drawing::Path>();
100 #endif
101 }
102 
~RSMask()103 RSMask::~RSMask()
104 {
105 }
106 
SetSvgX(double x)107 void RSMask::SetSvgX(double x)
108 {
109     svgX_ = x;
110 }
111 
GetSvgX() const112 double RSMask::GetSvgX() const
113 {
114     return svgX_;
115 }
116 
SetSvgY(double y)117 void RSMask::SetSvgY(double y)
118 {
119     svgY_ = y;
120 }
121 
GetSvgY() const122 double RSMask::GetSvgY() const
123 {
124     return svgY_;
125 }
126 
SetScaleX(double scaleX)127 void RSMask::SetScaleX(double scaleX)
128 {
129     scaleX_ = scaleX;
130 }
131 
GetScaleX() const132 double RSMask::GetScaleX() const
133 {
134     return scaleX_;
135 }
136 
SetScaleY(double scaleY)137 void RSMask::SetScaleY(double scaleY)
138 {
139     scaleY_ = scaleY;
140 }
141 
GetScaleY() const142 double RSMask::GetScaleY() const
143 {
144     return scaleY_;
145 }
146 
147 #ifndef USE_ROSEN_DRAWING
SetMaskPath(const SkPath & path)148 void RSMask::SetMaskPath(const SkPath& path)
149 {
150     maskPath_ = path;
151 }
152 #else
SetMaskPath(const Drawing::Path & path)153 void RSMask::SetMaskPath(const Drawing::Path& path)
154 {
155     maskPath_ = std::make_shared<Drawing::Path>(path);
156 }
157 #endif
158 
159 #ifndef USE_ROSEN_DRAWING
GetMaskPath() const160 SkPath RSMask::GetMaskPath() const
161 #else
162 std::shared_ptr<Drawing::Path> RSMask::GetMaskPath() const
163 #endif
164 {
165     return maskPath_;
166 }
167 
168 #ifndef USE_ROSEN_DRAWING
SetMaskPaint(const SkPaint & paint)169 void RSMask::SetMaskPaint(const SkPaint& paint)
170 {
171     maskPaint_ = paint;
172 }
173 
GetMaskPaint() const174 SkPaint RSMask::GetMaskPaint() const
175 {
176     return maskPaint_;
177 }
178 #else
SetMaskPen(const Drawing::Pen & pen)179 void RSMask::SetMaskPen(const Drawing::Pen& pen)
180 {
181     maskPen_ = pen;
182 }
183 
GetMaskPen() const184 Drawing::Pen RSMask::GetMaskPen() const
185 {
186     return maskPen_;
187 }
188 
SetMaskBrush(const Drawing::Brush & brush)189 void RSMask::SetMaskBrush(const Drawing::Brush& brush)
190 {
191     maskBrush_ = brush;
192 }
193 
GetMaskBrush() const194 Drawing::Brush RSMask::GetMaskBrush() const
195 {
196     return maskBrush_;
197 }
198 #endif
199 
SetSvgDom(const sk_sp<SkSVGDOM> & svgDom)200 void RSMask::SetSvgDom(const sk_sp<SkSVGDOM>& svgDom)
201 {
202     svgDom_ = svgDom;
203 }
204 
GetSvgDom() const205 sk_sp<SkSVGDOM> RSMask::GetSvgDom() const
206 {
207     return svgDom_;
208 }
209 
210 #ifndef USE_ROSEN_DRAWING
GetSvgPicture() const211 sk_sp<SkPicture> RSMask::GetSvgPicture() const
212 #else
213 std::shared_ptr<Drawing::Picture> RSMask::GetSvgPicture() const
214 #endif
215 {
216     return svgPicture_;
217 }
218 
SetMaskType(MaskType type)219 void RSMask::SetMaskType(MaskType type)
220 {
221     type_ = type;
222 }
223 
IsSvgMask() const224 bool RSMask::IsSvgMask() const
225 {
226     return (type_ == MaskType::SVG);
227 }
228 
IsGradientMask() const229 bool RSMask::IsGradientMask() const
230 {
231     return (type_ == MaskType::GRADIENT);
232 }
233 
IsPathMask() const234 bool RSMask::IsPathMask() const
235 {
236     return (type_ == MaskType::PATH);
237 }
238 
239 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel) const240 bool RSMask::Marshalling(Parcel& parcel) const
241 {
242     if (!(RSMarshallingHelper::Marshalling(parcel, type_) &&
243             RSMarshallingHelper::Marshalling(parcel, svgX_) &&
244             RSMarshallingHelper::Marshalling(parcel, svgY_) &&
245             RSMarshallingHelper::Marshalling(parcel, scaleX_) &&
246 #ifndef USE_ROSEN_DRAWING
247             RSMarshallingHelper::Marshalling(parcel, scaleY_) &&
248             RSMarshallingHelper::Marshalling(parcel, maskPaint_) &&
249             RSMarshallingHelper::Marshalling(parcel, maskPath_))) {
250 #else
251             RSMarshallingHelper::Marshalling(parcel, scaleY_))) {
252 #endif
253         ROSEN_LOGE("RSMask::Marshalling failed!");
254         return false;
255     }
256 
257 #ifdef USE_ROSEN_DRAWING
258     if (!MarshallingPathAndBrush(parcel)) {
259         ROSEN_LOGE("RSMask::Marshalling failed!");
260         return false;
261     }
262 #endif
263 
264     if (IsSvgMask()) {
265         ROSEN_LOGD("SVG RSMask::Marshalling");
266         SkPictureRecorder recorder;
267         SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::MakeSize(svgDom_->containerSize()));
268         svgDom_->render(recordingCanvas);
269         sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
270         if (!RSMarshallingHelper::Marshalling(parcel, picture)) {
271             ROSEN_LOGE("RSMask::Marshalling SkPicture failed!");
272             return false;
273         }
274     }
275     return true;
276 }
277 
278 #ifdef USE_ROSEN_DRAWING
279 bool RSMask::MarshallingPathAndBrush(Parcel& parcel) const
280 {
281     Drawing::CmdListData listData;
282     auto maskCmdList = Drawing::MaskCmdList::CreateFromData(listData, true);
283     Drawing::Filter filter = maskBrush_.GetFilter();
284     Drawing::BrushHandle brushHandle = {
285         maskBrush_.GetColor(),
286         maskBrush_.GetBlendMode(),
287         maskBrush_.IsAntiAlias(),
288         filter.GetFilterQuality(),
289         Drawing::CmdListHelper::AddColorSpaceToCmdList(*maskCmdList,
290             maskBrush_.GetColorSpace()),
291         Drawing::CmdListHelper::AddShaderEffectToCmdList(*maskCmdList,
292             maskBrush_.GetShaderEffect()),
293         Drawing::CmdListHelper::AddColorFilterToCmdList(*maskCmdList,
294             filter.GetColorFilter()),
295         Drawing::CmdListHelper::AddImageFilterToCmdList(*maskCmdList,
296             filter.GetImageFilter()),
297         Drawing::CmdListHelper::AddMaskFilterToCmdList(*maskCmdList,
298             filter.GetMaskFilter()),
299     };
300     maskCmdList->AddOp<Drawing::MaskBrushOpItem>(brushHandle);
301 
302     Drawing::PenHandle penHandle = {
303         maskPen_.GetWidth(),
304         maskPen_.GetMiterLimit(),
305         maskPen_.GetCapStyle(),
306         maskPen_.GetJoinStyle(),
307         Drawing::CmdListHelper::AddPathEffectToCmdList(*maskCmdList,
308             maskPen_.GetPathEffect()),
309         maskPen_.GetColor(),
310     };
311     maskCmdList->AddOp<Drawing::MaskPenOpItem>(penHandle);
312 
313     auto pathHandle = Drawing::CmdListHelper::AddPathToCmdList(*maskCmdList, *maskPath_);
314     maskCmdList->AddOp<Drawing::MaskPathOpItem>(pathHandle);
315 
316     if (!RSMarshallingHelper::Marshalling(parcel, maskCmdList)) {
317         ROSEN_LOGE("RSMask::MarshallingPathAndBrush failed!");
318         return false;
319     }
320     return true;
321 }
322 #endif
323 
324 RSMask* RSMask::Unmarshalling(Parcel& parcel)
325 {
326     auto rsMask = std::make_unique<RSMask>();
327     if (!(RSMarshallingHelper::Unmarshalling(parcel, rsMask->type_) &&
328             RSMarshallingHelper::Unmarshalling(parcel, rsMask->svgX_) &&
329             RSMarshallingHelper::Unmarshalling(parcel, rsMask->svgY_) &&
330             RSMarshallingHelper::Unmarshalling(parcel, rsMask->scaleX_) &&
331 #ifndef USE_ROSEN_DRAWING
332             RSMarshallingHelper::Unmarshalling(parcel, rsMask->scaleY_) &&
333             RSMarshallingHelper::Unmarshalling(parcel, rsMask->maskPaint_) &&
334             RSMarshallingHelper::Unmarshalling(parcel, rsMask->maskPath_))) {
335 #else
336             RSMarshallingHelper::Unmarshalling(parcel, rsMask->scaleY_))) {
337 #endif
338         ROSEN_LOGE("RSMask::Unmarshalling failed!");
339         return nullptr;
340     }
341 
342 #ifdef USE_ROSEN_DRAWING
343     std::shared_ptr<Drawing::MaskCmdList> maskCmdList = nullptr;
344     if (!RSMarshallingHelper::Unmarshalling(parcel, maskCmdList)) {
345         ROSEN_LOGE("RSMask::Unmarshalling failed!");
346         return nullptr;
347     }
348     if (maskCmdList) {
349         maskCmdList->Playback(rsMask->maskPath_, rsMask->maskPen_, rsMask->maskBrush_);
350     }
351 #endif
352 
353     if (rsMask->IsSvgMask()) {
354         ROSEN_LOGD("SVG RSMask::Unmarshalling");
355         if (!RSMarshallingHelper::Unmarshalling(parcel, rsMask->svgPicture_)) {
356             ROSEN_LOGE("RSMask::Unmarshalling SkPicture failed!");
357             return nullptr;
358         }
359     }
360     return rsMask.release();
361 }
362 #endif
363 } // namespace Rosen
364 } // namespace OHOS