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