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*>(¢er);
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