• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if defined(NEW_SKIA)
19 #include "modules/svg/include/SkSVGDOM.h"
20 #else
21 #include "experimental/svg/model/SkSVGDOM.h"
22 #endif
23 
24 #ifdef SUPPORT_OHOS_PIXMAP
25 #include "pixel_map.h"
26 #endif
27 #ifdef ACE_ENABLE_GPU
28 #include "skia_gpu_context.h"
29 #endif
30 #include "skia_image_filter.h"
31 #include "skia_path.h"
32 
33 #include "draw/core_canvas.h"
34 #include "image/bitmap.h"
35 #include "image/image.h"
36 #include "utils/log.h"
37 
38 namespace OHOS {
39 namespace Rosen {
40 namespace Drawing {
SkiaCanvas()41 SkiaCanvas::SkiaCanvas() : skiaCanvas_(std::make_shared<SkCanvas>()), skiaPaint_()
42 {
43     skCanvas_ = skiaCanvas_.get();
44 }
45 
SkiaCanvas(const std::shared_ptr<SkCanvas> & skCanvas)46 SkiaCanvas::SkiaCanvas(const std::shared_ptr<SkCanvas>& skCanvas) : skiaCanvas_(skCanvas), skiaPaint_()
47 {
48     skCanvas_ = skiaCanvas_.get();
49 }
50 
SkiaCanvas(int32_t width,int32_t height)51 SkiaCanvas::SkiaCanvas(int32_t width, int32_t height)
52     : skiaCanvas_(std::make_shared<SkCanvas>(width, height)), skiaPaint_()
53 {
54     skCanvas_ = skiaCanvas_.get();
55 }
56 
ExportSkCanvas() const57 SkCanvas* SkiaCanvas::ExportSkCanvas() const
58 {
59     return skCanvas_;
60 }
61 
ImportSkCanvas(SkCanvas * skCanvas)62 void SkiaCanvas::ImportSkCanvas(SkCanvas* skCanvas)
63 {
64     skCanvas_ = skCanvas;
65 }
66 
Bind(const Bitmap & bitmap)67 void SkiaCanvas::Bind(const Bitmap& bitmap)
68 {
69     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
70     if (skBitmapImpl != nullptr) {
71         skiaCanvas_ = std::make_shared<SkCanvas>(skBitmapImpl->ExportSkiaBitmap());
72         skCanvas_ = skiaCanvas_.get();
73     }
74 }
75 
GetTotalMatrix() const76 Matrix SkiaCanvas::GetTotalMatrix() const
77 {
78     if (skCanvas_ == nullptr) {
79         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
80         return Matrix();
81     }
82     auto skMatrix = skCanvas_->getTotalMatrix();
83     Matrix matrix;
84     matrix.SetMatrix(skMatrix.getScaleX(), skMatrix.getSkewX(), skMatrix.getTranslateX(),
85         skMatrix.getSkewX(), skMatrix.getScaleY(), skMatrix.getTranslateY(),
86         skMatrix.getPerspX(), skMatrix.getPerspY(), 1);
87     return matrix;
88 }
89 
GetLocalClipBounds() const90 Rect SkiaCanvas::GetLocalClipBounds() const
91 {
92     if (skCanvas_ == nullptr) {
93         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
94         return Rect();
95     }
96     auto rect = skCanvas_->getLocalClipBounds();
97     return Rect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
98 }
99 
GetDeviceClipBounds() const100 RectI SkiaCanvas::GetDeviceClipBounds() const
101 {
102     if (skCanvas_ == nullptr) {
103         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
104         return RectI();
105     }
106     auto iRect = skCanvas_->getDeviceClipBounds();
107     return RectI(iRect.fLeft, iRect.fTop, iRect.fRight, iRect.fBottom);
108 }
109 
110 #ifdef ACE_ENABLE_GPU
GetGPUContext() const111 std::shared_ptr<GPUContext> SkiaCanvas::GetGPUContext() const
112 {
113 #ifdef NEW_SKIA
114     if (skCanvas_ == nullptr || skCanvas_->recordingContext() == nullptr ||
115         GrAsDirectContext(skCanvas_->recordingContext()) == nullptr) {
116         LOGE("skCanvas_ or grContext is null, return on line %{public}d", __LINE__);
117         return nullptr;
118     }
119     auto grContext = GrAsDirectContext(skCanvas_->recordingContext());
120 #else
121     if (skCanvas_ == nullptr || skCanvas_->getGrContext() == nullptr) {
122         LOGE("skCanvas_ or grContext is null, return on line %{public}d", __LINE__);
123         return nullptr;
124     }
125     auto grContext = skCanvas_->getGrContext();
126 #endif
127 
128     auto gpuContext = std::make_shared<GPUContext>();
129     gpuContext->GetImpl<SkiaGPUContext>()->SetGrContext(sk_ref_sp(grContext));
130 
131     return gpuContext;
132 }
133 #endif
134 
GetWidth() const135 int32_t SkiaCanvas::GetWidth() const
136 {
137     return (skCanvas_ != nullptr) ? skCanvas_->imageInfo().width() : 0;
138 }
139 
GetHeight() const140 int32_t SkiaCanvas::GetHeight() const
141 {
142     return (skCanvas_ != nullptr) ? skCanvas_->imageInfo().height() : 0;
143 }
144 
DrawPoint(const Point & point)145 void SkiaCanvas::DrawPoint(const Point& point)
146 {
147     if (!skCanvas_) {
148         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
149         return;
150     }
151     for (auto d : skiaPaint_.GetSortedPaints()) {
152         if (d != nullptr) {
153             skCanvas_->drawPoint(SkPoint::Make(point.GetX(), point.GetY()), d->paint);
154         }
155     }
156 }
157 
DrawLine(const Point & startPt,const Point & endPt)158 void SkiaCanvas::DrawLine(const Point& startPt, const Point& endPt)
159 {
160     if (!skCanvas_) {
161         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
162         return;
163     }
164     for (auto d : skiaPaint_.GetSortedPaints()) {
165         if (d != nullptr) {
166             skCanvas_->drawLine(
167                 SkPoint::Make(startPt.GetX(), startPt.GetY()), SkPoint::Make(endPt.GetX(), endPt.GetY()), d->paint);
168         }
169     }
170 }
171 
DrawRect(const Rect & rect)172 void SkiaCanvas::DrawRect(const Rect& rect)
173 {
174     if (!skCanvas_) {
175         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
176         return;
177     }
178     SkRect r = SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
179     for (auto d : skiaPaint_.GetSortedPaints()) {
180         if (d != nullptr) {
181             skCanvas_->drawRect(r, d->paint);
182         }
183     }
184 }
185 
DrawRoundRect(const RoundRect & roundRect)186 void SkiaCanvas::DrawRoundRect(const RoundRect& roundRect)
187 {
188     if (!skCanvas_) {
189         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
190         return;
191     }
192     SkRRect rRect;
193     RoundRectCastToSkRRect(roundRect, rRect);
194     for (auto d : skiaPaint_.GetSortedPaints()) {
195         if (d != nullptr) {
196             skCanvas_->drawRRect(rRect, d->paint);
197         }
198     }
199 }
200 
DrawNestedRoundRect(const RoundRect & outer,const RoundRect & inner)201 void SkiaCanvas::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner)
202 {
203     if (!skCanvas_) {
204         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
205         return;
206     }
207     SkRRect outerRRect;
208     RoundRectCastToSkRRect(outer, outerRRect);
209 
210     SkRRect innerRRect;
211     RoundRectCastToSkRRect(inner, innerRRect);
212 
213     for (auto d : skiaPaint_.GetSortedPaints()) {
214         if (d != nullptr) {
215             skCanvas_->drawDRRect(outerRRect, innerRRect, d->paint);
216         }
217     }
218 }
219 
DrawArc(const Rect & oval,scalar startAngle,scalar sweepAngle)220 void SkiaCanvas::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle)
221 {
222     if (!skCanvas_) {
223         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
224         return;
225     }
226     SkRect arcRect = SkRect::MakeLTRB(oval.GetLeft(), oval.GetTop(), oval.GetRight(), oval.GetBottom());
227     for (auto d : skiaPaint_.GetSortedPaints()) {
228         if (d != nullptr) {
229             skCanvas_->drawArc(arcRect, startAngle, sweepAngle, false, d->paint);
230         }
231     }
232 }
233 
DrawPie(const Rect & oval,scalar startAngle,scalar sweepAngle)234 void SkiaCanvas::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle)
235 {
236     if (!skCanvas_) {
237         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
238         return;
239     }
240     SkRect pieRect = SkRect::MakeLTRB(oval.GetLeft(), oval.GetTop(), oval.GetRight(), oval.GetBottom());
241     for (auto d : skiaPaint_.GetSortedPaints()) {
242         if (d != nullptr) {
243             skCanvas_->drawArc(pieRect, startAngle, sweepAngle, true, d->paint);
244         }
245     }
246 }
247 
DrawOval(const Rect & oval)248 void SkiaCanvas::DrawOval(const Rect& oval)
249 {
250     if (!skCanvas_) {
251         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
252         return;
253     }
254     SkRect ovalRect = SkRect::MakeLTRB(oval.GetLeft(), oval.GetTop(), oval.GetRight(), oval.GetBottom());
255     for (auto d : skiaPaint_.GetSortedPaints()) {
256         if (d != nullptr) {
257             skCanvas_->drawOval(ovalRect, d->paint);
258         }
259     }
260 }
261 
DrawCircle(const Point & centerPt,scalar radius)262 void SkiaCanvas::DrawCircle(const Point& centerPt, scalar radius)
263 {
264     if (!skCanvas_) {
265         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
266         return;
267     }
268     for (auto d : skiaPaint_.GetSortedPaints()) {
269         if (d != nullptr) {
270             skCanvas_->drawCircle(centerPt.GetX(), centerPt.GetY(), radius, d->paint);
271         }
272     }
273 }
274 
DrawPath(const Path & path)275 void SkiaCanvas::DrawPath(const Path& path)
276 {
277     if (!skCanvas_) {
278         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
279         return;
280     }
281     auto skPathImpl = path.GetImpl<SkiaPath>();
282     for (auto d : skiaPaint_.GetSortedPaints()) {
283         if (skPathImpl != nullptr && d != nullptr) {
284             skCanvas_->drawPath(skPathImpl->GetPath(), d->paint);
285         }
286     }
287 }
288 
DrawBackground(const Brush & brush)289 void SkiaCanvas::DrawBackground(const Brush& brush)
290 {
291     if (!skCanvas_) {
292         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
293         return;
294     }
295     SkPaint paint;
296     skiaPaint_.BrushToSkPaint(brush, paint);
297     skCanvas_->drawPaint(paint);
298 }
299 
DrawShadow(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag)300 void SkiaCanvas::DrawShadow(const Path& path, const Point3& planeParams, const Point3& devLightPos, scalar lightRadius,
301     Color ambientColor, Color spotColor, ShadowFlags flag)
302 {
303     if (!skCanvas_) {
304         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
305         return;
306     }
307     auto skPathImpl = path.GetImpl<SkiaPath>();
308     SkPoint3 point1 = SkPoint3::Make(planeParams.GetX(), planeParams.GetY(), planeParams.GetZ());
309     SkPoint3 point2 = SkPoint3::Make(devLightPos.GetX(), devLightPos.GetY(), devLightPos.GetZ());
310     SkColor color1 = ambientColor.CastToColorQuad();
311     SkColor color2 = spotColor.CastToColorQuad();
312     SkShadowFlags flags = static_cast<SkShadowFlags>(flag);
313     if (skPathImpl != nullptr) {
314         SkShadowUtils::DrawShadow(skCanvas_, skPathImpl->GetPath(), point1, point2, color1, color2, flags);
315     }
316 }
317 
DrawRegion(const Region & region)318 void SkiaCanvas::DrawRegion(const Region& region)
319 {
320     if (!skCanvas_) {
321         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
322         return;
323     }
324 
325     for (auto d : skiaPaint_.GetSortedPaints()) {
326         if (d != nullptr) {
327             skCanvas_->drawRegion(*region.GetImpl<SkiaRegion>()->GetSkRegion(), d->paint);
328         }
329     }
330 }
331 
DrawBitmap(const Bitmap & bitmap,const scalar px,const scalar py)332 void SkiaCanvas::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py)
333 {
334     if (!skCanvas_) {
335         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
336         return;
337     }
338     SkBitmap bmp;
339 
340     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
341     if (skBitmapImpl != nullptr) {
342         bmp = skBitmapImpl->ExportSkiaBitmap();
343     }
344 
345     auto paints = skiaPaint_.GetSortedPaints();
346     if (paints.empty()) {
347 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
348         skCanvas_->drawImage(bmp.asImage(), px, py);
349 #else
350         skCanvas_->drawBitmap(bmp, px, py);
351 #endif
352         return;
353     }
354 
355     for (auto d : skiaPaint_.GetSortedPaints()) {
356         if (d != nullptr) {
357 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
358             skCanvas_->drawImage(bmp.asImage(), px, py, SkSamplingOptions(), &d->paint);
359 #else
360             skCanvas_->drawBitmap(bmp, px, py, &d->paint);
361 #endif
362         }
363     }
364 }
365 
366 #ifdef SUPPORT_OHOS_PIXMAP
ColorSpaceToSkColorSpace(Media::PixelMap & pixmap)367 static sk_sp<SkColorSpace> ColorSpaceToSkColorSpace(Media::PixelMap& pixmap)
368 {
369     return SkColorSpace::MakeSRGB();
370 }
371 
AlphaTypeToSkAlphaType(Media::AlphaType alphaType)372 static SkAlphaType AlphaTypeToSkAlphaType(Media::AlphaType alphaType)
373 {
374     switch (alphaType) {
375         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
376             return SkAlphaType::kUnknown_SkAlphaType;
377         case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
378             return SkAlphaType::kOpaque_SkAlphaType;
379         case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
380             return SkAlphaType::kPremul_SkAlphaType;
381         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
382             return SkAlphaType::kUnpremul_SkAlphaType;
383         default:
384             return SkAlphaType::kUnknown_SkAlphaType;
385     }
386 }
387 
PixelFormatToSkColorType(Media::PixelFormat format)388 static SkColorType PixelFormatToSkColorType(Media::PixelFormat format)
389 {
390     switch (format) {
391         case Media::PixelFormat::RGB_565:
392             return SkColorType::kRGB_565_SkColorType;
393         case Media::PixelFormat::RGBA_8888:
394             return SkColorType::kRGBA_8888_SkColorType;
395         case Media::PixelFormat::BGRA_8888:
396             return SkColorType::kBGRA_8888_SkColorType;
397         case Media::PixelFormat::ALPHA_8:
398             return SkColorType::kAlpha_8_SkColorType;
399         case Media::PixelFormat::RGBA_F16:
400             return SkColorType::kRGBA_F16_SkColorType;
401         case Media::PixelFormat::UNKNOWN:
402         case Media::PixelFormat::ARGB_8888:
403         case Media::PixelFormat::RGB_888:
404         case Media::PixelFormat::NV21:
405         case Media::PixelFormat::NV12:
406         case Media::PixelFormat::CMYK:
407         default:
408             return SkColorType::kUnknown_SkColorType;
409     }
410 }
411 
MakeSkImageInfoFromPixelMap(Media::PixelMap & pixelMap)412 static SkImageInfo MakeSkImageInfoFromPixelMap(Media::PixelMap& pixelMap)
413 {
414     SkColorType ct = PixelFormatToSkColorType(pixelMap.GetPixelFormat());
415     SkAlphaType at = AlphaTypeToSkAlphaType(pixelMap.GetAlphaType());
416     sk_sp<SkColorSpace> cs = ColorSpaceToSkColorSpace(pixelMap);
417     LOGD("SkColorType %{pubilic}d, SkAlphaType %{public}d", ct, at);
418     return SkImageInfo::Make(pixelMap.GetWidth(), pixelMap.GetHeight(), ct, at, cs);
419 }
420 #endif
421 
DrawBitmap(Media::PixelMap & pixelMap,const scalar px,const scalar py)422 void SkiaCanvas::DrawBitmap(Media::PixelMap& pixelMap, const scalar px, const scalar py)
423 {
424     if (!skCanvas_) {
425         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
426         return;
427     }
428 #ifdef SUPPORT_OHOS_PIXMAP
429     if (pixelMap.GetPixels() == nullptr) {
430         LOGE("PutPixelMap failed, pixelMap data invalid");
431         return;
432     }
433     SkBitmap bitmap;
434     auto imageInfo = MakeSkImageInfoFromPixelMap(pixelMap);
435     bitmap.installPixels(imageInfo, (void*)pixelMap.GetPixels(), static_cast<uint32_t>(pixelMap.GetRowBytes()));
436 
437     auto paints = skiaPaint_.GetSortedPaints();
438     if (paints.empty()) {
439 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
440         skCanvas_->drawImage(bitmap.asImage(), px, py);
441 #else
442         skCanvas_->drawBitmap(bitmap, px, py);
443 #endif
444         return;
445     }
446 
447     for (auto d : paints) {
448         if (d != nullptr) {
449 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
450             skCanvas_->drawImage(bitmap.asImage(), px, py, SkSamplingOptions(), &d->paint);
451 #else
452             skCanvas_->drawBitmap(bitmap, px, py, &d->paint);
453 #endif
454         }
455     }
456 #else
457     LOGE("Not support drawing Media::PixelMap");
458 #endif
459 }
460 
DrawImage(const Image & image,const scalar px,const scalar py,const SamplingOptions & sampling)461 void SkiaCanvas::DrawImage(const Image& image, const scalar px, const scalar py, const SamplingOptions& sampling)
462 {
463     if (!skCanvas_) {
464         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
465         return;
466     }
467     sk_sp<SkImage> img;
468 
469     auto skImageImpl = image.GetImpl<SkiaImage>();
470     if (skImageImpl != nullptr) {
471         img = skImageImpl->GetImage();
472     }
473 
474     auto paints = skiaPaint_.GetSortedPaints();
475     if (paints.empty()) {
476         skCanvas_->drawImage(img, px, py);
477         return;
478     }
479 
480     for (auto d : paints) {
481         if (d != nullptr) {
482 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
483             SkSamplingOptions samplingOptions;
484             if (sampling.GetUseCubic()) {
485                 samplingOptions = SkSamplingOptions({ sampling.GetCubicCoffB(), sampling.GetCubicCoffC() });
486             } else {
487                 samplingOptions = SkSamplingOptions(static_cast<SkFilterMode>(sampling.GetFilterMode()),
488                     static_cast<SkMipmapMode>(sampling.GetMipmapMode()));
489             }
490             skCanvas_->drawImage(img, px, py, samplingOptions, &d->paint);
491 #else
492             skCanvas_->drawImage(img, px, py, &d->paint);
493 #endif
494         }
495     }
496 }
497 
DrawImageRect(const Image & image,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint)498 void SkiaCanvas::DrawImageRect(
499     const Image& image, const Rect& src, const Rect& dst, const SamplingOptions& sampling, SrcRectConstraint constraint)
500 {
501     if (!skCanvas_) {
502         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
503         return;
504     }
505     sk_sp<SkImage> img;
506     auto skImageImpl = image.GetImpl<SkiaImage>();
507     if (skImageImpl != nullptr) {
508         img = skImageImpl->GetImage();
509     }
510 
511     SkRect srcRect = SkRect::MakeLTRB(src.GetLeft(), src.GetTop(), src.GetRight(), src.GetBottom());
512     SkRect dstRect = SkRect::MakeLTRB(dst.GetLeft(), dst.GetTop(), dst.GetRight(), dst.GetBottom());
513 
514     auto paints = skiaPaint_.GetSortedPaints();
515     if (paints.empty()) {
516 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
517         SkSamplingOptions samplingOptions;
518         skCanvas_->drawImageRect(
519             img, srcRect, dstRect, samplingOptions, nullptr, static_cast<SkCanvas::SrcRectConstraint>(constraint));
520 #else
521         skCanvas_->drawImageRect(
522             img, srcRect, dstRect, nullptr, static_cast<SkCanvas::SrcRectConstraint>(constraint));
523 #endif
524         return;
525     }
526 
527     for (auto d : paints) {
528         if (d != nullptr) {
529 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
530             SkSamplingOptions samplingOptions;
531             if (sampling.GetUseCubic()) {
532                 samplingOptions = SkSamplingOptions({ sampling.GetCubicCoffB(), sampling.GetCubicCoffC() });
533             } else {
534                 samplingOptions = SkSamplingOptions(static_cast<SkFilterMode>(sampling.GetFilterMode()),
535                     static_cast<SkMipmapMode>(sampling.GetMipmapMode()));
536             }
537             skCanvas_->drawImageRect(img, srcRect, dstRect, samplingOptions, &d->paint,
538                 static_cast<SkCanvas::SrcRectConstraint>(constraint));
539 #else
540             skCanvas_->drawImageRect(
541                 img, srcRect, dstRect, &d->paint, static_cast<SkCanvas::SrcRectConstraint>(constraint));
542 #endif
543         }
544     }
545 }
546 
DrawImageRect(const Image & image,const Rect & dst,const SamplingOptions & sampling)547 void SkiaCanvas::DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling)
548 {
549     if (!skCanvas_) {
550         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
551         return;
552     }
553     sk_sp<SkImage> img;
554     auto skImageImpl = image.GetImpl<SkiaImage>();
555     if (skImageImpl != nullptr) {
556         img = skImageImpl->GetImage();
557     }
558 
559     SkRect dstRect = SkRect::MakeLTRB(dst.GetLeft(), dst.GetTop(), dst.GetRight(), dst.GetBottom());
560 
561     auto paints = skiaPaint_.GetSortedPaints();
562     if (paints.empty()) {
563 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
564         SkSamplingOptions samplingOptions;
565         skCanvas_->drawImageRect(img, dstRect, samplingOptions, nullptr);
566 #else
567         skCanvas_->drawImageRect(img, dstRect, nullptr);
568 #endif
569         return;
570     }
571 
572     for (auto d : paints) {
573         if (d != nullptr) {
574 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
575             SkSamplingOptions samplingOptions;
576             if (sampling.GetUseCubic()) {
577                 samplingOptions = SkSamplingOptions({ sampling.GetCubicCoffB(), sampling.GetCubicCoffC() });
578             } else {
579                 samplingOptions = SkSamplingOptions(static_cast<SkFilterMode>(sampling.GetFilterMode()),
580                     static_cast<SkMipmapMode>(sampling.GetMipmapMode()));
581             }
582             skCanvas_->drawImageRect(img, dstRect, samplingOptions, &d->paint);
583 #else
584             skCanvas_->drawImageRect(img, dstRect, &d->paint);
585 #endif
586         }
587     }
588 }
589 
DrawPicture(const Picture & picture)590 void SkiaCanvas::DrawPicture(const Picture& picture)
591 {
592     if (!skCanvas_) {
593         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
594         return;
595     }
596     LOGD("+++++++ DrawPicture");
597     sk_sp<SkPicture> p;
598 
599     auto skPictureImpl = picture.GetImpl<SkiaPicture>();
600     if (skPictureImpl != nullptr) {
601         p = skPictureImpl->GetPicture();
602         skCanvas_->drawPicture(p.get());
603     }
604     LOGD("------- DrawPicture");
605 }
606 
DrawSVGDOM(const sk_sp<SkSVGDOM> & svgDom)607 void SkiaCanvas::DrawSVGDOM(const sk_sp<SkSVGDOM>& svgDom)
608 {
609     if (!skCanvas_) {
610         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
611         return;
612     }
613     if (!svgDom) {
614         LOGE("svgDom is null, return on line %{public}d", __LINE__);
615         return;
616     }
617     LOGD("+++++++ DrawSVGDOM");
618     svgDom->render(skCanvas_);
619     LOGD("------- DrawSVGDOM");
620 }
621 
ClipRect(const Rect & rect,ClipOp op,bool doAntiAlias)622 void SkiaCanvas::ClipRect(const Rect& rect, ClipOp op, bool doAntiAlias)
623 {
624     if (!skCanvas_) {
625         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
626         return;
627     }
628     SkRect clipRect = SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
629     SkClipOp clipOp = static_cast<SkClipOp>(op);
630     skCanvas_->clipRect(clipRect, clipOp, doAntiAlias);
631 }
632 
ClipRoundRect(const RoundRect & roundRect,ClipOp op,bool doAntiAlias)633 void SkiaCanvas::ClipRoundRect(const RoundRect& roundRect, ClipOp op, bool doAntiAlias)
634 {
635     if (!skCanvas_) {
636         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
637         return;
638     }
639     SkRRect rRect;
640     RoundRectCastToSkRRect(roundRect, rRect);
641     SkClipOp clipOp = static_cast<SkClipOp>(op);
642     skCanvas_->clipRRect(rRect, clipOp, doAntiAlias);
643 }
644 
ClipPath(const Path & path,ClipOp op,bool doAntiAlias)645 void SkiaCanvas::ClipPath(const Path& path, ClipOp op, bool doAntiAlias)
646 {
647     if (!skCanvas_) {
648         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
649         return;
650     }
651     auto skPathImpl = path.GetImpl<SkiaPath>();
652     if (skPathImpl != nullptr) {
653         SkClipOp clipOp = static_cast<SkClipOp>(op);
654         skCanvas_->clipPath(skPathImpl->GetPath(), clipOp, doAntiAlias);
655     }
656 }
657 
SetMatrix(const Matrix & matrix)658 void SkiaCanvas::SetMatrix(const Matrix& matrix)
659 {
660     if (!skCanvas_) {
661         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
662         return;
663     }
664     auto m = matrix.GetImpl<SkiaMatrix>();
665     if (m != nullptr) {
666         skCanvas_->setMatrix(m->ExportSkiaMatrix());
667     }
668 }
669 
ResetMatrix()670 void SkiaCanvas::ResetMatrix()
671 {
672     if (!skCanvas_) {
673         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
674         return;
675     }
676     skCanvas_->resetMatrix();
677 }
678 
ConcatMatrix(const Matrix & matrix)679 void SkiaCanvas::ConcatMatrix(const Matrix& matrix)
680 {
681     if (!skCanvas_) {
682         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
683         return;
684     }
685     auto m = matrix.GetImpl<SkiaMatrix>();
686     if (m != nullptr) {
687         skCanvas_->concat(m->ExportSkiaMatrix());
688     }
689 }
690 
Translate(scalar dx,scalar dy)691 void SkiaCanvas::Translate(scalar dx, scalar dy)
692 {
693     if (!skCanvas_) {
694         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
695         return;
696     }
697     skCanvas_->translate(dx, dy);
698 }
699 
Scale(scalar sx,scalar sy)700 void SkiaCanvas::Scale(scalar sx, scalar sy)
701 {
702     if (!skCanvas_) {
703         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
704         return;
705     }
706     skCanvas_->scale(sx, sy);
707 }
708 
Rotate(scalar deg,scalar sx,scalar sy)709 void SkiaCanvas::Rotate(scalar deg, scalar sx, scalar sy)
710 {
711     if (!skCanvas_) {
712         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
713         return;
714     }
715     skCanvas_->rotate(deg, sx, sy);
716 }
717 
Shear(scalar sx,scalar sy)718 void SkiaCanvas::Shear(scalar sx, scalar sy)
719 {
720     if (!skCanvas_) {
721         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
722         return;
723     }
724     skCanvas_->skew(sx, sy);
725 }
726 
Flush()727 void SkiaCanvas::Flush()
728 {
729     if (!skCanvas_) {
730         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
731         return;
732     }
733     skCanvas_->flush();
734 }
735 
Clear(ColorQuad color)736 void SkiaCanvas::Clear(ColorQuad color)
737 {
738     if (!skCanvas_) {
739         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
740         return;
741     }
742     skCanvas_->clear(color);
743 }
744 
Save()745 void SkiaCanvas::Save()
746 {
747     if (!skCanvas_) {
748         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
749         return;
750     }
751     skCanvas_->save();
752 }
753 
SaveLayer(const SaveLayerOps & saveLayerOps)754 void SkiaCanvas::SaveLayer(const SaveLayerOps& saveLayerOps)
755 {
756     if (!skCanvas_) {
757         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
758         return;
759     }
760     std::unique_ptr<SkRect> skBounds = nullptr;
761     auto bounds = saveLayerOps.GetBounds();
762     if (bounds != nullptr) {
763         skBounds = std::make_unique<SkRect>();
764         skBounds->setLTRB(bounds->GetLeft(), bounds->GetTop(), bounds->GetRight(), bounds->GetBottom());
765     }
766     std::unique_ptr<SkPaint> paint = nullptr;
767     auto brush = saveLayerOps.GetBrush();
768     if (brush != nullptr) {
769         paint = std::make_unique<SkPaint>();
770         skiaPaint_.BrushToSkPaint(*brush, *paint);
771     }
772     sk_sp<SkImageFilter> skImageFilter = nullptr;
773     auto imageFilter = saveLayerOps.GetImageFilter();
774     if (imageFilter != nullptr) {
775         auto skiaImageFilter = imageFilter->GetImpl<SkiaImageFilter>();
776         skImageFilter = skiaImageFilter->GetImageFilter();
777     }
778 
779     SkCanvas::SaveLayerRec slr(skBounds.get(), paint.get(), skImageFilter.get(),
780         static_cast<SkCanvas::SaveLayerFlags>(saveLayerOps.GetSaveLayerFlags() << 1));  // Offset 1 bit
781     skCanvas_->saveLayer(slr);
782 }
783 
Restore()784 void SkiaCanvas::Restore()
785 {
786     if (!skCanvas_) {
787         LOGE("skCanvas_ is null, return on line %{public}d", __LINE__);
788         return;
789     }
790     skCanvas_->restore();
791 }
792 
GetSaveCount() const793 uint32_t SkiaCanvas::GetSaveCount() const
794 {
795     return (skCanvas_ != nullptr) ? skCanvas_->getSaveCount() : 0;
796 }
797 
AttachPen(const Pen & pen)798 void SkiaCanvas::AttachPen(const Pen& pen)
799 {
800     skiaPaint_.ApplyPenToStroke(pen);
801 }
802 
AttachBrush(const Brush & brush)803 void SkiaCanvas::AttachBrush(const Brush& brush)
804 {
805     skiaPaint_.ApplyBrushToFill(brush);
806 }
807 
DetachPen()808 void SkiaCanvas::DetachPen()
809 {
810     skiaPaint_.DisableStroke();
811 }
812 
DetachBrush()813 void SkiaCanvas::DetachBrush()
814 {
815     skiaPaint_.DisableFill();
816 }
817 
RoundRectCastToSkRRect(const RoundRect & roundRect,SkRRect & skRRect) const818 void SkiaCanvas::RoundRectCastToSkRRect(const RoundRect& roundRect, SkRRect& skRRect) const
819 {
820     Rect rect = roundRect.GetRect();
821     SkRect outer = SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
822 
823     SkVector radii[4];
824     Point p;
825 
826     p = roundRect.GetCornerRadius(RoundRect::TOP_LEFT_POS);
827     radii[SkRRect::kUpperLeft_Corner] = { p.GetX(), p.GetY() };
828     p = roundRect.GetCornerRadius(RoundRect::TOP_RIGHT_POS);
829     radii[SkRRect::kUpperRight_Corner] = { p.GetX(), p.GetY() };
830     p = roundRect.GetCornerRadius(RoundRect::BOTTOM_RIGHT_POS);
831     radii[SkRRect::kLowerRight_Corner] = { p.GetX(), p.GetY() };
832     p = roundRect.GetCornerRadius(RoundRect::BOTTOM_LEFT_POS);
833     radii[SkRRect::kLowerLeft_Corner] = { p.GetX(), p.GetY() };
834 
835     skRRect.setRectRadii(outer, radii);
836 }
837 } // namespace Drawing
838 } // namespace Rosen
839 } // namespace OHOS
840