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 if (maskPath_ != nullptr) {
234 out += " path[isValid:" + std::to_string(maskPath_->IsValid());
235 auto bounds = maskPath_->GetBounds();
236 out += " bounds[top:" + std::to_string(bounds.GetTop()) + " bottom:" + std::to_string(bounds.GetBottom());
237 out += " left:" + std::to_string(bounds.GetLeft()) + " right:" + std::to_string(bounds.GetRight()) + "]";
238 out += " drawingType:" + std::to_string(static_cast<int>(maskPath_->GetDrawingType())) + "]";
239 }
240 if (pixelMap_ != nullptr) {
241 out += " pixelMap[width:" + std::to_string(pixelMap_->GetWidth());
242 out += " height:" + std::to_string(pixelMap_->GetHeight());
243 out += " byteCount:" + std::to_string(pixelMap_->GetByteCount()) + "]";
244 }
245 if (image_ != nullptr) {
246 out += " image";
247 image_->Dump(out);
248 }
249 out += ']';
250 }
251
252 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel) const253 bool RSMask::Marshalling(Parcel& parcel) const
254 {
255 if (!(RSMarshallingHelper::Marshalling(parcel, type_) &&
256 RSMarshallingHelper::Marshalling(parcel, svgX_) &&
257 RSMarshallingHelper::Marshalling(parcel, svgY_) &&
258 RSMarshallingHelper::Marshalling(parcel, scaleX_) &&
259 RSMarshallingHelper::Marshalling(parcel, scaleY_))) {
260 ROSEN_LOGE("RSMask::Marshalling failed!");
261 return false;
262 }
263
264 if (!MarshallingPathAndBrush(parcel)) {
265 ROSEN_LOGE("RSMask::Marshalling failed!");
266 return false;
267 }
268
269 if (IsPixelMapMask() && !RSMarshallingHelper::Marshalling(parcel, pixelMap_)) {
270 ROSEN_LOGE("RSMask::Marshalling Pixelmap failed!");
271 return false;
272 }
273 return true;
274 }
275
MarshallingPathAndBrush(Parcel & parcel) const276 bool RSMask::MarshallingPathAndBrush(Parcel& parcel) const
277 {
278 Drawing::CmdListData listData;
279 auto maskCmdList = Drawing::MaskCmdList::CreateFromData(listData, true);
280 Drawing::Filter filter = maskBrush_.GetFilter();
281 Drawing::BrushHandle brushHandle = {
282 maskBrush_.GetColor(),
283 maskBrush_.GetBlendMode(),
284 maskBrush_.IsAntiAlias(),
285 maskBrush_.GetBlenderEnabled(),
286 filter.GetFilterQuality(),
287 Drawing::CmdListHelper::AddColorSpaceToCmdList(*maskCmdList,
288 maskBrush_.GetColorSpace()),
289 Drawing::CmdListHelper::AddShaderEffectToCmdList(*maskCmdList,
290 maskBrush_.GetShaderEffect()),
291 Drawing::CmdListHelper::AddColorFilterToCmdList(*maskCmdList,
292 filter.GetColorFilter()),
293 Drawing::CmdListHelper::AddImageFilterToCmdList(*maskCmdList,
294 filter.GetImageFilter()),
295 Drawing::CmdListHelper::AddMaskFilterToCmdList(*maskCmdList,
296 filter.GetMaskFilter()),
297 };
298 maskCmdList->AddOp<Drawing::MaskBrushOpItem>(brushHandle);
299
300 Drawing::PenHandle penHandle = {
301 maskPen_.GetWidth(),
302 maskPen_.GetMiterLimit(),
303 maskPen_.GetCapStyle(),
304 maskPen_.GetJoinStyle(),
305 Drawing::CmdListHelper::AddPathEffectToCmdList(*maskCmdList,
306 maskPen_.GetPathEffect()),
307 maskPen_.GetColor(),
308 };
309 maskCmdList->AddOp<Drawing::MaskPenOpItem>(penHandle);
310
311 auto pathHandle = Drawing::CmdListHelper::AddPathToCmdList(*maskCmdList, *maskPath_);
312 maskCmdList->AddOp<Drawing::MaskPathOpItem>(pathHandle);
313
314 if (!RSMarshallingHelper::Marshalling(parcel, maskCmdList)) {
315 ROSEN_LOGE("RSMask::MarshallingPathAndBrush failed!");
316 return false;
317 }
318 return true;
319 }
320
Unmarshalling(Parcel & parcel)321 RSMask* RSMask::Unmarshalling(Parcel& parcel)
322 {
323 auto rsMask = std::make_unique<RSMask>();
324 if (!(RSMarshallingHelper::Unmarshalling(parcel, rsMask->type_) &&
325 RSMarshallingHelper::Unmarshalling(parcel, rsMask->svgX_) &&
326 RSMarshallingHelper::Unmarshalling(parcel, rsMask->svgY_) &&
327 RSMarshallingHelper::Unmarshalling(parcel, rsMask->scaleX_) &&
328 RSMarshallingHelper::Unmarshalling(parcel, rsMask->scaleY_))) {
329 ROSEN_LOGE("RSMask::Unmarshalling failed!");
330 return nullptr;
331 }
332
333 std::shared_ptr<Drawing::MaskCmdList> maskCmdList = nullptr;
334 if (!RSMarshallingHelper::Unmarshalling(parcel, maskCmdList)) {
335 ROSEN_LOGE("RSMask::Unmarshalling failed!");
336 return nullptr;
337 }
338 if (maskCmdList) {
339 maskCmdList->Playback(rsMask->maskPath_, rsMask->maskPen_, rsMask->maskBrush_);
340 }
341
342 if (rsMask->IsPixelMapMask() && !RSMarshallingHelper::Unmarshalling(parcel, rsMask->pixelMap_)) {
343 ROSEN_LOGE("RSMask::Unmarshalling pixelmap failed!");
344 return nullptr;
345 }
346
347 if (!rsMask->image_ && rsMask->pixelMap_) {
348 rsMask->image_ = RSPixelMapUtil::ExtractDrawingImage(rsMask->pixelMap_);
349 }
350 return rsMask.release();
351 }
352 #endif
353 } // namespace Rosen
354 } // namespace OHOS