• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "drawing_canvas.h"
17 
18 #include "src/utils/SkUTF.h"
19 
20 #include "drawing_canvas_utils.h"
21 #include "drawing_font_utils.h"
22 #include "drawing_helper.h"
23 #include "image_pixel_map_mdk.h"
24 #include "native_pixel_map.h"
25 #include "native_pixel_map_manager.h"
26 #include "pixelmap_native_impl.h"
27 #include "recording/recording_canvas.h"
28 #include "utils/log.h"
29 
30 using namespace OHOS;
31 using namespace Rosen;
32 using namespace Drawing;
33 
CastToCanvas(OH_Drawing_Canvas * cCanvas)34 static Canvas* CastToCanvas(OH_Drawing_Canvas* cCanvas)
35 {
36     return reinterpret_cast<Canvas*>(cCanvas);
37 }
38 
CastToPath(const OH_Drawing_Path & cPath)39 static const Path& CastToPath(const OH_Drawing_Path& cPath)
40 {
41     return reinterpret_cast<const Path&>(cPath);
42 }
43 
CastToBrush(const OH_Drawing_Brush & cBrush)44 static const Brush& CastToBrush(const OH_Drawing_Brush& cBrush)
45 {
46     return reinterpret_cast<const Brush&>(cBrush);
47 }
48 
CastToPen(const OH_Drawing_Pen & cPen)49 static const Pen& CastToPen(const OH_Drawing_Pen& cPen)
50 {
51     return reinterpret_cast<const Pen&>(cPen);
52 }
53 
CastToRegion(const OH_Drawing_Region & cRegion)54 static const OHOS::Rosen::Drawing::Region& CastToRegion(const OH_Drawing_Region& cRegion)
55 {
56     return reinterpret_cast<const OHOS::Rosen::Drawing::Region&>(cRegion);
57 }
58 
CastToBitmap(const OH_Drawing_Bitmap & cBitmap)59 static const Bitmap& CastToBitmap(const OH_Drawing_Bitmap& cBitmap)
60 {
61     return reinterpret_cast<const Bitmap&>(cBitmap);
62 }
63 
CastToRect(const OH_Drawing_Rect & cRect)64 static const Drawing::Rect& CastToRect(const OH_Drawing_Rect& cRect)
65 {
66     return reinterpret_cast<const Drawing::Rect&>(cRect);
67 }
68 
CastToPoint(const OH_Drawing_Point & cPoint)69 static const Point& CastToPoint(const OH_Drawing_Point& cPoint)
70 {
71     return reinterpret_cast<const Point&>(cPoint);
72 }
73 
CastToPoint(const OH_Drawing_Point2D & cPoint)74 static const Point& CastToPoint(const OH_Drawing_Point2D& cPoint)
75 {
76     return reinterpret_cast<const Point&>(cPoint);
77 }
78 
CastToPoint3(OH_Drawing_Point3D & cPoint3)79 static const Point3& CastToPoint3(OH_Drawing_Point3D& cPoint3)
80 {
81     return reinterpret_cast<const Point3&>(cPoint3);
82 }
83 
CastToRoundRect(const OH_Drawing_RoundRect & cRoundRect)84 static const RoundRect& CastToRoundRect(const OH_Drawing_RoundRect& cRoundRect)
85 {
86     return reinterpret_cast<const RoundRect&>(cRoundRect);
87 }
88 
CastToTextBlob(const OH_Drawing_TextBlob * cTextBlob)89 static const TextBlob* CastToTextBlob(const OH_Drawing_TextBlob* cTextBlob)
90 {
91     return reinterpret_cast<const TextBlob*>(cTextBlob);
92 }
93 
CastToMatrix(const OH_Drawing_Matrix & cMatrix)94 static const Matrix& CastToMatrix(const OH_Drawing_Matrix& cMatrix)
95 {
96     return reinterpret_cast<const Matrix&>(cMatrix);
97 }
98 
CastToImage(const OH_Drawing_Image & cImage)99 static const Image& CastToImage(const OH_Drawing_Image& cImage)
100 {
101     return reinterpret_cast<const Image&>(cImage);
102 }
103 
CastToSamplingOptions(const OH_Drawing_SamplingOptions & cSamplingOptions)104 static const SamplingOptions& CastToSamplingOptions(const OH_Drawing_SamplingOptions& cSamplingOptions)
105 {
106     return reinterpret_cast<const SamplingOptions&>(cSamplingOptions);
107 }
108 
CastToFont(const OH_Drawing_Font * cFont)109 static const Font* CastToFont(const OH_Drawing_Font* cFont)
110 {
111     return reinterpret_cast<const Font*>(cFont);
112 }
113 
OH_Drawing_CanvasCreate()114 OH_Drawing_Canvas* OH_Drawing_CanvasCreate()
115 {
116     return (OH_Drawing_Canvas*)new Canvas;
117 }
118 
OH_Drawing_CanvasDestroy(OH_Drawing_Canvas * cCanvas)119 void OH_Drawing_CanvasDestroy(OH_Drawing_Canvas* cCanvas)
120 {
121     if (!cCanvas) {
122         return;
123     }
124     delete CastToCanvas(cCanvas);
125 }
126 
OH_Drawing_CanvasBind(OH_Drawing_Canvas * cCanvas,OH_Drawing_Bitmap * cBitmap)127 void OH_Drawing_CanvasBind(OH_Drawing_Canvas* cCanvas, OH_Drawing_Bitmap* cBitmap)
128 {
129     if (cBitmap == nullptr) {
130         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
131         return;
132     }
133     Canvas* canvas = CastToCanvas(cCanvas);
134     if (canvas == nullptr) {
135         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
136         return;
137     }
138     canvas->Bind(CastToBitmap(*cBitmap));
139 }
140 
OH_Drawing_CanvasAttachPen(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Pen * cPen)141 void OH_Drawing_CanvasAttachPen(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Pen* cPen)
142 {
143     if (cPen == nullptr) {
144         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
145         return;
146     }
147     Canvas* canvas = CastToCanvas(cCanvas);
148     if (canvas == nullptr) {
149         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
150         return;
151     }
152     canvas->AttachPen(CastToPen(*cPen));
153 }
154 
OH_Drawing_CanvasDetachPen(OH_Drawing_Canvas * cCanvas)155 void OH_Drawing_CanvasDetachPen(OH_Drawing_Canvas* cCanvas)
156 {
157     Canvas* canvas = CastToCanvas(cCanvas);
158     if (canvas == nullptr) {
159         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
160         return;
161     }
162     canvas->DetachPen();
163 }
164 
OH_Drawing_CanvasAttachBrush(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Brush * cBrush)165 void OH_Drawing_CanvasAttachBrush(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Brush* cBrush)
166 {
167     if (cBrush == nullptr) {
168         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
169         return;
170     }
171     Canvas* canvas = CastToCanvas(cCanvas);
172     if (canvas == nullptr) {
173         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
174         return;
175     }
176     canvas->AttachBrush(CastToBrush(*cBrush));
177 }
178 
OH_Drawing_CanvasDetachBrush(OH_Drawing_Canvas * cCanvas)179 void OH_Drawing_CanvasDetachBrush(OH_Drawing_Canvas* cCanvas)
180 {
181     Canvas* canvas = CastToCanvas(cCanvas);
182     if (canvas == nullptr) {
183         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
184         return;
185     }
186     canvas->DetachBrush();
187 }
188 
OH_Drawing_CanvasSave(OH_Drawing_Canvas * cCanvas)189 void OH_Drawing_CanvasSave(OH_Drawing_Canvas* cCanvas)
190 {
191     Canvas* canvas = CastToCanvas(cCanvas);
192     if (canvas == nullptr) {
193         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
194         return;
195     }
196     canvas->Save();
197 }
198 
OH_Drawing_CanvasSaveLayer(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Rect * cRect,const OH_Drawing_Brush * cBrush)199 void OH_Drawing_CanvasSaveLayer(OH_Drawing_Canvas* cCanvas,
200     const OH_Drawing_Rect* cRect, const OH_Drawing_Brush* cBrush)
201 {
202     Canvas* canvas = CastToCanvas(cCanvas);
203     if (canvas == nullptr) {
204         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
205         return;
206     }
207 
208     SaveLayerOps slr = SaveLayerOps(reinterpret_cast<const Drawing::Rect*>(cRect),
209         reinterpret_cast<const Drawing::Brush*>(cBrush));
210     canvas->SaveLayer(slr);
211 }
212 
OH_Drawing_CanvasRestore(OH_Drawing_Canvas * cCanvas)213 void OH_Drawing_CanvasRestore(OH_Drawing_Canvas* cCanvas)
214 {
215     Canvas* canvas = CastToCanvas(cCanvas);
216     if (canvas == nullptr) {
217         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
218         return;
219     }
220     canvas->Restore();
221 }
222 
OH_Drawing_CanvasGetSaveCount(OH_Drawing_Canvas * cCanvas)223 uint32_t OH_Drawing_CanvasGetSaveCount(OH_Drawing_Canvas* cCanvas)
224 {
225     Canvas* canvas = CastToCanvas(cCanvas);
226     if (canvas == nullptr) {
227         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
228         return 0;
229     }
230     return canvas->GetSaveCount();
231 }
232 
OH_Drawing_CanvasRestoreToCount(OH_Drawing_Canvas * cCanvas,uint32_t saveCount)233 void OH_Drawing_CanvasRestoreToCount(OH_Drawing_Canvas* cCanvas, uint32_t saveCount)
234 {
235     Canvas* canvas = CastToCanvas(cCanvas);
236     if (canvas == nullptr) {
237         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
238         return;
239     }
240     canvas->RestoreToCount(saveCount);
241 }
242 
OH_Drawing_CanvasDrawLine(OH_Drawing_Canvas * cCanvas,float x1,float y1,float x2,float y2)243 void OH_Drawing_CanvasDrawLine(OH_Drawing_Canvas* cCanvas, float x1, float y1, float x2, float y2)
244 {
245     Canvas* canvas = CastToCanvas(cCanvas);
246     if (canvas == nullptr) {
247         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
248         return;
249     }
250     Point startPt(x1, y1);
251     Point endPt(x2, y2);
252     canvas->DrawLine(startPt, endPt);
253 }
254 
OH_Drawing_CanvasDrawPath(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Path * cPath)255 void OH_Drawing_CanvasDrawPath(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Path* cPath)
256 {
257     if (cPath == nullptr) {
258         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
259         return;
260     }
261     Canvas* canvas = CastToCanvas(cCanvas);
262     if (canvas == nullptr) {
263         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
264         return;
265     }
266     canvas->DrawPath(CastToPath(*cPath));
267 }
268 
OH_Drawing_CanvasDrawPoints(OH_Drawing_Canvas * cCanvas,OH_Drawing_PointMode mode,uint32_t count,const OH_Drawing_Point2D * pts)269 void OH_Drawing_CanvasDrawPoints(OH_Drawing_Canvas* cCanvas, OH_Drawing_PointMode mode,
270     uint32_t count, const OH_Drawing_Point2D* pts)
271 {
272     if (pts == nullptr || count == 0) {
273         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
274         return;
275     }
276     Canvas* canvas = CastToCanvas(cCanvas);
277     if (canvas == nullptr) {
278         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
279         return;
280     }
281 
282     if (mode < POINT_MODE_POINTS || mode > POINT_MODE_POLYGON) {
283         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
284         return;
285     }
286     const Point* points = reinterpret_cast<const Point*>(pts);
287     canvas->DrawPoints(static_cast<PointMode>(mode), count, points);
288 }
289 
OH_Drawing_CanvasDrawVertices(OH_Drawing_Canvas * cCanvas,OH_Drawing_VertexMode vertexMode,int32_t vertexCount,const OH_Drawing_Point2D * positions,const OH_Drawing_Point2D * texs,const uint32_t * colors,int32_t indexCount,const uint16_t * indices,OH_Drawing_BlendMode mode)290 void OH_Drawing_CanvasDrawVertices(OH_Drawing_Canvas* cCanvas, OH_Drawing_VertexMode vertexMode,
291     int32_t vertexCount, const OH_Drawing_Point2D* positions, const OH_Drawing_Point2D* texs,
292     const uint32_t* colors, int32_t indexCount, const uint16_t* indices, OH_Drawing_BlendMode mode)
293 {
294     // 3 means the minimum number of vertices required for a triangle
295     if (positions == nullptr || vertexCount < 3 || (indexCount < 3 && indexCount != 0)) {
296         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
297         return;
298     }
299 
300     Canvas* canvas = CastToCanvas(cCanvas);
301     if (canvas == nullptr) {
302         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
303         return;
304     }
305 
306     if (vertexMode < VERTEX_MODE_TRIANGLES || vertexMode > VERTEX_MODE_TRIANGLE_FAN) {
307         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
308         return;
309     }
310 
311     if (mode < BLEND_MODE_CLEAR || mode > BLEND_MODE_LUMINOSITY) {
312         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
313         return;
314     }
315 
316     Point* positionsPoint = new(std::nothrow) Point[vertexCount];
317     if (positionsPoint == nullptr) {
318         LOGE("OH_Drawing_CanvasDrawVertices: new position point failed.");
319         return;
320     }
321     for (int32_t i = 0; i < vertexCount; ++i) {
322         positionsPoint[i] = CastToPoint(positions[i]);
323     }
324 
325     Point* texsPoint = nullptr;
326     if (texs != nullptr) {
327         texsPoint = new(std::nothrow) Point[vertexCount];
328         if (texsPoint == nullptr) {
329             delete [] positionsPoint;
330             LOGE("OH_Drawing_CanvasDrawVertices: new texs point failed.");
331             return;
332         }
333         for (int32_t i = 0; i < vertexCount; i++) {
334             texsPoint[i] = CastToPoint(texs[i]);
335         }
336     }
337 
338     Vertices* vertices = new Vertices();
339     bool result = vertices->MakeCopy(static_cast<VertexMode>(vertexMode), vertexCount, positionsPoint,
340         texsPoint, colors, indices ? indexCount : 0, indices);
341     if (result) {
342         canvas->DrawVertices(*vertices, static_cast<BlendMode>(mode));
343     }
344     delete vertices;
345     delete [] positionsPoint;
346     delete [] texsPoint;
347 }
348 
OH_Drawing_CanvasDrawBackground(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Brush * cBrush)349 void OH_Drawing_CanvasDrawBackground(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Brush* cBrush)
350 {
351     if (cBrush == nullptr) {
352         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
353         return;
354     }
355     Canvas* canvas = CastToCanvas(cCanvas);
356     if (canvas == nullptr) {
357         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
358         return;
359     }
360     canvas->DrawBackground(CastToBrush(*cBrush));
361 }
362 
OH_Drawing_CanvasDrawRegion(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Region * cRegion)363 void OH_Drawing_CanvasDrawRegion(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Region* cRegion)
364 {
365     if (cRegion == nullptr) {
366         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
367         return;
368     }
369     Canvas* canvas = CastToCanvas(cCanvas);
370     if (canvas == nullptr) {
371         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
372         return;
373     }
374     canvas->DrawRegion(CastToRegion(*cRegion));
375 }
376 
OH_Drawing_CanvasDrawBitmap(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Bitmap * cBitmap,float left,float top)377 void OH_Drawing_CanvasDrawBitmap(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Bitmap* cBitmap, float left, float top)
378 {
379     if (cBitmap == nullptr) {
380         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
381         return;
382     }
383     Canvas* canvas = CastToCanvas(cCanvas);
384     if (canvas == nullptr) {
385         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
386         return;
387     }
388     canvas->DrawBitmap(CastToBitmap(*cBitmap), left, top);
389 }
390 
OH_Drawing_CanvasDrawPixelMapRect(OH_Drawing_Canvas * cCanvas,OH_Drawing_PixelMap * pixelMap,const OH_Drawing_Rect * src,const OH_Drawing_Rect * dst,const OH_Drawing_SamplingOptions * cSampingOptions)391 void OH_Drawing_CanvasDrawPixelMapRect(OH_Drawing_Canvas* cCanvas, OH_Drawing_PixelMap* pixelMap,
392     const OH_Drawing_Rect* src, const OH_Drawing_Rect* dst, const OH_Drawing_SamplingOptions* cSampingOptions)
393 {
394 #ifdef OHOS_PLATFORM
395     std::shared_ptr<Media::PixelMap> p = nullptr;
396     switch (NativePixelMapManager::GetInstance().GetNativePixelMapType(pixelMap)) {
397         case NativePixelMapType::OBJECT_FROM_C:
398             if (pixelMap) {
399                 p = reinterpret_cast<OH_PixelmapNative*>(pixelMap)->GetInnerPixelmap();
400             }
401             break;
402         case NativePixelMapType::OBJECT_FROM_JS:
403             p = Media::PixelMapNative_GetPixelMap(reinterpret_cast<NativePixelMap_*>(pixelMap));
404             break;
405         default:
406             break;
407     }
408     DrawingCanvasUtils::DrawPixelMapRect(CastToCanvas(cCanvas), p,
409         reinterpret_cast<const Drawing::Rect*>(src), reinterpret_cast<const Drawing::Rect*>(dst),
410         reinterpret_cast<const Drawing::SamplingOptions*>(cSampingOptions));
411 #endif
412 }
413 
OH_Drawing_CanvasDrawBitmapRect(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Bitmap * cBitmap,const OH_Drawing_Rect * src,const OH_Drawing_Rect * dst,const OH_Drawing_SamplingOptions * cSampling)414 void OH_Drawing_CanvasDrawBitmapRect(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Bitmap* cBitmap,
415     const OH_Drawing_Rect* src, const OH_Drawing_Rect* dst, const OH_Drawing_SamplingOptions* cSampling)
416 {
417     Canvas* canvas = CastToCanvas(cCanvas);
418     if (canvas == nullptr || cBitmap == nullptr || dst == nullptr) {
419         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
420         return;
421     }
422     const Bitmap& bitmap = CastToBitmap(*cBitmap);
423     auto image = bitmap.MakeImage();
424     if (image == nullptr) {
425         return;
426     }
427     if (src == nullptr) {
428         canvas->DrawImageRect(*image, CastToRect(*dst),
429             cSampling ? CastToSamplingOptions(*cSampling) : Drawing::SamplingOptions());
430     } else {
431         canvas->DrawImageRect(*image, CastToRect(*src),
432             CastToRect(*dst), cSampling ? CastToSamplingOptions(*cSampling) : Drawing::SamplingOptions());
433     }
434 }
435 
OH_Drawing_CanvasDrawRect(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Rect * cRect)436 void OH_Drawing_CanvasDrawRect(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Rect* cRect)
437 {
438     if (cRect == nullptr) {
439         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
440         return;
441     }
442     Canvas* canvas = CastToCanvas(cCanvas);
443     if (canvas == nullptr) {
444         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
445         return;
446     }
447     canvas->DrawRect(CastToRect(*cRect));
448 }
449 
OH_Drawing_CanvasDrawCircle(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Point * cPoint,float radius)450 void OH_Drawing_CanvasDrawCircle(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Point* cPoint, float radius)
451 {
452     if (cPoint == nullptr) {
453         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
454         return;
455     }
456     if (radius <= 0) {
457         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
458         return;
459     }
460     Canvas* canvas = CastToCanvas(cCanvas);
461     if (canvas == nullptr) {
462         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
463         return;
464     }
465     canvas->DrawCircle(CastToPoint(*cPoint), radius);
466 }
467 
OH_Drawing_CanvasDrawOval(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Rect * cRect)468 void OH_Drawing_CanvasDrawOval(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Rect* cRect)
469 {
470     if (cRect == nullptr) {
471         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
472         return;
473     }
474     Canvas* canvas = CastToCanvas(cCanvas);
475     if (canvas == nullptr) {
476         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
477         return;
478     }
479     canvas->DrawOval(CastToRect(*cRect));
480 }
481 
OH_Drawing_CanvasDrawArc(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Rect * cRect,float startAngle,float sweepAngle)482 void OH_Drawing_CanvasDrawArc(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Rect* cRect,
483     float startAngle, float sweepAngle)
484 {
485     if (cRect == nullptr) {
486         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
487         return;
488     }
489     Canvas* canvas = CastToCanvas(cCanvas);
490     if (canvas == nullptr) {
491         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
492         return;
493     }
494     canvas->DrawArc(CastToRect(*cRect), startAngle, sweepAngle);
495 }
496 
OH_Drawing_CanvasDrawRoundRect(OH_Drawing_Canvas * cCanvas,const OH_Drawing_RoundRect * cRoundRect)497 void OH_Drawing_CanvasDrawRoundRect(OH_Drawing_Canvas* cCanvas, const OH_Drawing_RoundRect* cRoundRect)
498 {
499     if (cRoundRect == nullptr) {
500         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
501         return;
502     }
503     Canvas* canvas = CastToCanvas(cCanvas);
504     if (canvas == nullptr) {
505         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
506         return;
507     }
508     canvas->DrawRoundRect(CastToRoundRect(*cRoundRect));
509 }
510 
OH_Drawing_CanvasDrawSingleCharacter(OH_Drawing_Canvas * cCanvas,const char * str,const OH_Drawing_Font * cFont,float x,float y)511 OH_Drawing_ErrorCode OH_Drawing_CanvasDrawSingleCharacter(OH_Drawing_Canvas* cCanvas, const char* str,
512     const OH_Drawing_Font* cFont, float x, float y)
513 {
514     if (str == nullptr || cFont == nullptr) {
515         return OH_DRAWING_ERROR_INVALID_PARAMETER;
516     }
517     Canvas* canvas = CastToCanvas(cCanvas);
518     if (canvas == nullptr) {
519         return OH_DRAWING_ERROR_INVALID_PARAMETER;
520     }
521     size_t len = strlen(str);
522     if (len == 0) {
523         return OH_DRAWING_ERROR_INVALID_PARAMETER;
524     }
525     const char* currentStr = str;
526     int32_t unicode = SkUTF::NextUTF8(&currentStr, currentStr + len);
527     const Font* font = CastToFont(cFont);
528     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
529     if (themeFont != nullptr) {
530         font = themeFont.get();
531     }
532     canvas->DrawSingleCharacter(unicode, *font, x, y);
533     return OH_DRAWING_SUCCESS;
534 }
535 
OH_Drawing_CanvasDrawTextBlob(OH_Drawing_Canvas * cCanvas,const OH_Drawing_TextBlob * cTextBlob,float x,float y)536 void OH_Drawing_CanvasDrawTextBlob(OH_Drawing_Canvas* cCanvas, const OH_Drawing_TextBlob* cTextBlob, float x, float y)
537 {
538     if (cTextBlob == nullptr) {
539         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
540         return;
541     }
542     Canvas* canvas = CastToCanvas(cCanvas);
543     if (canvas == nullptr) {
544         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
545         return;
546     }
547     canvas->DrawTextBlob(CastToTextBlob(cTextBlob), x, y);
548 }
549 
OH_Drawing_CanvasClipRect(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Rect * cRect,OH_Drawing_CanvasClipOp cClipOp,bool doAntiAlias)550 void OH_Drawing_CanvasClipRect(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Rect* cRect,
551     OH_Drawing_CanvasClipOp cClipOp, bool doAntiAlias)
552 {
553     if (cRect == nullptr) {
554         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
555         return;
556     }
557     Canvas* canvas = CastToCanvas(cCanvas);
558     if (canvas == nullptr) {
559         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
560         return;
561     }
562 
563     if (cClipOp < DIFFERENCE || cClipOp > INTERSECT) {
564         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
565         return;
566     }
567     canvas->ClipRect(CastToRect(*cRect), static_cast<ClipOp>(cClipOp), doAntiAlias);
568 }
569 
OH_Drawing_CanvasClipRoundRect(OH_Drawing_Canvas * cCanvas,const OH_Drawing_RoundRect * cRoundRect,OH_Drawing_CanvasClipOp cClipOp,bool doAntiAlias)570 void OH_Drawing_CanvasClipRoundRect(OH_Drawing_Canvas* cCanvas, const OH_Drawing_RoundRect* cRoundRect,
571     OH_Drawing_CanvasClipOp cClipOp, bool doAntiAlias)
572 {
573     if (cRoundRect == nullptr) {
574         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
575         return;
576     }
577     Canvas* canvas = CastToCanvas(cCanvas);
578     if (canvas == nullptr) {
579         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
580         return;
581     }
582 
583     if (cClipOp < DIFFERENCE || cClipOp > INTERSECT) {
584         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
585         return;
586     }
587     canvas->ClipRoundRect(CastToRoundRect(*cRoundRect), static_cast<ClipOp>(cClipOp), doAntiAlias);
588 }
589 
OH_Drawing_CanvasClipPath(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Path * cPath,OH_Drawing_CanvasClipOp cClipOp,bool doAntiAlias)590 void OH_Drawing_CanvasClipPath(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Path* cPath,
591     OH_Drawing_CanvasClipOp cClipOp, bool doAntiAlias)
592 {
593     if (cPath == nullptr) {
594         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
595         return;
596     }
597     Canvas* canvas = CastToCanvas(cCanvas);
598     if (canvas == nullptr) {
599         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
600         return;
601     }
602 
603     if (cClipOp < DIFFERENCE || cClipOp > INTERSECT) {
604         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
605         return;
606     }
607     canvas->ClipPath(CastToPath(*cPath), static_cast<ClipOp>(cClipOp), doAntiAlias);
608 }
609 
OH_Drawing_CanvasRotate(OH_Drawing_Canvas * cCanvas,float degrees,float px,float py)610 void OH_Drawing_CanvasRotate(OH_Drawing_Canvas* cCanvas, float degrees, float px, float py)
611 {
612     Canvas* canvas = CastToCanvas(cCanvas);
613     if (canvas == nullptr) {
614         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
615         return;
616     }
617     canvas->Rotate(degrees, px, py);
618 }
619 
OH_Drawing_CanvasTranslate(OH_Drawing_Canvas * cCanvas,float dx,float dy)620 void OH_Drawing_CanvasTranslate(OH_Drawing_Canvas* cCanvas, float dx, float dy)
621 {
622     Canvas* canvas = CastToCanvas(cCanvas);
623     if (canvas == nullptr) {
624         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
625         return;
626     }
627     canvas->Translate(dx, dy);
628 }
629 
OH_Drawing_CanvasScale(OH_Drawing_Canvas * cCanvas,float sx,float sy)630 void OH_Drawing_CanvasScale(OH_Drawing_Canvas* cCanvas, float sx, float sy)
631 {
632     Canvas* canvas = CastToCanvas(cCanvas);
633     if (canvas == nullptr) {
634         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
635         return;
636     }
637     canvas->Scale(sx, sy);
638 }
639 
OH_Drawing_CanvasSkew(OH_Drawing_Canvas * cCanvas,float sx,float sy)640 void OH_Drawing_CanvasSkew(OH_Drawing_Canvas* cCanvas, float sx, float sy)
641 {
642     Canvas* canvas = CastToCanvas(cCanvas);
643     if (canvas == nullptr) {
644         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
645         return;
646     }
647     canvas->Shear(sx, sy);
648 }
649 
OH_Drawing_CanvasClear(OH_Drawing_Canvas * cCanvas,uint32_t color)650 void OH_Drawing_CanvasClear(OH_Drawing_Canvas* cCanvas, uint32_t color)
651 {
652     Canvas* canvas = CastToCanvas(cCanvas);
653     if (canvas == nullptr) {
654         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
655         return;
656     }
657     canvas->Clear(color);
658 }
659 
OH_Drawing_CanvasGetWidth(OH_Drawing_Canvas * cCanvas)660 int32_t OH_Drawing_CanvasGetWidth(OH_Drawing_Canvas* cCanvas)
661 {
662     Canvas* canvas = CastToCanvas(cCanvas);
663     if (canvas == nullptr) {
664         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
665         return 0;
666     }
667     return canvas->GetWidth();
668 }
669 
OH_Drawing_CanvasGetHeight(OH_Drawing_Canvas * cCanvas)670 int32_t OH_Drawing_CanvasGetHeight(OH_Drawing_Canvas* cCanvas)
671 {
672     Canvas* canvas = CastToCanvas(cCanvas);
673     if (canvas == nullptr) {
674         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
675         return 0;
676     }
677     return canvas->GetHeight();
678 }
679 
OH_Drawing_CanvasGetLocalClipBounds(OH_Drawing_Canvas * cCanvas,OH_Drawing_Rect * cRect)680 void OH_Drawing_CanvasGetLocalClipBounds(OH_Drawing_Canvas* cCanvas, OH_Drawing_Rect* cRect)
681 {
682     if (cRect == nullptr) {
683         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
684         return;
685     }
686     Canvas* canvas = CastToCanvas(cCanvas);
687     if (canvas == nullptr) {
688         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
689         return;
690     }
691     Drawing::Rect rect = canvas->GetLocalClipBounds();
692     Drawing::Rect* outRect = reinterpret_cast<Drawing::Rect*>(cRect);
693     *outRect = rect;
694 }
695 
OH_Drawing_CanvasGetTotalMatrix(OH_Drawing_Canvas * cCanvas,OH_Drawing_Matrix * cMatrix)696 void OH_Drawing_CanvasGetTotalMatrix(OH_Drawing_Canvas* cCanvas, OH_Drawing_Matrix* cMatrix)
697 {
698     Canvas* canvas = CastToCanvas(cCanvas);
699     if (canvas == nullptr || cMatrix == nullptr) {
700         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
701         return;
702     }
703     Matrix matrix = canvas->GetTotalMatrix();
704     Matrix* outMatrix = reinterpret_cast<Matrix*>(cMatrix);
705     *outMatrix = matrix;
706 }
707 
OH_Drawing_CanvasConcatMatrix(OH_Drawing_Canvas * cCanvas,OH_Drawing_Matrix * cMatrix)708 void OH_Drawing_CanvasConcatMatrix(OH_Drawing_Canvas* cCanvas, OH_Drawing_Matrix* cMatrix)
709 {
710     Canvas* canvas = CastToCanvas(cCanvas);
711     if (canvas == nullptr || cMatrix == nullptr) {
712         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
713         return;
714     }
715     canvas->ConcatMatrix(*reinterpret_cast<Matrix*>(cMatrix));
716 }
717 
OH_Drawing_CanvasDrawShadow(OH_Drawing_Canvas * cCanvas,OH_Drawing_Path * cPath,OH_Drawing_Point3D cPlaneParams,OH_Drawing_Point3D cDevLightPos,float lightRadius,uint32_t ambientColor,uint32_t spotColor,OH_Drawing_CanvasShadowFlags flag)718 void OH_Drawing_CanvasDrawShadow(OH_Drawing_Canvas* cCanvas, OH_Drawing_Path* cPath, OH_Drawing_Point3D cPlaneParams,
719     OH_Drawing_Point3D cDevLightPos, float lightRadius, uint32_t ambientColor, uint32_t spotColor,
720     OH_Drawing_CanvasShadowFlags flag)
721 {
722     Canvas* canvas = CastToCanvas(cCanvas);
723     if (canvas == nullptr || cPath == nullptr) {
724         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
725         return;
726     }
727     if (flag < SHADOW_FLAGS_NONE || flag > SHADOW_FLAGS_ALL) {
728         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
729         return;
730     }
731     canvas->DrawShadow(*reinterpret_cast<Path*>(cPath), CastToPoint3(cPlaneParams),
732         CastToPoint3(cDevLightPos), lightRadius, Color(ambientColor), Color(spotColor),
733         static_cast<ShadowFlags>(flag));
734 }
735 
OH_Drawing_CanvasSetMatrix(OH_Drawing_Canvas * cCanvas,OH_Drawing_Matrix * matrix)736 void OH_Drawing_CanvasSetMatrix(OH_Drawing_Canvas* cCanvas, OH_Drawing_Matrix* matrix)
737 {
738     Canvas* canvas = CastToCanvas(cCanvas);
739     if (canvas == nullptr || matrix == nullptr) {
740         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
741         return;
742     }
743     canvas->SetMatrix(CastToMatrix(*matrix));
744 }
745 
OH_Drawing_CanvasResetMatrix(OH_Drawing_Canvas * cCanvas)746 void OH_Drawing_CanvasResetMatrix(OH_Drawing_Canvas* cCanvas)
747 {
748     Canvas* canvas = CastToCanvas(cCanvas);
749     if (canvas == nullptr) {
750         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
751         return;
752     }
753     canvas->ResetMatrix();
754 }
755 
OH_Drawing_CanvasDrawImageRectWithSrc(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Image * cImage,const OH_Drawing_Rect * src,const OH_Drawing_Rect * dst,const OH_Drawing_SamplingOptions * cSampling,OH_Drawing_SrcRectConstraint constraint)756 void OH_Drawing_CanvasDrawImageRectWithSrc(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Image* cImage,
757     const OH_Drawing_Rect* src, const OH_Drawing_Rect* dst, const OH_Drawing_SamplingOptions* cSampling,
758     OH_Drawing_SrcRectConstraint constraint)
759 {
760     Canvas* canvas = CastToCanvas(cCanvas);
761     if (canvas == nullptr || cImage == nullptr || src == nullptr || dst == nullptr) {
762         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
763         return;
764     }
765     canvas->DrawImageRect(CastToImage(*cImage), CastToRect(*src), CastToRect(*dst), cSampling
766         ? CastToSamplingOptions(*cSampling) : Drawing::SamplingOptions(), static_cast<SrcRectConstraint>(constraint));
767 }
768 
OH_Drawing_CanvasDrawImageRect(OH_Drawing_Canvas * cCanvas,OH_Drawing_Image * cImage,OH_Drawing_Rect * dst,OH_Drawing_SamplingOptions * cSampling)769 void OH_Drawing_CanvasDrawImageRect(OH_Drawing_Canvas* cCanvas, OH_Drawing_Image* cImage, OH_Drawing_Rect* dst,
770     OH_Drawing_SamplingOptions* cSampling)
771 {
772     Canvas* canvas = CastToCanvas(cCanvas);
773     if (canvas == nullptr || cImage == nullptr || dst == nullptr) {
774         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
775         return;
776     }
777     canvas->DrawImageRect(CastToImage(*cImage), CastToRect(*dst),
778         cSampling ? CastToSamplingOptions(*cSampling) : Drawing::SamplingOptions());
779 }
780 
OH_Drawing_CanvasReadPixels(OH_Drawing_Canvas * cCanvas,OH_Drawing_Image_Info * cImageInfo,void * dstPixels,uint32_t dstRowBytes,int32_t srcX,int32_t srcY)781 bool OH_Drawing_CanvasReadPixels(OH_Drawing_Canvas* cCanvas, OH_Drawing_Image_Info* cImageInfo,
782     void* dstPixels, uint32_t dstRowBytes, int32_t srcX, int32_t srcY)
783 {
784     Canvas* canvas = CastToCanvas(cCanvas);
785     if (canvas == nullptr || cImageInfo == nullptr || dstPixels == nullptr) {
786         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
787         return false;
788     }
789     ImageInfo imageInfo(cImageInfo->width, cImageInfo->height,
790         static_cast<ColorType>(cImageInfo->colorType), static_cast<AlphaType>(cImageInfo->alphaType));
791     return canvas->ReadPixels(imageInfo, dstPixels, dstRowBytes, srcX, srcY);
792 }
793 
OH_Drawing_CanvasReadPixelsToBitmap(OH_Drawing_Canvas * cCanvas,OH_Drawing_Bitmap * cBitmap,int32_t srcX,int32_t srcY)794 bool OH_Drawing_CanvasReadPixelsToBitmap(OH_Drawing_Canvas* cCanvas, OH_Drawing_Bitmap* cBitmap,
795     int32_t srcX, int32_t srcY)
796 {
797     Canvas* canvas = CastToCanvas(cCanvas);
798     if (canvas == nullptr || cBitmap == nullptr) {
799         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
800         return false;
801     }
802     return canvas->ReadPixels(CastToBitmap(*cBitmap), srcX, srcY);
803 }
804 
OH_Drawing_CanvasIsClipEmpty(OH_Drawing_Canvas * cCanvas,bool * isClipEmpty)805 OH_Drawing_ErrorCode OH_Drawing_CanvasIsClipEmpty(OH_Drawing_Canvas* cCanvas, bool* isClipEmpty)
806 {
807     if (isClipEmpty == nullptr) {
808         return OH_DRAWING_ERROR_INVALID_PARAMETER;
809     }
810     Canvas* canvas = CastToCanvas(cCanvas);
811     if (canvas == nullptr) {
812         return OH_DRAWING_ERROR_INVALID_PARAMETER;
813     }
814     *isClipEmpty = canvas->IsClipEmpty();
815     return OH_DRAWING_SUCCESS;
816 }
817 
OH_Drawing_CanvasGetImageInfo(OH_Drawing_Canvas * cCanvas,OH_Drawing_Image_Info * cImageInfo)818 OH_Drawing_ErrorCode OH_Drawing_CanvasGetImageInfo(OH_Drawing_Canvas* cCanvas, OH_Drawing_Image_Info* cImageInfo)
819 {
820     if (cCanvas == nullptr || cImageInfo == nullptr) {
821         return OH_DRAWING_ERROR_INVALID_PARAMETER;
822     }
823     ImageInfo imageInfo = CastToCanvas(cCanvas)->GetImageInfo();
824 
825     cImageInfo->width = imageInfo.GetWidth();
826     cImageInfo->height = imageInfo.GetHeight();
827     cImageInfo->colorType = static_cast<OH_Drawing_ColorFormat>(imageInfo.GetColorType());
828     cImageInfo->alphaType = static_cast<OH_Drawing_AlphaFormat>(imageInfo.GetAlphaType());
829     return OH_DRAWING_SUCCESS;
830 }
831 
OH_Drawing_CanvasClipRegion(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Region * cRegion,OH_Drawing_CanvasClipOp op)832 OH_Drawing_ErrorCode OH_Drawing_CanvasClipRegion(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Region* cRegion,
833     OH_Drawing_CanvasClipOp op)
834 {
835     if (cRegion == nullptr) {
836         return OH_DRAWING_ERROR_INVALID_PARAMETER;
837     }
838     Canvas* canvas = CastToCanvas(cCanvas);
839     if (canvas == nullptr) {
840         return OH_DRAWING_ERROR_INVALID_PARAMETER;
841     }
842 
843     if (op < DIFFERENCE || op > INTERSECT) {
844         return OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
845     }
846     canvas->ClipRegion(CastToRegion(*cRegion), static_cast<ClipOp>(op));
847     return OH_DRAWING_SUCCESS;
848 }
849 
OH_Drawing_CanvasDrawPoint(OH_Drawing_Canvas * cCanvas,const OH_Drawing_Point2D * cPoint)850 OH_Drawing_ErrorCode OH_Drawing_CanvasDrawPoint(OH_Drawing_Canvas* cCanvas, const OH_Drawing_Point2D* cPoint)
851 {
852     if (cPoint == nullptr) {
853         return OH_DRAWING_ERROR_INVALID_PARAMETER;
854     }
855     Canvas* canvas = CastToCanvas(cCanvas);
856     if (canvas == nullptr) {
857         return OH_DRAWING_ERROR_INVALID_PARAMETER;
858     }
859     canvas->DrawPoint(CastToPoint(*cPoint));
860     return OH_DRAWING_SUCCESS;
861 }
862 
OH_Drawing_CanvasDrawColor(OH_Drawing_Canvas * cCanvas,uint32_t color,OH_Drawing_BlendMode cBlendMode)863 OH_Drawing_ErrorCode OH_Drawing_CanvasDrawColor(OH_Drawing_Canvas* cCanvas, uint32_t color,
864     OH_Drawing_BlendMode cBlendMode)
865 {
866     Canvas* canvas = CastToCanvas(cCanvas);
867     if (canvas == nullptr) {
868         return OH_DRAWING_ERROR_INVALID_PARAMETER;
869     }
870 
871     if (cBlendMode < BLEND_MODE_CLEAR || cBlendMode > BLEND_MODE_LUMINOSITY) {
872         return OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
873     }
874 
875     canvas->DrawColor(color, static_cast<BlendMode>(cBlendMode));
876     return OH_DRAWING_SUCCESS;
877 }
878 
OH_Drawing_CanvasDrawRecordCmd(OH_Drawing_Canvas * cCanvas,OH_Drawing_RecordCmd * cRecordCmd)879 OH_Drawing_ErrorCode OH_Drawing_CanvasDrawRecordCmd(OH_Drawing_Canvas* cCanvas,
880     OH_Drawing_RecordCmd* cRecordCmd)
881 {
882     if (cCanvas == nullptr || cRecordCmd == nullptr) {
883         return OH_DRAWING_ERROR_INVALID_PARAMETER;
884     }
885     Canvas* canvas = CastToCanvas(cCanvas);
886     auto recordCmdHandle = Helper::CastTo<OH_Drawing_RecordCmd*, NativeHandle<RecordCmd>*>(cRecordCmd);
887     if (recordCmdHandle->value == nullptr) {
888         return OH_DRAWING_ERROR_INVALID_PARAMETER;
889     }
890     canvas->DrawRecordCmd(recordCmdHandle->value);
891     return OH_DRAWING_SUCCESS;
892 }