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_path.h"
17 
18 #include "drawing_canvas_utils.h"
19 
20 #include "draw/path.h"
21 
22 using namespace OHOS;
23 using namespace Rosen;
24 using namespace Drawing;
25 
CastToPath(OH_Drawing_Path * cPath)26 static Path* CastToPath(OH_Drawing_Path* cPath)
27 {
28     return reinterpret_cast<Path*>(cPath);
29 }
30 
CastToMatrix(const OH_Drawing_Matrix * cMatrix)31 static const Matrix* CastToMatrix(const OH_Drawing_Matrix* cMatrix)
32 {
33     return reinterpret_cast<const Matrix*>(cMatrix);
34 }
35 
CastToMatrix(OH_Drawing_Matrix * cMatrix)36 static Matrix* CastToMatrix(OH_Drawing_Matrix* cMatrix)
37 {
38     return reinterpret_cast<Matrix*>(cMatrix);
39 }
40 
CastToRect(const OH_Drawing_Rect & cRect)41 static const Rect& CastToRect(const OH_Drawing_Rect& cRect)
42 {
43     return reinterpret_cast<const Rect&>(cRect);
44 }
45 
CastToRect(OH_Drawing_Rect * cRect)46 static Rect* CastToRect(OH_Drawing_Rect* cRect)
47 {
48     return reinterpret_cast<Rect*>(cRect);
49 }
50 
CastToRoundRect(const OH_Drawing_RoundRect & cRoundRect)51 static const RoundRect& CastToRoundRect(const OH_Drawing_RoundRect& cRoundRect)
52 {
53     return reinterpret_cast<const RoundRect&>(cRoundRect);
54 }
55 
CastToPoint(OH_Drawing_Point2D * cPoint)56 static Point* CastToPoint(OH_Drawing_Point2D* cPoint)
57 {
58     return reinterpret_cast<Point*>(cPoint);
59 }
60 
CastToPoint(const OH_Drawing_Point2D * cPoint)61 static const Point* CastToPoint(const OH_Drawing_Point2D* cPoint)
62 {
63     return reinterpret_cast<const Point*>(cPoint);
64 }
65 
OH_Drawing_PathCreate()66 OH_Drawing_Path* OH_Drawing_PathCreate()
67 {
68     return (OH_Drawing_Path*)new Path;
69 }
70 
OH_Drawing_PathCopy(OH_Drawing_Path * cPath)71 OH_Drawing_Path* OH_Drawing_PathCopy(OH_Drawing_Path* cPath)
72 {
73     Path* path = CastToPath(cPath);
74     if (path == nullptr) {
75         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
76         return nullptr;
77     }
78     return (OH_Drawing_Path*)new Path(*path);
79 }
80 
OH_Drawing_PathDestroy(OH_Drawing_Path * cPath)81 void OH_Drawing_PathDestroy(OH_Drawing_Path* cPath)
82 {
83     if (!cPath) {
84         return;
85     }
86     delete CastToPath(cPath);
87 }
88 
OH_Drawing_PathMoveTo(OH_Drawing_Path * cPath,float x,float y)89 void OH_Drawing_PathMoveTo(OH_Drawing_Path* cPath, float x, float y)
90 {
91     Path* path = CastToPath(cPath);
92     if (path == nullptr) {
93         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
94         return;
95     }
96     path->MoveTo(x, y);
97 }
98 
OH_Drawing_PathRMoveTo(OH_Drawing_Path * cPath,float x,float y)99 void OH_Drawing_PathRMoveTo(OH_Drawing_Path* cPath, float x, float y)
100 {
101     Path* path = CastToPath(cPath);
102     if (path == nullptr) {
103         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
104         return;
105     }
106     path->RMoveTo(x, y);
107 }
108 
OH_Drawing_PathLineTo(OH_Drawing_Path * cPath,float x,float y)109 void OH_Drawing_PathLineTo(OH_Drawing_Path* cPath, float x, float y)
110 {
111     Path* path = CastToPath(cPath);
112     if (path == nullptr) {
113         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
114         return;
115     }
116     path->LineTo(x, y);
117 }
118 
OH_Drawing_PathRLineTo(OH_Drawing_Path * cPath,float x,float y)119 void OH_Drawing_PathRLineTo(OH_Drawing_Path* cPath, float x, float y)
120 {
121     Path* path = CastToPath(cPath);
122     if (path == nullptr) {
123         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
124         return;
125     }
126     path->RLineTo(x, y);
127 }
128 
OH_Drawing_PathArcTo(OH_Drawing_Path * cPath,float x1,float y1,float x2,float y2,float startDeg,float sweepDeg)129 void OH_Drawing_PathArcTo(
130     OH_Drawing_Path* cPath, float x1, float y1, float x2, float y2, float startDeg, float sweepDeg)
131 {
132     Path* path = CastToPath(cPath);
133     if (path == nullptr) {
134         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
135         return;
136     }
137     path->ArcTo(x1, y1, x2, y2, startDeg, sweepDeg);
138 }
139 
OH_Drawing_PathQuadTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY)140 void OH_Drawing_PathQuadTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, float endX, float endY)
141 {
142     Path* path = CastToPath(cPath);
143     if (path == nullptr) {
144         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
145         return;
146     }
147     path->QuadTo(ctrlX, ctrlY, endX, endY);
148 }
149 
OH_Drawing_PathRQuadTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY)150 void OH_Drawing_PathRQuadTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, float endX, float endY)
151 {
152     Path* path = CastToPath(cPath);
153     if (path == nullptr) {
154         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
155         return;
156     }
157     path->RQuadTo(ctrlX, ctrlY, endX, endY);
158 }
159 
OH_Drawing_PathConicTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY,float weight)160 void OH_Drawing_PathConicTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, float endX, float endY, float weight)
161 {
162     Path* path = CastToPath(cPath);
163     if (path == nullptr) {
164         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
165         return;
166     }
167     path->ConicTo(ctrlX, ctrlY, endX, endY, weight);
168 }
169 
OH_Drawing_PathRConicTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY,float weight)170 void OH_Drawing_PathRConicTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, float endX, float endY, float weight)
171 {
172     Path* path = CastToPath(cPath);
173     if (path == nullptr) {
174         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
175         return;
176     }
177     path->RConicTo(ctrlX, ctrlY, endX, endY, weight);
178 }
179 
OH_Drawing_PathCubicTo(OH_Drawing_Path * cPath,float ctrlX1,float ctrlY1,float ctrlX2,float ctrlY2,float endX,float endY)180 void OH_Drawing_PathCubicTo(
181     OH_Drawing_Path* cPath, float ctrlX1, float ctrlY1, float ctrlX2, float ctrlY2, float endX, float endY)
182 {
183     Path* path = CastToPath(cPath);
184     if (path == nullptr) {
185         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
186         return;
187     }
188     path->CubicTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);
189 }
190 
OH_Drawing_PathRCubicTo(OH_Drawing_Path * cPath,float ctrlX1,float ctrlY1,float ctrlX2,float ctrlY2,float endX,float endY)191 void OH_Drawing_PathRCubicTo(
192     OH_Drawing_Path* cPath, float ctrlX1, float ctrlY1, float ctrlX2, float ctrlY2, float endX, float endY)
193 {
194     Path* path = CastToPath(cPath);
195     if (path == nullptr) {
196         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
197         return;
198     }
199     path->RCubicTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);
200 }
201 
OH_Drawing_PathAddRect(OH_Drawing_Path * cPath,float left,float top,float right,float bottom,OH_Drawing_PathDirection dir)202 void OH_Drawing_PathAddRect(OH_Drawing_Path* cPath, float left,
203     float top, float right, float bottom, OH_Drawing_PathDirection dir)
204 {
205     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
206         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
207         return;
208     }
209     Path* path = CastToPath(cPath);
210     if (path == nullptr) {
211         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
212         return;
213     }
214     path->AddRect(left, top, right, bottom, static_cast<PathDirection>(dir));
215 }
216 
OH_Drawing_PathAddRectWithInitialCorner(OH_Drawing_Path * cPath,const OH_Drawing_Rect * cRect,OH_Drawing_PathDirection dir,uint32_t start)217 void OH_Drawing_PathAddRectWithInitialCorner(OH_Drawing_Path* cPath, const OH_Drawing_Rect* cRect,
218     OH_Drawing_PathDirection dir, uint32_t start)
219 {
220     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
221         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
222         return;
223     }
224     if (cRect == nullptr) {
225         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
226         return;
227     }
228     Path* path = CastToPath(cPath);
229     if (path == nullptr) {
230         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
231         return;
232     }
233     path->AddRect(CastToRect(*cRect), start, static_cast<PathDirection>(dir));
234 }
235 
OH_Drawing_PathAddRoundRect(OH_Drawing_Path * cPath,const OH_Drawing_RoundRect * roundRect,OH_Drawing_PathDirection dir)236 void OH_Drawing_PathAddRoundRect(OH_Drawing_Path* cPath,
237     const OH_Drawing_RoundRect* roundRect, OH_Drawing_PathDirection dir)
238 {
239     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
240         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
241         return;
242     }
243     if (roundRect == nullptr) {
244         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
245         return;
246     }
247     Path* path = CastToPath(cPath);
248     if (path == nullptr) {
249         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
250         return;
251     }
252     path->AddRoundRect(CastToRoundRect(*roundRect), static_cast<PathDirection>(dir));
253 }
254 
OH_Drawing_PathAddOvalWithInitialPoint(OH_Drawing_Path * cPath,const OH_Drawing_Rect * oval,uint32_t start,OH_Drawing_PathDirection dir)255 void OH_Drawing_PathAddOvalWithInitialPoint(OH_Drawing_Path* cPath,
256     const OH_Drawing_Rect* oval, uint32_t start, OH_Drawing_PathDirection dir)
257 {
258     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
259         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
260         return;
261     }
262     if (oval == nullptr) {
263         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
264         return;
265     }
266     Path* path = CastToPath(cPath);
267     if (path == nullptr) {
268         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
269         return;
270     }
271     path->AddOval(CastToRect(*oval), start, static_cast<PathDirection>(dir));
272 }
273 
OH_Drawing_PathAddArc(OH_Drawing_Path * cPath,const OH_Drawing_Rect * arc,float startAngle,float sweepAngle)274 void OH_Drawing_PathAddArc(OH_Drawing_Path* cPath,
275     const OH_Drawing_Rect* arc, float startAngle, float sweepAngle)
276 {
277     if (arc == nullptr) {
278         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
279         return;
280     }
281     Path* path = CastToPath(cPath);
282     if (path == nullptr) {
283         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
284         return;
285     }
286     path->AddArc(CastToRect(*arc), startAngle, sweepAngle);
287 }
288 
OH_Drawing_PathAddPath(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,const OH_Drawing_Matrix * matrix)289 void OH_Drawing_PathAddPath(OH_Drawing_Path* cPath,
290     const OH_Drawing_Path* src, const OH_Drawing_Matrix* matrix)
291 {
292     if (src == nullptr) {
293         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
294         return;
295     }
296     Path* path = CastToPath(cPath);
297     if (path == nullptr) {
298         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
299         return;
300     }
301     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
302     if (matrix == nullptr) {
303         path->AddPath(*srcPath);
304         return;
305     }
306     path->AddPath(*srcPath, *CastToMatrix(matrix));
307 }
308 
OH_Drawing_PathAddPathWithMatrixAndMode(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,const OH_Drawing_Matrix * cMatrix,OH_Drawing_PathAddMode mode)309 void OH_Drawing_PathAddPathWithMatrixAndMode(OH_Drawing_Path* cPath,
310     const OH_Drawing_Path* src, const OH_Drawing_Matrix* cMatrix, OH_Drawing_PathAddMode mode)
311 {
312     if (mode < PATH_ADD_MODE_APPEND || mode > PATH_ADD_MODE_EXTEND) {
313         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
314         return;
315     }
316     Path* path = CastToPath(cPath);
317     if (path == nullptr) {
318         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
319         return;
320     }
321     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
322     if (srcPath == nullptr) {
323         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
324         return;
325     }
326     const Matrix* matrix = CastToMatrix(cMatrix);
327     if (matrix == nullptr) {
328         path->AddPath(*srcPath, static_cast<PathAddMode>(mode));
329         return;
330     }
331     path->AddPath(*srcPath, *matrix, static_cast<PathAddMode>(mode));
332 }
333 
OH_Drawing_PathAddPathWithMode(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,OH_Drawing_PathAddMode mode)334 void OH_Drawing_PathAddPathWithMode(OH_Drawing_Path* cPath, const OH_Drawing_Path* src, OH_Drawing_PathAddMode mode)
335 {
336     if (mode < PATH_ADD_MODE_APPEND || mode > PATH_ADD_MODE_EXTEND) {
337         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
338         return;
339     }
340     Path* path = CastToPath(cPath);
341     if (path == nullptr) {
342         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
343         return;
344     }
345     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
346     if (srcPath == nullptr) {
347         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
348         return;
349     }
350     path->AddPath(*srcPath, static_cast<PathAddMode>(mode));
351 }
352 
OH_Drawing_PathAddPathWithOffsetAndMode(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,float dx,float dy,OH_Drawing_PathAddMode mode)353 void OH_Drawing_PathAddPathWithOffsetAndMode(OH_Drawing_Path* cPath,
354     const OH_Drawing_Path* src, float dx, float dy, OH_Drawing_PathAddMode mode)
355 {
356     if (mode < PATH_ADD_MODE_APPEND || mode > PATH_ADD_MODE_EXTEND) {
357         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
358         return;
359     }
360     Path* path = CastToPath(cPath);
361     if (path == nullptr) {
362         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
363         return;
364     }
365     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
366     if (srcPath == nullptr) {
367         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
368         return;
369     }
370     path->AddPath(*srcPath, dx, dy, static_cast<PathAddMode>(mode));
371 }
372 
OH_Drawing_PathAddOval(OH_Drawing_Path * cPath,const OH_Drawing_Rect * oval,OH_Drawing_PathDirection dir)373 void OH_Drawing_PathAddOval(OH_Drawing_Path* cPath, const OH_Drawing_Rect* oval, OH_Drawing_PathDirection dir)
374 {
375     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
376         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
377         return;
378     }
379     if (oval == nullptr) {
380         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
381         return;
382     }
383     Path* path = CastToPath(cPath);
384     if (path == nullptr) {
385         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
386         return;
387     }
388     path->AddOval(CastToRect(*oval), static_cast<PathDirection>(dir));
389 }
390 
OH_Drawing_PathAddPolygon(OH_Drawing_Path * cPath,const OH_Drawing_Point2D * cPoints,uint32_t count,bool isClosed)391 void OH_Drawing_PathAddPolygon(OH_Drawing_Path* cPath, const OH_Drawing_Point2D* cPoints, uint32_t count, bool isClosed)
392 {
393     if (cPoints == nullptr || count == 0) {
394         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
395         return;
396     }
397     Path* path = CastToPath(cPath);
398     if (path == nullptr) {
399         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
400         return;
401     }
402     const Point* points = CastToPoint(cPoints);
403     std::vector<Point> pointsTemp(count);
404     for (uint32_t idx = 0; idx < count; idx++) {
405         pointsTemp[idx] = points[idx];
406     }
407     path->AddPoly(pointsTemp, count, isClosed);
408 }
409 
OH_Drawing_PathAddCircle(OH_Drawing_Path * cPath,float x,float y,float radius,OH_Drawing_PathDirection dir)410 void OH_Drawing_PathAddCircle(OH_Drawing_Path* cPath, float x, float y, float radius, OH_Drawing_PathDirection dir)
411 {
412     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
413         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
414         return;
415     }
416     if (radius <= 0) {
417         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
418         return;
419     }
420     Path* path = CastToPath(cPath);
421     if (path == nullptr) {
422         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
423         return;
424     }
425     path->AddCircle(x, y, radius, static_cast<PathDirection>(dir));
426 }
427 
OH_Drawing_PathBuildFromSvgString(OH_Drawing_Path * cPath,const char * str)428 bool OH_Drawing_PathBuildFromSvgString(OH_Drawing_Path* cPath, const char* str)
429 {
430     if (str == nullptr) {
431         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
432         return false;
433     }
434     Path* path = CastToPath(cPath);
435     if (path == nullptr) {
436         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
437         return false;
438     }
439     return path->BuildFromSVGString(str);
440 }
441 
OH_Drawing_PathContains(OH_Drawing_Path * cPath,float x,float y)442 bool OH_Drawing_PathContains(OH_Drawing_Path* cPath, float x, float y)
443 {
444     Path* path = CastToPath(cPath);
445     if (path == nullptr) {
446         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
447         return false;
448     }
449     return path->Contains(x, y);
450 }
451 
OH_Drawing_PathTransform(OH_Drawing_Path * cPath,const OH_Drawing_Matrix * matrix)452 void OH_Drawing_PathTransform(OH_Drawing_Path* cPath, const OH_Drawing_Matrix* matrix)
453 {
454     if (matrix == nullptr) {
455         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
456         return;
457     }
458     Path* path = CastToPath(cPath);
459     if (path == nullptr) {
460         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
461         return;
462     }
463     path->Transform(*CastToMatrix(matrix));
464 }
465 
OH_Drawing_PathTransformWithPerspectiveClip(OH_Drawing_Path * cPath,const OH_Drawing_Matrix * cMatrix,OH_Drawing_Path * dstPath,bool applyPerspectiveClip)466 void OH_Drawing_PathTransformWithPerspectiveClip(OH_Drawing_Path* cPath, const OH_Drawing_Matrix* cMatrix,
467     OH_Drawing_Path* dstPath, bool applyPerspectiveClip)
468 {
469     Path* path = CastToPath(cPath);
470     if (path == nullptr) {
471         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
472         return;
473     }
474     const Matrix* matrix = CastToMatrix(cMatrix);
475     if (matrix == nullptr) {
476         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
477         return;
478     }
479     path->TransformWithPerspectiveClip(*matrix, CastToPath(dstPath), applyPerspectiveClip);
480 }
481 
OH_Drawing_PathSetFillType(OH_Drawing_Path * cPath,OH_Drawing_PathFillType fillstyle)482 void OH_Drawing_PathSetFillType(OH_Drawing_Path* cPath, OH_Drawing_PathFillType fillstyle)
483 {
484     if (fillstyle < PATH_FILL_TYPE_WINDING || fillstyle > PATH_FILL_TYPE_INVERSE_EVEN_ODD) {
485         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
486         return;
487     }
488     Path* path = CastToPath(cPath);
489     if (path == nullptr) {
490         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
491         return;
492     }
493     path->SetFillStyle(static_cast<PathFillType>(fillstyle));
494 }
495 
OH_Drawing_PathClose(OH_Drawing_Path * cPath)496 void OH_Drawing_PathClose(OH_Drawing_Path* cPath)
497 {
498     Path* path = CastToPath(cPath);
499     if (path == nullptr) {
500         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
501         return;
502     }
503     path->Close();
504 }
505 
OH_Drawing_PathOffset(OH_Drawing_Path * cPath,OH_Drawing_Path * dst,float dx,float dy)506 void OH_Drawing_PathOffset(OH_Drawing_Path* cPath, OH_Drawing_Path* dst, float dx, float dy)
507 {
508     Path* path = CastToPath(cPath);
509     if (path == nullptr) {
510         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
511         return;
512     }
513     Path* dstPath = CastToPath(const_cast<OH_Drawing_Path*>(dst));
514     path->Offset(dstPath, dx, dy);
515 }
516 
OH_Drawing_PathReset(OH_Drawing_Path * cPath)517 void OH_Drawing_PathReset(OH_Drawing_Path* cPath)
518 {
519     Path* path = CastToPath(cPath);
520     if (path == nullptr) {
521         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
522         return;
523     }
524     path->Reset();
525 }
526 
OH_Drawing_PathGetLength(OH_Drawing_Path * cPath,bool forceClosed)527 float OH_Drawing_PathGetLength(OH_Drawing_Path* cPath, bool forceClosed)
528 {
529     Path* path = CastToPath(cPath);
530     if (path == nullptr) {
531         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
532         return -1;
533     }
534     return path->GetLength(forceClosed);
535 }
536 
OH_Drawing_PathIsClosed(OH_Drawing_Path * cPath,bool forceClosed)537 bool OH_Drawing_PathIsClosed(OH_Drawing_Path* cPath, bool forceClosed)
538 {
539     Path* path = CastToPath(cPath);
540     if (path == nullptr) {
541         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
542         return false;
543     }
544     return path->IsClosed(forceClosed);
545 }
546 
OH_Drawing_PathGetPositionTangent(OH_Drawing_Path * cPath,bool forceClosed,float distance,OH_Drawing_Point2D * cPosition,OH_Drawing_Point2D * cTangent)547 bool OH_Drawing_PathGetPositionTangent(OH_Drawing_Path* cPath, bool forceClosed,
548     float distance, OH_Drawing_Point2D* cPosition, OH_Drawing_Point2D* cTangent)
549 {
550     Path* path = CastToPath(cPath);
551     Point* position = CastToPoint(cPosition);
552     Point* tangent = CastToPoint(cTangent);
553     if (path == nullptr || position == nullptr || tangent == nullptr) {
554         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
555         return false;
556     }
557     return path->GetPositionAndTangent(distance, *position, *tangent, forceClosed);
558 }
559 
OH_Drawing_PathOp(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,OH_Drawing_PathOpMode op)560 bool OH_Drawing_PathOp(OH_Drawing_Path* cPath, const OH_Drawing_Path* src, OH_Drawing_PathOpMode op)
561 {
562     if (op < PATH_OP_MODE_DIFFERENCE || op > PATH_OP_MODE_REVERSE_DIFFERENCE) {
563         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
564         return false;
565     }
566     Path* path = CastToPath(cPath);
567     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
568     if (path == nullptr || srcPath == nullptr) {
569         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
570         return false;
571     }
572     return path->Op(*path, *srcPath, static_cast<PathOp>(op));
573 }
574 
OH_Drawing_PathGetMatrix(OH_Drawing_Path * cPath,bool forceClosed,float distance,OH_Drawing_Matrix * cMatrix,OH_Drawing_PathMeasureMatrixFlags flag)575 bool OH_Drawing_PathGetMatrix(OH_Drawing_Path* cPath, bool forceClosed,
576     float distance, OH_Drawing_Matrix* cMatrix, OH_Drawing_PathMeasureMatrixFlags flag)
577 {
578     if (flag < GET_POSITION_MATRIX || flag > GET_POSITION_AND_TANGENT_MATRIX) {
579         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
580         return false;
581     }
582     Path* path = CastToPath(cPath);
583     Matrix* matrix = CastToMatrix(cMatrix);
584     if (path == nullptr || matrix == nullptr) {
585         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
586         return false;
587     }
588     return path->GetMatrix(forceClosed, distance, matrix, static_cast<PathMeasureMatrixFlags>(flag));
589 }
590 
OH_Drawing_PathGetBounds(OH_Drawing_Path * cPath,OH_Drawing_Rect * cRect)591 void OH_Drawing_PathGetBounds(OH_Drawing_Path* cPath, OH_Drawing_Rect* cRect)
592 {
593     Path* path = CastToPath(cPath);
594     Rect* rect = CastToRect(cRect);
595     if (path == nullptr || rect == nullptr) {
596         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
597         return;
598     }
599     *rect = path->GetBounds();
600 }