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 #include "recording/mask_cmd_list.h"
23 #include "recording/cmd_list_helper.h"
24 #include "effect/shader_effect.h"
25 #include "platform/common/rs_log.h"
26 #include "render/rs_pixel_map_util.h"
27
28 namespace OHOS {
29 namespace Rosen {
CreateGradientMask(const Drawing::Brush & maskBrush)30 std::shared_ptr<RSMask> RSMask::CreateGradientMask(const Drawing::Brush& maskBrush)
31 {
32 auto mask = std::make_shared<RSMask>();
33 if (mask) {
34 mask->SetMaskBrush(maskBrush);
35 mask->SetMaskType(MaskType::GRADIENT);
36 }
37 return mask;
38 }
39
CreatePathMask(const Drawing::Path & maskPath,const Drawing::Brush & maskBrush)40 std::shared_ptr<RSMask> RSMask::CreatePathMask(const Drawing::Path& maskPath, const Drawing::Brush& maskBrush)
41 {
42 auto mask = std::make_shared<RSMask>();
43 if (mask) {
44 mask->SetMaskPath(maskPath);
45 mask->SetMaskBrush(maskBrush);
46 mask->SetMaskType(MaskType::PATH);
47 }
48 return mask;
49 }
50
CreatePathMask(const Drawing::Path & maskPath,const Drawing::Pen & maskPen,const Drawing::Brush & maskBrush)51 std::shared_ptr<RSMask> RSMask::CreatePathMask(
52 const Drawing::Path& maskPath, const Drawing::Pen& maskPen, const Drawing::Brush& maskBrush)
53 {
54 auto mask = std::make_shared<RSMask>();
55 if (mask) {
56 mask->SetMaskPath(maskPath);
57 mask->SetMaskPen(maskPen);
58 mask->SetMaskBrush(maskBrush);
59 mask->SetMaskType(MaskType::PATH);
60 }
61 return mask;
62 }
63
CreateSVGMask(double x,double y,double scaleX,double scaleY,const sk_sp<SkSVGDOM> & svgDom)64 std::shared_ptr<RSMask> RSMask::CreateSVGMask(double x, double y, double scaleX, double scaleY,
65 const sk_sp<SkSVGDOM>& svgDom)
66 {
67 auto mask = std::make_shared<RSMask>();
68 if (mask) {
69 mask->SetSvgX(x);
70 mask->SetSvgY(y);
71 mask->SetScaleX(scaleX);
72 mask->SetScaleY(scaleY);
73 mask->SetSvgDom(svgDom);
74 mask->SetMaskType(MaskType::SVG);
75 }
76 return mask;
77 }
78
CreatePixelMapMask(const std::shared_ptr<Media::PixelMap> pixelMap)79 std::shared_ptr<RSMask> RSMask::CreatePixelMapMask(const std::shared_ptr<Media::PixelMap> pixelMap)
80 {
81 auto mask = std::make_shared<RSMask>();
82 if (mask) {
83 mask->SetPixelMap(pixelMap);
84 mask->SetMaskType(MaskType::PIXEL_MAP);
85 }
86 return mask;
87 }
88
RSMask()89 RSMask::RSMask()
90 {
91 maskPath_ = std::make_shared<Drawing::Path>();
92 }
93
~RSMask()94 RSMask::~RSMask()
95 {
96 }
97
SetSvgX(double x)98 void RSMask::SetSvgX(double x)
99 {
100 svgX_ = x;
101 }
102
GetSvgX() const103 double RSMask::GetSvgX() const
104 {
105 return svgX_;
106 }
107
SetSvgY(double y)108 void RSMask::SetSvgY(double y)
109 {
110 svgY_ = y;
111 }
112
GetSvgY() const113 double RSMask::GetSvgY() const
114 {
115 return svgY_;
116 }
117
SetScaleX(double scaleX)118 void RSMask::SetScaleX(double scaleX)
119 {
120 scaleX_ = scaleX;
121 }
122
GetScaleX() const123 double RSMask::GetScaleX() const
124 {
125 return scaleX_;
126 }
127
SetScaleY(double scaleY)128 void RSMask::SetScaleY(double scaleY)
129 {
130 scaleY_ = scaleY;
131 }
132
GetScaleY() const133 double RSMask::GetScaleY() const
134 {
135 return scaleY_;
136 }
137
SetMaskPath(const Drawing::Path & path)138 void RSMask::SetMaskPath(const Drawing::Path& path)
139 {
140 maskPath_ = std::make_shared<Drawing::Path>(path);
141 }
142
GetMaskPath() const143 std::shared_ptr<Drawing::Path> RSMask::GetMaskPath() const
144 {
145 return maskPath_;
146 }
147
SetMaskPen(const Drawing::Pen & pen)148 void RSMask::SetMaskPen(const Drawing::Pen& pen)
149 {
150 maskPen_ = pen;
151 }
152
GetMaskPen() const153 Drawing::Pen RSMask::GetMaskPen() const
154 {
155 return maskPen_;
156 }
157
SetMaskBrush(const Drawing::Brush & brush)158 void RSMask::SetMaskBrush(const Drawing::Brush& brush)
159 {
160 maskBrush_ = brush;
161 }
162
GetMaskBrush() const163 Drawing::Brush RSMask::GetMaskBrush() const
164 {
165 return maskBrush_;
166 }
167
SetSvgDom(const sk_sp<SkSVGDOM> & svgDom)168 void RSMask::SetSvgDom(const sk_sp<SkSVGDOM>& svgDom)
169 {
170 svgDom_ = svgDom;
171 }
172
GetSvgDom() const173 sk_sp<SkSVGDOM> RSMask::GetSvgDom() const
174 {
175 return svgDom_;
176 }
177
GetSvgPicture() const178 std::shared_ptr<Drawing::Picture> RSMask::GetSvgPicture() const
179 {
180 return svgPicture_;
181 }
182
SetMaskType(MaskType type)183 void RSMask::SetMaskType(MaskType type)
184 {
185 type_ = type;
186 }
187
SetPixelMap(const std::shared_ptr<Media::PixelMap> pixelMap)188 void RSMask::SetPixelMap(const std::shared_ptr<Media::PixelMap> pixelMap)
189 {
190 pixelMap_ = pixelMap;
191 image_ = RSPixelMapUtil::ExtractDrawingImage(pixelMap_);
192 }
193
GetPixelMap() const194 std::shared_ptr<Media::PixelMap> RSMask::GetPixelMap() const
195 {
196 return pixelMap_;
197 }
198
GetImage() const199 std::shared_ptr<Drawing::Image> RSMask::GetImage() const
200 {
201 return image_;
202 }
203
IsSvgMask() const204 bool RSMask::IsSvgMask() const
205 {
206 return (type_ == MaskType::SVG);
207 }
208
IsGradientMask() const209 bool RSMask::IsGradientMask() const
210 {
211 return (type_ == MaskType::GRADIENT);
212 }
213
IsPixelMapMask() const214 bool RSMask::IsPixelMapMask() const
215 {
216 return (type_ == MaskType::PIXEL_MAP);
217 }
218
IsPathMask() const219 bool RSMask::IsPathMask() const
220 {
221 return (type_ == MaskType::PATH);
222 }
223
Dump(std::string & out) const224 void RSMask::Dump(std::string& out) const
225 {
226 out += "[maskType:" + std::to_string(static_cast<int>(type_));
227 out += " x:" + std::to_string(svgX_) + " y:" + std::to_string(svgY_);
228 out += " scaleX:" + std::to_string(scaleX_) + " scaleY:" + std::to_string(scaleY_);
229 out += " pen";
230 maskPen_.Dump(out);
231 out += " brush";
232 maskBrush_.Dump(out);
233 out += " path[";
234 if (maskPath_ != nullptr) {
235 out += "isValid:" + std::to_string(maskPath_->IsValid());
236 auto bounds = maskPath_->GetBounds();
237 out += " bounds[top:" + std::to_string(bounds.GetTop()) + " bottom:" + std::to_string(bounds.GetBottom());
238 out += " left:" + std::to_string(bounds.GetLeft()) + " right:" + std::to_string(bounds.GetRight()) + "]";
239 out += " drawingType:" + std::to_string(static_cast<int>(maskPath_->GetDrawingType()));
240 }
241 out += "] pixelMap[";
242 if (pixelMap_ != nullptr) {
243 out += "width:" + std::to_string(pixelMap_->GetWidth());
244 out += " height:" + std::to_string(pixelMap_->GetHeight());
245 out += " byteCount:" + std::to_string(pixelMap_->GetByteCount());
246 }
247 out += ']';
248 if (image_ != nullptr) {
249 out += " image";
250 image_->Dump(out);
251 }
252 out += ']';
253 }
254
255 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel) const256 bool RSMask::Marshalling(Parcel& parcel) const
257 {
258 if (!(RSMarshallingHelper::Marshalling(parcel, type_) &&
259 RSMarshallingHelper::Marshalling(parcel, svgX_) &&
260 RSMarshallingHelper::Marshalling(parcel, svgY_) &&
261 RSMarshallingHelper::Marshalling(parcel, scaleX_) &&
262 RSMarshallingHelper::Marshalling(parcel, scaleY_))) {
263 ROSEN_LOGE("RSMask::Marshalling failed!");
264 return false;
265 }
266
267 if (!MarshallingPathAndBrush(parcel)) {
268 ROSEN_LOGE("RSMask::Marshalling failed!");
269 return false;
270 }
271
272 if (IsPixelMapMask() && !RSMarshallingHelper::Marshalling(parcel, pixelMap_)) {
273 ROSEN_LOGE("RSMask::Marshalling Pixelmap failed!");
274 return false;
275 }
276 return true;
277 }
278
MarshallingPathAndBrush(Parcel & parcel) const279 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 maskBrush_.GetBlenderEnabled(),
289 filter.GetFilterQuality(),
290 Drawing::CmdListHelper::AddColorSpaceToCmdList(*maskCmdList,
291 maskBrush_.GetColorSpace()),
292 Drawing::CmdListHelper::AddShaderEffectToCmdList(*maskCmdList,
293 maskBrush_.GetShaderEffect()),
294 Drawing::CmdListHelper::AddColorFilterToCmdList(*maskCmdList,
295 filter.GetColorFilter()),
296 Drawing::CmdListHelper::AddImageFilterToCmdList(*maskCmdList,
297 filter.GetImageFilter()),
298 Drawing::CmdListHelper::AddMaskFilterToCmdList(*maskCmdList,
299 filter.GetMaskFilter()),
300 };
301 maskCmdList->AddOp<Drawing::MaskBrushOpItem>(brushHandle);
302
303 Drawing::PenHandle penHandle = {
304 maskPen_.GetWidth(),
305 maskPen_.GetMiterLimit(),
306 maskPen_.GetCapStyle(),
307 maskPen_.GetJoinStyle(),
308 Drawing::CmdListHelper::AddPathEffectToCmdList(*maskCmdList,
309 maskPen_.GetPathEffect()),
310 maskPen_.GetColor(),
311 };
312 maskCmdList->AddOp<Drawing::MaskPenOpItem>(penHandle);
313
314 auto pathHandle = Drawing::CmdListHelper::AddPathToCmdList(*maskCmdList, *maskPath_);
315 maskCmdList->AddOp<Drawing::MaskPathOpItem>(pathHandle);
316
317 if (!RSMarshallingHelper::Marshalling(parcel, maskCmdList)) {
318 ROSEN_LOGE("RSMask::MarshallingPathAndBrush failed!");
319 return false;
320 }
321 return true;
322 }
323
Unmarshalling(Parcel & parcel)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 RSMarshallingHelper::Unmarshalling(parcel, rsMask->scaleY_))) {
332 ROSEN_LOGE("RSMask::Unmarshalling failed!");
333 return nullptr;
334 }
335
336 std::shared_ptr<Drawing::MaskCmdList> maskCmdList = nullptr;
337 if (!RSMarshallingHelper::Unmarshalling(parcel, maskCmdList)) {
338 ROSEN_LOGE("RSMask::Unmarshalling failed!");
339 return nullptr;
340 }
341 if (maskCmdList) {
342 maskCmdList->Playback(rsMask->maskPath_, rsMask->maskPen_, rsMask->maskBrush_);
343 }
344
345 if (rsMask->IsPixelMapMask() && !RSMarshallingHelper::Unmarshalling(parcel, rsMask->pixelMap_)) {
346 ROSEN_LOGE("RSMask::Unmarshalling pixelmap failed!");
347 return nullptr;
348 }
349
350 if (!rsMask->image_ && rsMask->pixelMap_) {
351 rsMask->image_ = RSPixelMapUtil::ExtractDrawingImage(rsMask->pixelMap_);
352 }
353 return rsMask.release();
354 }
355 #endif
356 } // namespace Rosen
357 } // namespace OHOS