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