1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.. All rights reserved.
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 "skia_canvas.h"
17 
18 #include "modules/svg/include/SkSVGDOM.h"
19 
20 #ifdef RS_ENABLE_GPU
21 #include "skia_gpu_context.h"
22 #endif
23 #include "skia_convert_utils.h"
24 #include "skia_image_filter.h"
25 #include "skia_path.h"
26 #include "skia_image_info.h"
27 #include "skia_data.h"
28 #include "skia_text_blob.h"
29 #include "skia_surface.h"
30 #include "include/effects/SkRuntimeEffect.h"
31 #include "skia_canvas_autocache.h"
32 #include "skia_oplist_handle.h"
33 
34 #include "draw/core_canvas.h"
35 #include "draw/canvas.h"
36 #include "image/bitmap.h"
37 #include "image/image.h"
38 #include "utils/log.h"
39 #include "utils/performanceCaculate.h"
40 #include "SkOverdrawCanvas.h"
41 #include "include/utils/SkNoDrawCanvas.h"
42 
43 namespace OHOS {
44 namespace Rosen {
45 namespace Drawing {
SkiaCanvas()46 SkiaCanvas::SkiaCanvas() : skiaCanvas_(std::make_shared<SkCanvas>())
47 {
48     skCanvas_ = skiaCanvas_.get();
49 }
50 
SkiaCanvas(const std::shared_ptr<SkCanvas> & skCanvas)51 SkiaCanvas::SkiaCanvas(const std::shared_ptr<SkCanvas>& skCanvas) : skiaCanvas_(skCanvas)
52 {
53     skCanvas_ = skiaCanvas_.get();
54 }
55 
SkiaCanvas(int32_t width,int32_t height)56 SkiaCanvas::SkiaCanvas(int32_t width, int32_t height)
57     : skiaCanvas_(std::make_shared<SkCanvas>(width, height))
58 {
59     skCanvas_ = skiaCanvas_.get();
60 }
61 
ExportSkCanvas() const62 SkCanvas* SkiaCanvas::ExportSkCanvas() const
63 {
64     return skCanvas_;
65 }
66 
ImportSkCanvas(SkCanvas * skCanvas)67 void SkiaCanvas::ImportSkCanvas(SkCanvas* skCanvas)
68 {
69     skCanvas_ = skCanvas;
70 }
71 
Bind(const Bitmap & bitmap)72 void SkiaCanvas::Bind(const Bitmap& bitmap)
73 {
74     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
75     if (skBitmapImpl != nullptr) {
76         skiaCanvas_ = std::make_shared<SkCanvas>(skBitmapImpl->ExportSkiaBitmap());
77         skCanvas_ = skiaCanvas_.get();
78     }
79 }
80 
GetTotalMatrix() const81 Matrix SkiaCanvas::GetTotalMatrix() const
82 {
83     if (skCanvas_ == nullptr) {
84         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
85         return Matrix();
86     }
87     Matrix matrix;
88     matrix.GetImpl<SkiaMatrix>()->ImportMatrix(skCanvas_->getTotalMatrix());
89     return matrix;
90 }
91 
GetLocalClipBounds() const92 Rect SkiaCanvas::GetLocalClipBounds() const
93 {
94     if (skCanvas_ == nullptr) {
95         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
96         return Rect();
97     }
98     auto rect = skCanvas_->getLocalClipBounds();
99     return Rect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
100 }
101 
GetDeviceClipBounds() const102 RectI SkiaCanvas::GetDeviceClipBounds() const
103 {
104     if (skCanvas_ == nullptr) {
105         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
106         return RectI();
107     }
108     auto iRect = skCanvas_->getDeviceClipBounds();
109     return RectI(iRect.fLeft, iRect.fTop, iRect.fRight, iRect.fBottom);
110 }
111 
GetRoundInDeviceClipBounds() const112 RectI SkiaCanvas::GetRoundInDeviceClipBounds() const
113 {
114     if (skCanvas_ == nullptr) {
115         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
116         return RectI();
117     }
118     auto iRect = skCanvas_->getRoundInDeviceClipBounds();
119     return RectI(iRect.fLeft, iRect.fTop, iRect.fRight, iRect.fBottom);
120 }
121 
122 #ifdef RS_ENABLE_GPU
GetGPUContext() const123 std::shared_ptr<GPUContext> SkiaCanvas::GetGPUContext() const
124 {
125     if (skCanvas_ == nullptr || skCanvas_->recordingContext() == nullptr ||
126         GrAsDirectContext(skCanvas_->recordingContext()) == nullptr) {
127         LOGD("skCanvas_ or grContext is null, return on line %{public}d", __LINE__);
128         return nullptr;
129     }
130     auto grContext = GrAsDirectContext(skCanvas_->recordingContext());
131 
132     auto gpuContext = std::make_shared<GPUContext>();
133     gpuContext->GetImpl<SkiaGPUContext>()->SetGrContext(sk_ref_sp(grContext));
134 
135     return gpuContext;
136 }
137 #endif
138 
GetWidth() const139 int32_t SkiaCanvas::GetWidth() const
140 {
141     return (skCanvas_ != nullptr) ? skCanvas_->imageInfo().width() : 0;
142 }
143 
GetHeight() const144 int32_t SkiaCanvas::GetHeight() const
145 {
146     return (skCanvas_ != nullptr) ? skCanvas_->imageInfo().height() : 0;
147 }
148 
GetImageInfo()149 ImageInfo SkiaCanvas::GetImageInfo()
150 {
151     if (skCanvas_ == nullptr) {
152         return {};
153     }
154     return SkiaImageInfo::ConvertToRSImageInfo(skCanvas_->imageInfo());
155 }
156 
ReadPixels(const ImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY)157 bool SkiaCanvas::ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
158     int srcX, int srcY)
159 {
160     if (!skCanvas_) {
161         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
162         return false;
163     }
164     auto colorSpace = dstInfo.GetColorSpace();
165     auto colorSpaceImpl = colorSpace ? colorSpace->GetImpl<SkiaColorSpace>() : nullptr;
166     SkImageInfo info = SkImageInfo::Make(dstInfo.GetWidth(), dstInfo.GetHeight(),
167                                          SkiaImageInfo::ConvertToSkColorType(dstInfo.GetColorType()),
168                                          SkiaImageInfo::ConvertToSkAlphaType(dstInfo.GetAlphaType()),
169                                          colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : nullptr);
170     return skCanvas_->readPixels(info, dstPixels, dstRowBytes, srcX, srcY);
171 }
172 
ReadPixels(const Bitmap & dstBitmap,int srcX,int srcY)173 bool SkiaCanvas::ReadPixels(const Bitmap& dstBitmap, int srcX, int srcY)
174 {
175     if (!skCanvas_) {
176         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
177         return false;
178     }
179     const SkBitmap& skBitmap = dstBitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
180     return skCanvas_->readPixels(skBitmap, srcX, srcY);
181 }
182 
DrawSdf(const SDFShapeBase & shape)183 void SkiaCanvas::DrawSdf(const SDFShapeBase& shape)
184 {
185     std::string shaderString = shape.Getshader();
186     if (skCanvas_ == nullptr || skCanvas_->getSurface() == nullptr || shaderString.size() == 0) {
187         LOGE("skCanvas_ or surface is null, or sdf shape is empty. return on line %{public}d", __LINE__);
188         return;
189     }
190 
191     SkAutoCanvasRestore acr(skCanvas_, true);
192     auto [effect, err] = SkRuntimeEffect::MakeForShader(static_cast<SkString>(shaderString));
193     if (effect == nullptr) {
194         LOGE("sdf make shader fail : %{public}s", err.c_str());
195         return;
196     }
197     float width = skCanvas_->imageInfo().width();
198     SkRuntimeShaderBuilder builder(effect);
199     if (shape.GetParaNum() > 0) {
200         std::vector<float> para = shape.GetPara();
201         std::vector<float> para1 = shape.GetTransPara();
202         uint64_t num1 = para1.size();
203         uint64_t num = para.size();
204         for (uint64_t i = 1; i <= num; i++) {
205             char buf[10] = {0}; // maximum length of string needed is 10.
206             (void)sprintf_s(buf, sizeof(buf), "para%lu", i);
207             builder.uniform(buf) = para[i-1];
208         }
209         for (uint64_t i = 1; i <= num1; i++) {
210             char buf[15] = {0}; // maximum length of string needed is 15.
211             (void)sprintf_s(buf, sizeof(buf), "transpara%lu", i);
212             builder.uniform(buf) = para1[i-1];
213         }
214         std::vector<float> color = shape.GetColorPara();
215         builder.uniform("fillcolpara1") = color[0];
216         builder.uniform("fillcolpara2") = color[1]; // color_[1] is fillcolor green channel.
217         builder.uniform("fillcolpara3") = color[2]; // color_[2] is fillcolor blue channel.
218         builder.uniform("strokecolpara1") = color[3]; // color_[3] is strokecolor red channel.
219         builder.uniform("strokecolpara2") = color[4]; // color_[4] is strokecolor green channel.
220         builder.uniform("strokecolpara3") = color[5]; // color_[5] is strokecolor blue channel.
221         builder.uniform("sdfalpha") = color[6]; // color_[6] is color alpha channel.
222         builder.uniform("sdfsize") = shape.GetSize();
223         builder.uniform("filltype") = shape.GetFillType();
224         builder.uniform("translatex") = shape.GetTranslateX();
225         builder.uniform("translatey") = shape.GetTranslateY();
226     }
227     builder.uniform("width") = width;
228     auto shader = builder.makeShader(nullptr, false);
229     SkPaint paint;
230     paint.setShader(shader);
231     skCanvas_->drawPaint(paint);
232 }
233 
DrawPoint(const Point & point,const Paint & paint)234 void SkiaCanvas::DrawPoint(const Point& point, const Paint& paint)
235 {
236     if (!skCanvas_) {
237         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
238         return;
239     }
240     const SkPoint* skPoint = reinterpret_cast<const SkPoint*>(&point);
241     skPaint_ = defaultPaint_;
242     SkiaPaint::PaintToSkPaint(paint, skPaint_);
243     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
244     skCanvas_->drawPoint(*skPoint, skPaint_);
245 }
246 
DrawPoints(PointMode mode,size_t count,const Point pts[],const Paint & paint)247 void SkiaCanvas::DrawPoints(PointMode mode, size_t count, const Point pts[], const Paint& paint)
248 {
249     if (!skCanvas_) {
250         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
251         return;
252     }
253 
254     const SkPoint* skPts = reinterpret_cast<const SkPoint*>(pts);
255     skPaint_ = defaultPaint_;
256     SkiaPaint::PaintToSkPaint(paint, skPaint_);
257     skCanvas_->drawPoints(static_cast<SkCanvas::PointMode>(mode), count, skPts, skPaint_);
258 }
259 
DrawLine(const Point & startPt,const Point & endPt,const Paint & paint)260 void SkiaCanvas::DrawLine(const Point& startPt, const Point& endPt, const Paint& paint)
261 {
262     if (!skCanvas_) {
263         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
264         return;
265     }
266     const SkPoint* skStartPt = reinterpret_cast<const SkPoint*>(&startPt);
267     const SkPoint* skEndPt = reinterpret_cast<const SkPoint*>(&endPt);
268     skPaint_ = defaultPaint_;
269     SkiaPaint::PaintToSkPaint(paint, skPaint_);
270     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
271     skCanvas_->drawLine(*skStartPt, *skEndPt, skPaint_);
272 }
273 
DrawRect(const Rect & rect,const Paint & paint)274 void SkiaCanvas::DrawRect(const Rect& rect, const Paint& paint)
275 {
276     if (!skCanvas_) {
277         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
278         return;
279     }
280     const SkRect* skRect = reinterpret_cast<const SkRect*>(&rect);
281     skPaint_ = defaultPaint_;
282     SkiaPaint::PaintToSkPaint(paint, skPaint_);
283     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
284     skCanvas_->drawRect(*skRect, skPaint_);
285 }
286 
DrawRoundRect(const RoundRect & roundRect,const Paint & paint)287 void SkiaCanvas::DrawRoundRect(const RoundRect& roundRect, const Paint& paint)
288 {
289     if (!skCanvas_) {
290         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
291         return;
292     }
293     SkRRect rRect;
294     RoundRectCastToSkRRect(roundRect, rRect);
295     skPaint_ = defaultPaint_;
296     SkiaPaint::PaintToSkPaint(paint, skPaint_);
297     skCanvas_->drawRRect(rRect, skPaint_);
298 }
299 
DrawNestedRoundRect(const RoundRect & outer,const RoundRect & inner,const Paint & paint)300 void SkiaCanvas::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner, const Paint& paint)
301 {
302     if (!skCanvas_) {
303         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
304         return;
305     }
306     SkRRect outerRRect;
307     RoundRectCastToSkRRect(outer, outerRRect);
308 
309     SkRRect innerRRect;
310     RoundRectCastToSkRRect(inner, innerRRect);
311 
312     skPaint_ = defaultPaint_;
313     SkiaPaint::PaintToSkPaint(paint, skPaint_);
314     skCanvas_->drawDRRect(outerRRect, innerRRect, skPaint_);
315 }
316 
DrawArc(const Rect & oval,scalar startAngle,scalar sweepAngle,const Paint & paint)317 void SkiaCanvas::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint)
318 {
319     if (!skCanvas_) {
320         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
321         return;
322     }
323     const SkRect* arcRect = reinterpret_cast<const SkRect*>(&oval);
324     skPaint_ = defaultPaint_;
325     SkiaPaint::PaintToSkPaint(paint, skPaint_);
326     skCanvas_->drawArc(*arcRect, startAngle, sweepAngle, false, skPaint_);
327 }
328 
DrawPie(const Rect & oval,scalar startAngle,scalar sweepAngle,const Paint & paint)329 void SkiaCanvas::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint)
330 {
331     if (!skCanvas_) {
332         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
333         return;
334     }
335     const SkRect* pieRect = reinterpret_cast<const SkRect*>(&oval);
336     skPaint_ = defaultPaint_;
337     SkiaPaint::PaintToSkPaint(paint, skPaint_);
338     skCanvas_->drawArc(*pieRect, startAngle, sweepAngle, true, skPaint_);
339 }
340 
DrawOval(const Rect & oval,const Paint & paint)341 void SkiaCanvas::DrawOval(const Rect& oval, const Paint& paint)
342 {
343     if (!skCanvas_) {
344         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
345         return;
346     }
347     const SkRect* ovalRect = reinterpret_cast<const SkRect*>(&oval);
348     skPaint_ = defaultPaint_;
349     SkiaPaint::PaintToSkPaint(paint, skPaint_);
350     skCanvas_->drawOval(*ovalRect, skPaint_);
351 }
352 
DrawCircle(const Point & centerPt,scalar radius,const Paint & paint)353 void SkiaCanvas::DrawCircle(const Point& centerPt, scalar radius, const Paint& paint)
354 {
355     if (!skCanvas_) {
356         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
357         return;
358     }
359     skPaint_ = defaultPaint_;
360     SkiaPaint::PaintToSkPaint(paint, skPaint_);
361     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
362     skCanvas_->drawCircle(centerPt.GetX(), centerPt.GetY(), radius, skPaint_);
363 }
364 
DrawPath(const Path & path,const Paint & paint)365 void SkiaCanvas::DrawPath(const Path& path, const Paint& paint)
366 {
367     if (!skCanvas_) {
368         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
369         return;
370     }
371     auto skPathImpl = path.GetImpl<SkiaPath>();
372     if (skPathImpl == nullptr) {
373         return;
374     }
375     skPaint_ = defaultPaint_;
376     SkiaPaint::PaintToSkPaint(paint, skPaint_);
377     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
378     skCanvas_->drawPath(skPathImpl->GetPath(), skPaint_);
379 }
380 
DrawBackground(const Brush & brush)381 void SkiaCanvas::DrawBackground(const Brush& brush)
382 {
383     if (!skCanvas_) {
384         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
385         return;
386     }
387     SkPaint paint;
388     SkiaPaint::BrushToSkPaint(brush, paint);
389     skCanvas_->drawPaint(paint);
390 }
391 
DrawShadow(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag)392 void SkiaCanvas::DrawShadow(const Path& path, const Point3& planeParams, const Point3& devLightPos, scalar lightRadius,
393     Color ambientColor, Color spotColor, ShadowFlags flag)
394 {
395     if (!skCanvas_) {
396         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
397         return;
398     }
399     auto skPathImpl = path.GetImpl<SkiaPath>();
400     const SkPoint3* point1 = reinterpret_cast<const SkPoint3*>(&planeParams);
401     const SkPoint3* point2 = reinterpret_cast<const SkPoint3*>(&devLightPos);
402     SkColor color1 = ambientColor.CastToColorQuad();
403     SkColor color2 = spotColor.CastToColorQuad();
404     SkShadowFlags flags = static_cast<SkShadowFlags>(flag);
405     if (skPathImpl != nullptr) {
406         SkShadowUtils::DrawShadow(
407             skCanvas_, skPathImpl->GetPath(), *point1, *point2, lightRadius, color1, color2, flags);
408     }
409 }
410 
DrawShadowStyle(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag,bool isLimitElevation)411 void SkiaCanvas::DrawShadowStyle(const Path& path, const Point3& planeParams, const Point3& devLightPos,
412     scalar lightRadius, Color ambientColor, Color spotColor, ShadowFlags flag, bool isLimitElevation)
413 {
414     if (!skCanvas_) {
415         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
416         return;
417     }
418     auto skPathImpl = path.GetImpl<SkiaPath>();
419     const SkPoint3* point1 = reinterpret_cast<const SkPoint3*>(&planeParams);
420     const SkPoint3* point2 = reinterpret_cast<const SkPoint3*>(&devLightPos);
421     SkColor color1 = ambientColor.CastToColorQuad();
422     SkColor color2 = spotColor.CastToColorQuad();
423     SkShadowFlags flags = static_cast<SkShadowFlags>(flag);
424     if (skPathImpl != nullptr) {
425         SkShadowUtils::DrawShadowStyle(
426             skCanvas_, skPathImpl->GetPath(), *point1, *point2, lightRadius, color1, color2, flags, isLimitElevation);
427     }
428 }
429 
DrawColor(ColorQuad color,BlendMode mode)430 void SkiaCanvas::DrawColor(ColorQuad color, BlendMode mode)
431 {
432     if (!skCanvas_) {
433         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
434         return;
435     }
436 
437     skCanvas_->drawColor(static_cast<SkColor>(color), static_cast<SkBlendMode>(mode));
438 }
439 
DrawRegion(const Region & region,const Paint & paint)440 void SkiaCanvas::DrawRegion(const Region& region, const Paint& paint)
441 {
442     if (!skCanvas_) {
443         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
444         return;
445     }
446 
447     skPaint_ = defaultPaint_;
448     SkiaPaint::PaintToSkPaint(paint, skPaint_);
449     skCanvas_->drawRegion(*region.GetImpl<SkiaRegion>()->GetSkRegion(), skPaint_);
450 }
451 
DrawPatch(const Point cubics[12],const ColorQuad colors[4],const Point texCoords[4],BlendMode mode,const Paint & paint)452 void SkiaCanvas::DrawPatch(const Point cubics[12], const ColorQuad colors[4],
453     const Point texCoords[4], BlendMode mode, const Paint& paint)
454 {
455     if (!skCanvas_) {
456         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
457         return;
458     }
459 
460     const size_t cubicsPointCount = 12;
461     std::vector<SkPoint> skiaCubics = {};
462     if (cubics != nullptr) {
463         skiaCubics.resize(cubicsPointCount);
464         for (size_t i = 0; i < cubicsPointCount; ++i) {
465             skiaCubics[i].fX = cubics[i].GetX();
466             skiaCubics[i].fY = cubics[i].GetY();
467         }
468     }
469 
470     const size_t colorCount = 4;
471     std::vector<SkColor> skiaColors = {};
472     if (colors != nullptr) {
473         skiaColors.resize(colorCount);
474         for (size_t i = 0; i < colorCount; ++i) {
475             skiaColors[i] = static_cast<SkColor>(colors[i]);
476         }
477     }
478 
479     const size_t texCoordCount = 4;
480     std::vector<SkPoint> skiaTexCoords = {};
481     if (texCoords != nullptr) {
482         skiaTexCoords.resize(texCoordCount);
483         for (size_t i = 0; i < texCoordCount; ++i) {
484             skiaTexCoords[i].fX = texCoords[i].GetX();
485             skiaTexCoords[i].fY = texCoords[i].GetY();
486         }
487     }
488 
489     skPaint_ = defaultPaint_;
490     SkiaPaint::PaintToSkPaint(paint, skPaint_);
491     skCanvas_->drawPatch(
492         skiaCubics.empty() ? nullptr : skiaCubics.data(),
493         skiaColors.empty() ? nullptr : skiaColors.data(),
494         skiaTexCoords.empty() ? nullptr : skiaTexCoords.data(),
495         static_cast<SkBlendMode>(mode), skPaint_);
496 }
497 
DrawVertices(const Vertices & vertices,BlendMode mode,const Paint & paint)498 void SkiaCanvas::DrawVertices(const Vertices& vertices, BlendMode mode, const Paint& paint)
499 {
500     if (!skCanvas_) {
501         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
502         return;
503     }
504 
505     sk_sp<SkVertices> verts;
506     auto skVerticesImpl = vertices.GetImpl<SkiaVertices>();
507     if (skVerticesImpl != nullptr) {
508         verts = skVerticesImpl->GetVertices();
509     }
510 
511     skPaint_ = defaultPaint_;
512     SkiaPaint::PaintToSkPaint(paint, skPaint_);
513     skCanvas_->drawVertices(verts, static_cast<SkBlendMode>(mode), skPaint_);
514 }
515 
DrawImageNine(const Image * image,const RectI & center,const Rect & dst,FilterMode filter,const Brush * brush)516 void SkiaCanvas::DrawImageNine(const Image* image, const RectI& center, const Rect& dst,
517     FilterMode filter, const Brush* brush)
518 {
519     if (!skCanvas_) {
520         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
521         return;
522     }
523 
524     if (!image) {
525         LOGD("image is null, return on line %{public}d", __LINE__);
526         return;
527     }
528 
529     auto skImageImpl = image->GetImpl<SkiaImage>();
530     sk_sp<SkImage> img = nullptr;
531     if (skImageImpl != nullptr) {
532         img = skImageImpl->GetImage();
533         if (img == nullptr) {
534             LOGD("img is null, return on line %{public}d", __LINE__);
535             return;
536         }
537     }
538 
539     const SkIRect* skCenter = reinterpret_cast<const SkIRect*>(&center);
540     const SkRect* skDst = reinterpret_cast<const SkRect*>(&dst);
541 
542     SkFilterMode skFilterMode = static_cast<SkFilterMode>(filter);
543 
544     std::unique_ptr<SkPaint> paint = nullptr;
545     if (brush != nullptr) {
546         paint = std::make_unique<SkPaint>();
547         SkiaPaint::BrushToSkPaint(*brush, *paint);
548     }
549     skCanvas_->drawImageNine(img.get(), *skCenter, *skDst, skFilterMode, paint.get());
550 }
551 
DrawImageLattice(const Image * image,const Lattice & lattice,const Rect & dst,FilterMode filter,const Paint & paint)552 void SkiaCanvas::DrawImageLattice(const Image* image, const Lattice& lattice, const Rect& dst,
553     FilterMode filter, const Paint& paint)
554 {
555     if (!skCanvas_) {
556         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
557         return;
558     }
559 
560     if (!image) {
561         LOGD("image is null, return on line %{public}d", __LINE__);
562         return;
563     }
564 
565     auto skImageImpl = image->GetImpl<SkiaImage>();
566     sk_sp<SkImage> img = nullptr;
567     if (skImageImpl != nullptr) {
568         img = skImageImpl->GetImage();
569         if (img == nullptr) {
570             LOGD("img is null, return on line %{public}d", __LINE__);
571             return;
572         }
573     }
574 
575     int count = (lattice.fXCount + 1) * (lattice.fYCount + 1);
576     std::vector<SkCanvas::Lattice::RectType> skRectTypes = {};
577     if (!lattice.fRectTypes.empty()) {
578         skRectTypes.resize(count);
579         for (int i = 0; i < count; ++i) {
580             skRectTypes[i] = static_cast<SkCanvas::Lattice::RectType>(lattice.fRectTypes[i]);
581         }
582     }
583     std::vector<SkColor> skColors = {};
584     if (!lattice.fColors.empty()) {
585         skColors.resize(count);
586         for (int i = 0; i < count; ++i) {
587             skColors[i] = static_cast<SkColor>(lattice.fColors[i].CastToColorQuad());
588         }
589     }
590     SkCanvas::Lattice skLattice = {lattice.fXDivs.empty() ? nullptr : lattice.fXDivs.data(),
591         lattice.fYDivs.empty() ? nullptr : lattice.fYDivs.data(),
592         skRectTypes.empty() ? nullptr : skRectTypes.data(),
593         lattice.fXCount, lattice.fYCount,
594         lattice.fBounds.empty() ? nullptr : reinterpret_cast<const SkIRect*>(lattice.fBounds.data()),
595         skColors.empty() ? nullptr : skColors.data()};
596 
597     const SkRect* skDst = reinterpret_cast<const SkRect*>(&dst);
598     SkFilterMode skFilterMode = static_cast<SkFilterMode>(filter);
599 
600     skPaint_ = defaultPaint_;
601     SkiaPaint::PaintToSkPaint(paint, skPaint_);
602     skCanvas_->drawImageLattice(img.get(), skLattice, *skDst, skFilterMode, &skPaint_);
603 }
604 
OpCalculateBefore(const Matrix & matrix)605 bool SkiaCanvas::OpCalculateBefore(const Matrix& matrix)
606 {
607     if (!skCanvas_) {
608         LOGD("opinc before is null");
609         return false;
610     }
611     if (skiaCanvasOp_ || skCanvasBackup_) {
612         LOGD("opinc PreOpListDrawArea is nested");
613         return false;
614     }
615     auto m = matrix.GetImpl<SkiaMatrix>();
616     if (!m) {
617         LOGD("opinc get matrix null");
618         return false;
619     }
620     auto tmp = std::make_shared<SkiaCanvasAutoCache>(skCanvas_);
621     tmp->Init(m->ExportSkiaMatrix());
622     skiaCanvasOp_ = tmp;
623     skCanvasBackup_ = skiaCanvasOp_.get();
624     std::swap(skCanvas_, skCanvasBackup_);
625     return true;
626 }
627 
OpCalculateAfter(const Rect & bound)628 std::shared_ptr<Drawing::OpListHandle> SkiaCanvas::OpCalculateAfter(const Rect& bound)
629 {
630     std::shared_ptr<Drawing::OpListHandle> handle = nullptr;
631     if (!skCanvas_ || !skiaCanvasOp_) {
632         LOGD("opinc after is null");
633         return handle;
634     }
635 
636     do {
637         auto nodeBound = SkRect::MakeLTRB(bound.GetLeft(), bound.GetTop(), bound.GetRight(), bound.GetBottom());
638         if (!skiaCanvasOp_->OpCanCache(nodeBound)) {
639             LOGD("opinc opCanCache false");
640             break;
641         }
642 
643         int opNum = skiaCanvasOp_->GetOpsNum();
644         int percent = skiaCanvasOp_->GetOpsPercent();
645         auto& skUnionRect = skiaCanvasOp_->GetOpUnionRect();
646         auto& skOpListDrawArea = skiaCanvasOp_->GetOpListDrawArea();
647         if (skUnionRect.isEmpty() || opNum == 0 || percent == 0 || skOpListDrawArea.size() == 0) {
648             LOGD("opinc opNum is zero");
649             break;
650         }
651         Drawing::Rect unionRect(skUnionRect.left(), skUnionRect.top(), skUnionRect.right(), skUnionRect.bottom());
652         std::vector<Drawing::Rect> rects;
653         for (auto &item : skOpListDrawArea) {
654             rects.emplace_back(Drawing::Rect(item.left(), item.top(), item.right(), item.bottom()));
655         }
656         Drawing::OpListHandle::OpInfo opinfo{ true, opNum, percent, std::move(unionRect), std::move(rects) };
657         handle = std::make_shared<Drawing::OpListHandle>(std::move(opinfo));
658     } while (false);
659 
660     std::swap(skCanvas_, skCanvasBackup_); // restore canvas
661     skiaCanvasOp_ = nullptr;
662     skCanvasBackup_ = nullptr;
663     return handle;
664 }
665 
DrawAtlas(const Image * atlas,const RSXform xform[],const Rect tex[],const ColorQuad colors[],int count,BlendMode mode,const SamplingOptions & sampling,const Rect * cullRect,const Paint & paint)666 void SkiaCanvas::DrawAtlas(const Image* atlas, const RSXform xform[], const Rect tex[], const ColorQuad colors[],
667     int count, BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect, const Paint& paint)
668 {
669     if (!skCanvas_ || !atlas || !xform || !tex) {
670         LOGD("skCanvas_ or atlas, xform or tex is null, return on line %{public}d", __LINE__);
671         return;
672     }
673     const int maxCount = 2000; // max count supported is 2000
674     if (count <= 0 || count > maxCount) {
675         LOGD("invalid count for atlas, return on line %{public}d", __LINE__);
676         return;
677     }
678 
679     auto skImageImpl = atlas->GetImpl<SkiaImage>();
680     if (skImageImpl == nullptr) {
681         LOGD("skImageImpl is null, return on line %{public}d", __LINE__);
682         return;
683     }
684     sk_sp<SkImage> img = skImageImpl->GetImage();
685     if (img == nullptr) {
686         LOGD("img is null, return on line %{public}d", __LINE__);
687         return;
688     }
689 
690     SkRSXform skRSXform[count];
691     SkRect skTex[count];
692     for (int i = 0; i < count; ++i) {
693         SkiaConvertUtils::DrawingRSXformCastToSkXform(xform[i], skRSXform[i]);
694         SkiaConvertUtils::DrawingRectCastToSkRect(tex[i], skTex[i]);
695     }
696 
697     std::vector<SkColor> skColors = {};
698     if (colors != nullptr) {
699         skColors.resize(count);
700         for (int i = 0; i < count; ++i) {
701             skColors[i] = static_cast<SkColor>(colors[i]);
702         }
703     }
704 
705     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
706     const SkRect* skCullRect = reinterpret_cast<const SkRect*>(cullRect);
707     skPaint_ = defaultPaint_;
708     SkiaPaint::PaintToSkPaint(paint, skPaint_);
709     skCanvas_->drawAtlas(img.get(), skRSXform, skTex, skColors.empty() ? nullptr : skColors.data(), count,
710         static_cast<SkBlendMode>(mode), *samplingOptions, skCullRect, &skPaint_);
711 }
712 
DrawBitmap(const Bitmap & bitmap,const scalar px,const scalar py,const Paint & paint)713 void SkiaCanvas::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py, const Paint& paint)
714 {
715     if (!skCanvas_) {
716         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
717         return;
718     }
719     SkBitmap bmp;
720     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
721     if (skBitmapImpl != nullptr) {
722         bmp = skBitmapImpl->ExportSkiaBitmap();
723     }
724 
725     skPaint_ = defaultPaint_;
726     SkiaPaint::PaintToSkPaint(paint, skPaint_);
727     skCanvas_->drawImage(bmp.asImage(), px, py, SkSamplingOptions(), &skPaint_);
728 }
729 
DrawImage(const Image & image,const scalar px,const scalar py,const SamplingOptions & sampling,const Paint & paint)730 void SkiaCanvas::DrawImage(const Image& image, const scalar px, const scalar py,
731     const SamplingOptions& sampling, const Paint& paint)
732 {
733     if (!skCanvas_) {
734         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
735         return;
736     }
737     sk_sp<SkImage> img;
738 
739     auto skImageImpl = image.GetImpl<SkiaImage>();
740     if (skImageImpl != nullptr) {
741         img = skImageImpl->GetImage();
742         if (img == nullptr) {
743             LOGD("img is null, return on line %{public}d", __LINE__);
744             return;
745         }
746     }
747 
748     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
749     skPaint_ = defaultPaint_;
750     SkiaPaint::PaintToSkPaint(paint, skPaint_);
751     skCanvas_->drawImage(img, px, py, *samplingOptions, &skPaint_);
752 }
753 
DrawImageRect(const Image & image,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint,const Paint & paint)754 void SkiaCanvas::DrawImageRect(const Image& image, const Rect& src, const Rect& dst,
755     const SamplingOptions& sampling, SrcRectConstraint constraint, const Paint& paint)
756 {
757     if (!skCanvas_) {
758         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
759         return;
760     }
761     sk_sp<SkImage> img;
762     auto skImageImpl = image.GetImpl<SkiaImage>();
763     if (skImageImpl != nullptr) {
764         img = skImageImpl->GetImage();
765         if (img == nullptr) {
766             LOGD("img is null, return on line %{public}d", __LINE__);
767             return;
768         }
769     }
770 
771     const SkRect* srcRect = reinterpret_cast<const SkRect*>(&src);
772     const SkRect* dstRect = reinterpret_cast<const SkRect*>(&dst);
773     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
774 
775     skPaint_ = defaultPaint_;
776     SkiaPaint::PaintToSkPaint(paint, skPaint_);
777     skCanvas_->drawImageRect(img, *srcRect, *dstRect, *samplingOptions, &skPaint_,
778         static_cast<SkCanvas::SrcRectConstraint>(constraint));
779 }
780 
DrawImageRect(const Image & image,const Rect & dst,const SamplingOptions & sampling,const Paint & paint)781 void SkiaCanvas::DrawImageRect(const Image& image, const Rect& dst,
782     const SamplingOptions& sampling, const Paint& paint)
783 {
784     if (!skCanvas_) {
785         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
786         return;
787     }
788     sk_sp<SkImage> img;
789     auto skImageImpl = image.GetImpl<SkiaImage>();
790     if (skImageImpl != nullptr) {
791         img = skImageImpl->GetImage();
792         if (img == nullptr) {
793             LOGD("img is null, return on line %{public}d", __LINE__);
794             return;
795         }
796     }
797 
798     const SkRect* dstRect = reinterpret_cast<const SkRect*>(&dst);
799     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
800     skPaint_ = defaultPaint_;
801     SkiaPaint::PaintToSkPaint(paint, skPaint_);
802     skCanvas_->drawImageRect(img, *dstRect, *samplingOptions, &skPaint_);
803 }
804 
DrawPicture(const Picture & picture)805 void SkiaCanvas::DrawPicture(const Picture& picture)
806 {
807     if (!skCanvas_) {
808         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
809         return;
810     }
811     sk_sp<SkPicture> p;
812 
813     auto skPictureImpl = picture.GetImpl<SkiaPicture>();
814     if (skPictureImpl != nullptr) {
815         p = skPictureImpl->GetPicture();
816         skCanvas_->drawPicture(p.get());
817     }
818 }
819 
DrawSVGDOM(const sk_sp<SkSVGDOM> & svgDom)820 void SkiaCanvas::DrawSVGDOM(const sk_sp<SkSVGDOM>& svgDom)
821 {
822     if (!skCanvas_) {
823         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
824         return;
825     }
826     if (!svgDom) {
827         LOGD("svgDom is null, return on line %{public}d", __LINE__);
828         return;
829     }
830     svgDom->render(skCanvas_);
831 }
832 
DrawTextBlob(const TextBlob * blob,const scalar x,const scalar y,const Paint & paint)833 void SkiaCanvas::DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y, const Paint& paint)
834 {
835     if (!skCanvas_) {
836         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
837         return;
838     }
839     if (!blob) {
840         LOGD("blob is null, return on line %{public}d", __LINE__);
841         return;
842     }
843     auto skiaTextBlob = blob->GetImpl<SkiaTextBlob>();
844     if (!skiaTextBlob) {
845         LOGD("skiaTextBlob is null, return on line %{public}d", __LINE__);
846         return;
847     }
848     SkTextBlob* skTextBlob = skiaTextBlob->GetTextBlob().get();
849     if (!skTextBlob) {
850         LOGD("skTextBlob is null, return on line %{public}d", __LINE__);
851         return;
852     }
853 
854     skPaint_ = defaultPaint_;
855     SkiaPaint::PaintToSkPaint(paint, skPaint_);
856     skCanvas_->drawTextBlob(skTextBlob, x, y, skPaint_);
857 }
858 
DrawSymbol(const DrawingHMSymbolData & symbol,Point locate,const Paint & paint)859 void SkiaCanvas::DrawSymbol(const DrawingHMSymbolData& symbol, Point locate, const Paint& paint)
860 {
861     if (!skCanvas_) {
862         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
863         return;
864     }
865 
866     HMSymbolData skSymbol;
867     if (!ConvertToHMSymbolData(symbol, skSymbol)) {
868         LOGD("ConvertToHMSymbolData failed, return on line %{public}d", __LINE__);
869         return;
870     }
871 
872     const SkPoint* skLocate = reinterpret_cast<const SkPoint*>(&locate);
873 
874     skPaint_ = defaultPaint_;
875     SkiaPaint::PaintToSkPaint(paint, skPaint_);
876     skCanvas_->drawSymbol(skSymbol, *skLocate, skPaint_);
877 }
878 
ClipRect(const Rect & rect,ClipOp op,bool doAntiAlias)879 void SkiaCanvas::ClipRect(const Rect& rect, ClipOp op, bool doAntiAlias)
880 {
881     if (!skCanvas_) {
882         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
883         return;
884     }
885     const SkRect* clipRect = reinterpret_cast<const SkRect*>(&rect);
886     SkClipOp clipOp = static_cast<SkClipOp>(op);
887     skCanvas_->clipRect(*clipRect, clipOp, doAntiAlias);
888 }
889 
ClipIRect(const RectI & rect,ClipOp op)890 void SkiaCanvas::ClipIRect(const RectI& rect, ClipOp op)
891 {
892     if (!skCanvas_) {
893         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
894         return;
895     }
896     SkRect clipRect = SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
897     SkClipOp clipOp = static_cast<SkClipOp>(op);
898     skCanvas_->clipRect(clipRect, clipOp, false);
899 }
900 
ClipRoundRect(const RoundRect & roundRect,ClipOp op,bool doAntiAlias)901 void SkiaCanvas::ClipRoundRect(const RoundRect& roundRect, ClipOp op, bool doAntiAlias)
902 {
903     if (!skCanvas_) {
904         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
905         return;
906     }
907     SkRRect rRect;
908     RoundRectCastToSkRRect(roundRect, rRect);
909     SkClipOp clipOp = static_cast<SkClipOp>(op);
910     skCanvas_->clipRRect(rRect, clipOp, doAntiAlias);
911 }
912 
ClipRoundRect(const Rect & rect,std::vector<Point> & pts,bool doAntiAlias)913 void SkiaCanvas::ClipRoundRect(const Rect& rect, std::vector<Point>& pts, bool doAntiAlias)
914 {
915     if (!skCanvas_) {
916         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
917         return;
918     }
919     SkRRect rRect;
920     rRect.setRectRadii(SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()),
921         reinterpret_cast<const SkVector *>(pts.data()));
922     skCanvas_->clipRRect(rRect, doAntiAlias);
923 }
924 
ClipPath(const Path & path,ClipOp op,bool doAntiAlias)925 void SkiaCanvas::ClipPath(const Path& path, ClipOp op, bool doAntiAlias)
926 {
927     if (!skCanvas_) {
928         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
929         return;
930     }
931     auto skPathImpl = path.GetImpl<SkiaPath>();
932     if (skPathImpl != nullptr) {
933         SkClipOp clipOp = static_cast<SkClipOp>(op);
934         skCanvas_->clipPath(skPathImpl->GetPath(), clipOp, doAntiAlias);
935     }
936 }
937 
ClipRegion(const Region & region,ClipOp op)938 void SkiaCanvas::ClipRegion(const Region& region, ClipOp op)
939 {
940     if (!skCanvas_) {
941         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
942         return;
943     }
944     auto skRegionImpl = region.GetImpl<SkiaRegion>();
945     if (skRegionImpl != nullptr) {
946         SkClipOp clipOp = static_cast<SkClipOp>(op);
947         skCanvas_->clipRegion(*(skRegionImpl->GetSkRegion()), clipOp);
948     }
949 }
950 
IsClipEmpty()951 bool SkiaCanvas::IsClipEmpty()
952 {
953     if (!skCanvas_) {
954         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
955         return false;
956     }
957     return skCanvas_->isClipEmpty();
958 }
959 
IsClipRect()960 bool SkiaCanvas::IsClipRect()
961 {
962     if (!skCanvas_) {
963         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
964         return false;
965     }
966     return skCanvas_->isClipRect();
967 }
968 
QuickReject(const Rect & rect)969 bool SkiaCanvas::QuickReject(const Rect& rect)
970 {
971     if (!skCanvas_) {
972         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
973         return false;
974     }
975     const SkRect* clipRect = reinterpret_cast<const SkRect*>(&rect);
976     return skCanvas_->quickReject(*clipRect);
977 }
978 
SetMatrix(const Matrix & matrix)979 void SkiaCanvas::SetMatrix(const Matrix& matrix)
980 {
981     if (!skCanvas_) {
982         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
983         return;
984     }
985     auto m = matrix.GetImpl<SkiaMatrix>();
986     if (m != nullptr) {
987         skCanvas_->setMatrix(m->ExportSkiaMatrix());
988     }
989 }
990 
ResetMatrix()991 void SkiaCanvas::ResetMatrix()
992 {
993     if (!skCanvas_) {
994         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
995         return;
996     }
997     skCanvas_->resetMatrix();
998 }
999 
ConcatMatrix(const Matrix & matrix)1000 void SkiaCanvas::ConcatMatrix(const Matrix& matrix)
1001 {
1002     if (!skCanvas_) {
1003         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1004         return;
1005     }
1006     auto m = matrix.GetImpl<SkiaMatrix>();
1007     if (m != nullptr) {
1008         skCanvas_->concat(m->ExportSkiaMatrix());
1009     }
1010 }
1011 
Translate(scalar dx,scalar dy)1012 void SkiaCanvas::Translate(scalar dx, scalar dy)
1013 {
1014     if (!skCanvas_) {
1015         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1016         return;
1017     }
1018     skCanvas_->translate(dx, dy);
1019 }
1020 
Scale(scalar sx,scalar sy)1021 void SkiaCanvas::Scale(scalar sx, scalar sy)
1022 {
1023     if (!skCanvas_) {
1024         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1025         return;
1026     }
1027     skCanvas_->scale(sx, sy);
1028 }
1029 
Rotate(scalar deg,scalar sx,scalar sy)1030 void SkiaCanvas::Rotate(scalar deg, scalar sx, scalar sy)
1031 {
1032     if (!skCanvas_) {
1033         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1034         return;
1035     }
1036     skCanvas_->rotate(deg, sx, sy);
1037 }
1038 
Shear(scalar sx,scalar sy)1039 void SkiaCanvas::Shear(scalar sx, scalar sy)
1040 {
1041     if (!skCanvas_) {
1042         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1043         return;
1044     }
1045     skCanvas_->skew(sx, sy);
1046 }
1047 
Flush()1048 void SkiaCanvas::Flush()
1049 {
1050     if (!skCanvas_) {
1051         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1052         return;
1053     }
1054     skCanvas_->flush();
1055 }
1056 
Clear(ColorQuad color)1057 void SkiaCanvas::Clear(ColorQuad color)
1058 {
1059     if (!skCanvas_) {
1060         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1061         return;
1062     }
1063     skCanvas_->clear(color);
1064 }
1065 
Save()1066 uint32_t SkiaCanvas::Save()
1067 {
1068     if (!skCanvas_) {
1069         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1070         return 0;
1071     }
1072     return static_cast<uint32_t>(skCanvas_->save());
1073 }
1074 
SaveLayer(const SaveLayerOps & saveLayerOps)1075 void SkiaCanvas::SaveLayer(const SaveLayerOps& saveLayerOps)
1076 {
1077     if (!skCanvas_) {
1078         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1079         return;
1080     }
1081     std::unique_ptr<SkRect> skBounds = nullptr;
1082     auto bounds = saveLayerOps.GetBounds();
1083     if (bounds != nullptr) {
1084         skBounds = std::make_unique<SkRect>();
1085         skBounds->setLTRB(bounds->GetLeft(), bounds->GetTop(), bounds->GetRight(), bounds->GetBottom());
1086     }
1087     std::unique_ptr<SkPaint> paint = nullptr;
1088     auto brush = saveLayerOps.GetBrush();
1089     if (brush != nullptr) {
1090         paint = std::make_unique<SkPaint>();
1091         SkiaPaint::BrushToSkPaint(*brush, *paint);
1092     }
1093 
1094     SkCanvas::SaveLayerRec slr(skBounds.get(), paint.get(), nullptr,
1095         static_cast<SkCanvas::SaveLayerFlags>(saveLayerOps.GetSaveLayerFlags() << 1));  // Offset 1 bit
1096     skCanvas_->saveLayer(slr);
1097 }
1098 
Restore()1099 void SkiaCanvas::Restore()
1100 {
1101     if (!skCanvas_) {
1102         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1103         return;
1104     }
1105     skCanvas_->restore();
1106 }
1107 
GetSaveCount() const1108 uint32_t SkiaCanvas::GetSaveCount() const
1109 {
1110     return (skCanvas_ != nullptr) ? skCanvas_->getSaveCount() : 0;
1111 }
1112 
Discard()1113 void SkiaCanvas::Discard()
1114 {
1115     if (!skCanvas_) {
1116         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1117         return;
1118     }
1119     skCanvas_->discard();
1120 }
1121 
RoundRectCastToSkRRect(const RoundRect & roundRect,SkRRect & skRRect) const1122 void SkiaCanvas::RoundRectCastToSkRRect(const RoundRect& roundRect, SkRRect& skRRect) const
1123 {
1124     const SkRect* outer = reinterpret_cast<const SkRect*>(&roundRect.GetRect());
1125     if (roundRect.IsSimpleRoundRect()) {
1126         skRRect.setRectXY(*outer, roundRect.GetSimpleX(), roundRect.GetSimpleY());
1127         return;
1128     }
1129 
1130     const SkVector* radii = reinterpret_cast<const SkVector*>(&roundRect.GetCornerRadius(RoundRect::TOP_LEFT_POS));
1131     skRRect.setRectRadii(*outer, radii);
1132 }
1133 
ConvertToHMSymbolData(const DrawingHMSymbolData & symbol,HMSymbolData & skSymbol)1134 bool SkiaCanvas::ConvertToHMSymbolData(const DrawingHMSymbolData& symbol, HMSymbolData& skSymbol)
1135 {
1136     Path path = symbol.path_;
1137     auto skPathImpl = path.GetImpl<SkiaPath>();
1138     if (skPathImpl == nullptr) {
1139         return false;
1140     }
1141     skSymbol.path_ = skPathImpl->GetPath();
1142 
1143     skSymbol.symbolInfo_.symbolGlyphId = symbol.symbolInfo_.symbolGlyphId;
1144     skSymbol.symbolInfo_.layers = symbol.symbolInfo_.layers;
1145 
1146     std::vector<RenderGroup> groups;
1147     auto drawingGroup = symbol.symbolInfo_.renderGroups;
1148     for (size_t i = 0; i < drawingGroup.size(); i++) {
1149         RenderGroup group;
1150         group.color.a = drawingGroup.at(i).color.a;
1151         group.color.r = drawingGroup.at(i).color.r;
1152         group.color.g = drawingGroup.at(i).color.g;
1153         group.color.b = drawingGroup.at(i).color.b;
1154         auto drawingGroupInfos = drawingGroup.at(i).groupInfos;
1155         std::vector<GroupInfo> infos;
1156         for (size_t j = 0; j < drawingGroupInfos.size(); j++) {
1157             GroupInfo info;
1158             info.layerIndexes = drawingGroupInfos.at(j).layerIndexes;
1159             info.maskIndexes = drawingGroupInfos.at(j).maskIndexes;
1160             infos.push_back(info);
1161         }
1162         group.groupInfos = infos;
1163         groups.push_back(group);
1164     }
1165     skSymbol.symbolInfo_.renderGroups = groups;
1166     return true;
1167 }
1168 
BuildOverDraw(std::shared_ptr<Canvas> canvas)1169 void SkiaCanvas::BuildOverDraw(std::shared_ptr<Canvas> canvas)
1170 {
1171     auto skiaCanvas = canvas->GetImpl<SkiaCanvas>();
1172     skiaCanvas_ = std::make_shared<SkOverdrawCanvas>(skiaCanvas->ExportSkCanvas());
1173     skCanvas_ = skiaCanvas_.get();
1174 }
1175 
BuildNoDraw(int32_t width,int32_t height)1176 void SkiaCanvas::BuildNoDraw(int32_t width, int32_t height)
1177 {
1178     skiaCanvas_ = std::make_shared<SkNoDrawCanvas>(width, height);
1179     skCanvas_ = skiaCanvas_.get();
1180 }
1181 
Reset(int32_t width,int32_t height)1182 void SkiaCanvas::Reset(int32_t width, int32_t height)
1183 {
1184     SkNoDrawCanvas* noDraw = reinterpret_cast<SkNoDrawCanvas*>(skCanvas_);
1185     noDraw->resetCanvas(width, height);
1186 }
1187 
DrawBlurImage(const Image & image,const Drawing::HpsBlurParameter & blurParams)1188 bool SkiaCanvas::DrawBlurImage(const Image& image, const Drawing::HpsBlurParameter& blurParams)
1189 {
1190     if (!skCanvas_) {
1191         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1192         return false;
1193     }
1194 
1195     auto skImageImpl = image.GetImpl<SkiaImage>();
1196     if (skImageImpl == nullptr) {
1197         LOGE("skImageImpl is null, return on line %{public}d", __LINE__);
1198         return false;
1199     }
1200 
1201     sk_sp<SkImage> img = skImageImpl->GetImage();
1202     if (img == nullptr) {
1203         LOGE("img is null, return on line %{public}d", __LINE__);
1204         return false;
1205     }
1206 
1207     SkRect srcRect = SkRect::MakeLTRB(blurParams.src.GetLeft(), blurParams.src.GetTop(),
1208         blurParams.src.GetRight(), blurParams.src.GetBottom());
1209     SkRect dstRect = SkRect::MakeLTRB(blurParams.dst.GetLeft(), blurParams.dst.GetTop(),
1210         blurParams.dst.GetRight(), blurParams.dst.GetBottom());
1211 
1212     SkBlurArg blurArg(srcRect, dstRect, blurParams.sigma, blurParams.saturation, blurParams.brightness);
1213     return skCanvas_->drawBlurImage(img.get(), blurArg);
1214 }
1215 
CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter & blurParams)1216 std::array<int, 2> SkiaCanvas::CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter& blurParams)
1217 {
1218     if (!skCanvas_) {
1219         LOGD("SkiaCanvas::CalcHpsBluredImageDimension, skCanvas_ is nullptr");
1220         return {0, 0};
1221     }
1222 
1223     SkRect srcRect = SkRect::MakeLTRB(blurParams.src.GetLeft(), blurParams.src.GetTop(),
1224         blurParams.src.GetRight(), blurParams.src.GetBottom());
1225     SkRect dstRect = SkRect::MakeLTRB(blurParams.dst.GetLeft(), blurParams.dst.GetTop(),
1226         blurParams.dst.GetRight(), blurParams.dst.GetBottom());
1227 
1228     SkBlurArg blurArg(srcRect, dstRect, blurParams.sigma, blurParams.saturation, blurParams.brightness);
1229     return skCanvas_->CalcHpsBluredImageDimension(blurArg);
1230 }
1231 } // namespace Drawing
1232 } // namespace Rosen
1233 } // namespace OHOS
1234