• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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_PathSetPath(OH_Drawing_Path * cPath,OH_Drawing_Path * cOther)89 OH_Drawing_ErrorCode OH_Drawing_PathSetPath(OH_Drawing_Path* cPath, OH_Drawing_Path* cOther)
90 {
91     if (cPath == nullptr || cOther == nullptr) {
92         return OH_DRAWING_ERROR_INVALID_PARAMETER;
93     }
94     Path* path = CastToPath(cPath);
95     Path* other = CastToPath(cOther);
96     path->SetPath(*other);
97     return OH_DRAWING_SUCCESS;
98 }
99 
OH_Drawing_PathIsEmpty(OH_Drawing_Path * cPath,bool * isEmpty)100 OH_Drawing_ErrorCode OH_Drawing_PathIsEmpty(OH_Drawing_Path* cPath, bool* isEmpty)
101 {
102     if (cPath == nullptr || isEmpty == nullptr) {
103         return OH_DRAWING_ERROR_INVALID_PARAMETER;
104     }
105     *isEmpty = CastToPath(cPath)->IsEmpty();
106     return OH_DRAWING_SUCCESS;
107 }
108 
OH_Drawing_PathIsRect(OH_Drawing_Path * cPath,OH_Drawing_Rect * cRect,bool * isRect)109 OH_Drawing_ErrorCode OH_Drawing_PathIsRect(OH_Drawing_Path* cPath, OH_Drawing_Rect* cRect, bool* isRect)
110 {
111     if (cPath == nullptr || isRect == nullptr) {
112         return OH_DRAWING_ERROR_INVALID_PARAMETER;
113     }
114     Path* path = CastToPath(cPath);
115     Rect* rect = CastToRect(cRect);
116     *isRect = path->IsRect(rect);
117     return OH_DRAWING_SUCCESS;
118 }
119 
OH_Drawing_PathMoveTo(OH_Drawing_Path * cPath,float x,float y)120 void OH_Drawing_PathMoveTo(OH_Drawing_Path* cPath, float x, float y)
121 {
122     Path* path = CastToPath(cPath);
123     if (path == nullptr) {
124         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
125         return;
126     }
127     path->MoveTo(x, y);
128 }
129 
OH_Drawing_PathRMoveTo(OH_Drawing_Path * cPath,float x,float y)130 void OH_Drawing_PathRMoveTo(OH_Drawing_Path* cPath, float x, float y)
131 {
132     Path* path = CastToPath(cPath);
133     if (path == nullptr) {
134         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
135         return;
136     }
137     path->RMoveTo(x, y);
138 }
139 
OH_Drawing_PathLineTo(OH_Drawing_Path * cPath,float x,float y)140 void OH_Drawing_PathLineTo(OH_Drawing_Path* cPath, float x, float y)
141 {
142     Path* path = CastToPath(cPath);
143     if (path == nullptr) {
144         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
145         return;
146     }
147     path->LineTo(x, y);
148 }
149 
OH_Drawing_PathRLineTo(OH_Drawing_Path * cPath,float x,float y)150 void OH_Drawing_PathRLineTo(OH_Drawing_Path* cPath, float x, float y)
151 {
152     Path* path = CastToPath(cPath);
153     if (path == nullptr) {
154         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
155         return;
156     }
157     path->RLineTo(x, y);
158 }
159 
OH_Drawing_PathArcTo(OH_Drawing_Path * cPath,float x1,float y1,float x2,float y2,float startDeg,float sweepDeg)160 void OH_Drawing_PathArcTo(
161     OH_Drawing_Path* cPath, float x1, float y1, float x2, float y2, float startDeg, float sweepDeg)
162 {
163     Path* path = CastToPath(cPath);
164     if (path == nullptr) {
165         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
166         return;
167     }
168     path->ArcTo(x1, y1, x2, y2, startDeg, sweepDeg);
169 }
170 
OH_Drawing_PathQuadTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY)171 void OH_Drawing_PathQuadTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, float endX, float endY)
172 {
173     Path* path = CastToPath(cPath);
174     if (path == nullptr) {
175         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
176         return;
177     }
178     path->QuadTo(ctrlX, ctrlY, endX, endY);
179 }
180 
OH_Drawing_PathRQuadTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY)181 void OH_Drawing_PathRQuadTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, 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->RQuadTo(ctrlX, ctrlY, endX, endY);
189 }
190 
OH_Drawing_PathConicTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY,float weight)191 void OH_Drawing_PathConicTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, float endX, float endY, float weight)
192 {
193     Path* path = CastToPath(cPath);
194     if (path == nullptr) {
195         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
196         return;
197     }
198     path->ConicTo(ctrlX, ctrlY, endX, endY, weight);
199 }
200 
OH_Drawing_PathRConicTo(OH_Drawing_Path * cPath,float ctrlX,float ctrlY,float endX,float endY,float weight)201 void OH_Drawing_PathRConicTo(OH_Drawing_Path* cPath, float ctrlX, float ctrlY, float endX, float endY, float weight)
202 {
203     Path* path = CastToPath(cPath);
204     if (path == nullptr) {
205         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
206         return;
207     }
208     path->RConicTo(ctrlX, ctrlY, endX, endY, weight);
209 }
210 
OH_Drawing_PathCubicTo(OH_Drawing_Path * cPath,float ctrlX1,float ctrlY1,float ctrlX2,float ctrlY2,float endX,float endY)211 void OH_Drawing_PathCubicTo(
212     OH_Drawing_Path* cPath, float ctrlX1, float ctrlY1, float ctrlX2, float ctrlY2, float endX, float endY)
213 {
214     Path* path = CastToPath(cPath);
215     if (path == nullptr) {
216         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
217         return;
218     }
219     path->CubicTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);
220 }
221 
OH_Drawing_PathRCubicTo(OH_Drawing_Path * cPath,float ctrlX1,float ctrlY1,float ctrlX2,float ctrlY2,float endX,float endY)222 void OH_Drawing_PathRCubicTo(
223     OH_Drawing_Path* cPath, float ctrlX1, float ctrlY1, float ctrlX2, float ctrlY2, float endX, float endY)
224 {
225     Path* path = CastToPath(cPath);
226     if (path == nullptr) {
227         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
228         return;
229     }
230     path->RCubicTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);
231 }
232 
OH_Drawing_PathAddRect(OH_Drawing_Path * cPath,float left,float top,float right,float bottom,OH_Drawing_PathDirection dir)233 void OH_Drawing_PathAddRect(OH_Drawing_Path* cPath, float left,
234     float top, float right, float bottom, OH_Drawing_PathDirection dir)
235 {
236     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
237         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
238         return;
239     }
240     Path* path = CastToPath(cPath);
241     if (path == nullptr) {
242         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
243         return;
244     }
245     path->AddRect(left, top, right, bottom, static_cast<PathDirection>(dir));
246 }
247 
OH_Drawing_PathAddRectWithInitialCorner(OH_Drawing_Path * cPath,const OH_Drawing_Rect * cRect,OH_Drawing_PathDirection dir,uint32_t start)248 void OH_Drawing_PathAddRectWithInitialCorner(OH_Drawing_Path* cPath, const OH_Drawing_Rect* cRect,
249     OH_Drawing_PathDirection dir, uint32_t start)
250 {
251     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
252         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
253         return;
254     }
255     if (cRect == nullptr) {
256         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
257         return;
258     }
259     Path* path = CastToPath(cPath);
260     if (path == nullptr) {
261         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
262         return;
263     }
264     path->AddRect(CastToRect(*cRect), start, static_cast<PathDirection>(dir));
265 }
266 
OH_Drawing_PathAddRoundRect(OH_Drawing_Path * cPath,const OH_Drawing_RoundRect * roundRect,OH_Drawing_PathDirection dir)267 void OH_Drawing_PathAddRoundRect(OH_Drawing_Path* cPath,
268     const OH_Drawing_RoundRect* roundRect, OH_Drawing_PathDirection dir)
269 {
270     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
271         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
272         return;
273     }
274     if (roundRect == nullptr) {
275         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
276         return;
277     }
278     Path* path = CastToPath(cPath);
279     if (path == nullptr) {
280         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
281         return;
282     }
283     path->AddRoundRect(CastToRoundRect(*roundRect), static_cast<PathDirection>(dir));
284 }
285 
OH_Drawing_PathAddOvalWithInitialPoint(OH_Drawing_Path * cPath,const OH_Drawing_Rect * oval,uint32_t start,OH_Drawing_PathDirection dir)286 void OH_Drawing_PathAddOvalWithInitialPoint(OH_Drawing_Path* cPath,
287     const OH_Drawing_Rect* oval, uint32_t start, OH_Drawing_PathDirection dir)
288 {
289     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
290         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
291         return;
292     }
293     if (oval == nullptr) {
294         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
295         return;
296     }
297     Path* path = CastToPath(cPath);
298     if (path == nullptr) {
299         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
300         return;
301     }
302     path->AddOval(CastToRect(*oval), start, static_cast<PathDirection>(dir));
303 }
304 
OH_Drawing_PathAddArc(OH_Drawing_Path * cPath,const OH_Drawing_Rect * arc,float startAngle,float sweepAngle)305 void OH_Drawing_PathAddArc(OH_Drawing_Path* cPath,
306     const OH_Drawing_Rect* arc, float startAngle, float sweepAngle)
307 {
308     if (arc == nullptr) {
309         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
310         return;
311     }
312     Path* path = CastToPath(cPath);
313     if (path == nullptr) {
314         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
315         return;
316     }
317     path->AddArc(CastToRect(*arc), startAngle, sweepAngle);
318 }
319 
OH_Drawing_PathAddPath(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,const OH_Drawing_Matrix * matrix)320 void OH_Drawing_PathAddPath(OH_Drawing_Path* cPath,
321     const OH_Drawing_Path* src, const OH_Drawing_Matrix* matrix)
322 {
323     if (src == nullptr) {
324         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
325         return;
326     }
327     Path* path = CastToPath(cPath);
328     if (path == nullptr) {
329         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
330         return;
331     }
332     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
333     if (matrix == nullptr) {
334         path->AddPath(*srcPath);
335         return;
336     }
337     path->AddPath(*srcPath, *CastToMatrix(matrix));
338 }
339 
OH_Drawing_PathAddPathWithMatrixAndMode(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,const OH_Drawing_Matrix * cMatrix,OH_Drawing_PathAddMode mode)340 void OH_Drawing_PathAddPathWithMatrixAndMode(OH_Drawing_Path* cPath,
341     const OH_Drawing_Path* src, const OH_Drawing_Matrix* cMatrix, OH_Drawing_PathAddMode mode)
342 {
343     if (mode < PATH_ADD_MODE_APPEND || mode > PATH_ADD_MODE_EXTEND) {
344         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
345         return;
346     }
347     Path* path = CastToPath(cPath);
348     if (path == nullptr) {
349         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
350         return;
351     }
352     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
353     if (srcPath == nullptr) {
354         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
355         return;
356     }
357     const Matrix* matrix = CastToMatrix(cMatrix);
358     if (matrix == nullptr) {
359         path->AddPath(*srcPath, static_cast<PathAddMode>(mode));
360         return;
361     }
362     path->AddPath(*srcPath, *matrix, static_cast<PathAddMode>(mode));
363 }
364 
OH_Drawing_PathAddPathWithMode(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,OH_Drawing_PathAddMode mode)365 void OH_Drawing_PathAddPathWithMode(OH_Drawing_Path* cPath, const OH_Drawing_Path* src, OH_Drawing_PathAddMode mode)
366 {
367     if (mode < PATH_ADD_MODE_APPEND || mode > PATH_ADD_MODE_EXTEND) {
368         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
369         return;
370     }
371     Path* path = CastToPath(cPath);
372     if (path == nullptr) {
373         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
374         return;
375     }
376     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
377     if (srcPath == nullptr) {
378         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
379         return;
380     }
381     path->AddPath(*srcPath, static_cast<PathAddMode>(mode));
382 }
383 
OH_Drawing_PathAddPathWithOffsetAndMode(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,float dx,float dy,OH_Drawing_PathAddMode mode)384 void OH_Drawing_PathAddPathWithOffsetAndMode(OH_Drawing_Path* cPath,
385     const OH_Drawing_Path* src, float dx, float dy, OH_Drawing_PathAddMode mode)
386 {
387     if (mode < PATH_ADD_MODE_APPEND || mode > PATH_ADD_MODE_EXTEND) {
388         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
389         return;
390     }
391     Path* path = CastToPath(cPath);
392     if (path == nullptr) {
393         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
394         return;
395     }
396     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
397     if (srcPath == nullptr) {
398         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
399         return;
400     }
401     path->AddPath(*srcPath, dx, dy, static_cast<PathAddMode>(mode));
402 }
403 
OH_Drawing_PathAddOval(OH_Drawing_Path * cPath,const OH_Drawing_Rect * oval,OH_Drawing_PathDirection dir)404 void OH_Drawing_PathAddOval(OH_Drawing_Path* cPath, const OH_Drawing_Rect* oval, OH_Drawing_PathDirection dir)
405 {
406     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
407         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
408         return;
409     }
410     if (oval == nullptr) {
411         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
412         return;
413     }
414     Path* path = CastToPath(cPath);
415     if (path == nullptr) {
416         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
417         return;
418     }
419     path->AddOval(CastToRect(*oval), static_cast<PathDirection>(dir));
420 }
421 
OH_Drawing_PathAddPolygon(OH_Drawing_Path * cPath,const OH_Drawing_Point2D * cPoints,uint32_t count,bool isClosed)422 void OH_Drawing_PathAddPolygon(OH_Drawing_Path* cPath, const OH_Drawing_Point2D* cPoints, uint32_t count, bool isClosed)
423 {
424     if (cPoints == nullptr || count == 0) {
425         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
426         return;
427     }
428     Path* path = CastToPath(cPath);
429     if (path == nullptr) {
430         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
431         return;
432     }
433     const Point* points = CastToPoint(cPoints);
434     std::vector<Point> pointsTemp(count);
435     for (uint32_t idx = 0; idx < count; idx++) {
436         pointsTemp[idx] = points[idx];
437     }
438     path->AddPoly(pointsTemp, count, isClosed);
439 }
440 
OH_Drawing_PathAddCircle(OH_Drawing_Path * cPath,float x,float y,float radius,OH_Drawing_PathDirection dir)441 void OH_Drawing_PathAddCircle(OH_Drawing_Path* cPath, float x, float y, float radius, OH_Drawing_PathDirection dir)
442 {
443     if (dir < PATH_DIRECTION_CW || dir > PATH_DIRECTION_CCW) {
444         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
445         return;
446     }
447     if (radius <= 0) {
448         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
449         return;
450     }
451     Path* path = CastToPath(cPath);
452     if (path == nullptr) {
453         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
454         return;
455     }
456     path->AddCircle(x, y, radius, static_cast<PathDirection>(dir));
457 }
458 
OH_Drawing_PathBuildFromSvgString(OH_Drawing_Path * cPath,const char * str)459 bool OH_Drawing_PathBuildFromSvgString(OH_Drawing_Path* cPath, const char* str)
460 {
461     if (str == nullptr) {
462         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
463         return false;
464     }
465     Path* path = CastToPath(cPath);
466     if (path == nullptr) {
467         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
468         return false;
469     }
470     return path->BuildFromSVGString(str);
471 }
472 
OH_Drawing_PathContains(OH_Drawing_Path * cPath,float x,float y)473 bool OH_Drawing_PathContains(OH_Drawing_Path* cPath, float x, float y)
474 {
475     Path* path = CastToPath(cPath);
476     if (path == nullptr) {
477         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
478         return false;
479     }
480     return path->Contains(x, y);
481 }
482 
OH_Drawing_PathTransform(OH_Drawing_Path * cPath,const OH_Drawing_Matrix * matrix)483 void OH_Drawing_PathTransform(OH_Drawing_Path* cPath, const OH_Drawing_Matrix* matrix)
484 {
485     if (matrix == nullptr) {
486         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
487         return;
488     }
489     Path* path = CastToPath(cPath);
490     if (path == nullptr) {
491         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
492         return;
493     }
494     path->Transform(*CastToMatrix(matrix));
495 }
496 
OH_Drawing_PathTransformWithPerspectiveClip(OH_Drawing_Path * cPath,const OH_Drawing_Matrix * cMatrix,OH_Drawing_Path * dstPath,bool applyPerspectiveClip)497 void OH_Drawing_PathTransformWithPerspectiveClip(OH_Drawing_Path* cPath, const OH_Drawing_Matrix* cMatrix,
498     OH_Drawing_Path* dstPath, bool applyPerspectiveClip)
499 {
500     Path* path = CastToPath(cPath);
501     if (path == nullptr) {
502         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
503         return;
504     }
505     const Matrix* matrix = CastToMatrix(cMatrix);
506     if (matrix == nullptr) {
507         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
508         return;
509     }
510     path->TransformWithPerspectiveClip(*matrix, CastToPath(dstPath), applyPerspectiveClip);
511 }
512 
OH_Drawing_PathSetFillType(OH_Drawing_Path * cPath,OH_Drawing_PathFillType fillstyle)513 void OH_Drawing_PathSetFillType(OH_Drawing_Path* cPath, OH_Drawing_PathFillType fillstyle)
514 {
515     if (fillstyle < PATH_FILL_TYPE_WINDING || fillstyle > PATH_FILL_TYPE_INVERSE_EVEN_ODD) {
516         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
517         return;
518     }
519     Path* path = CastToPath(cPath);
520     if (path == nullptr) {
521         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
522         return;
523     }
524     path->SetFillStyle(static_cast<PathFillType>(fillstyle));
525 }
526 
OH_Drawing_PathGetFillType(OH_Drawing_Path * cPath,OH_Drawing_PathFillType * pathFillType)527 OH_Drawing_ErrorCode OH_Drawing_PathGetFillType(OH_Drawing_Path* cPath, OH_Drawing_PathFillType* pathFillType)
528 {
529     if (cPath == nullptr || pathFillType == nullptr) {
530         return OH_DRAWING_ERROR_INVALID_PARAMETER;
531     }
532     Path* path = CastToPath(cPath);
533     PathFillType* type = reinterpret_cast<PathFillType*>(pathFillType);
534     *type = path->GetFillStyle();
535     return OH_DRAWING_SUCCESS;
536 }
537 
OH_Drawing_PathClose(OH_Drawing_Path * cPath)538 void OH_Drawing_PathClose(OH_Drawing_Path* cPath)
539 {
540     Path* path = CastToPath(cPath);
541     if (path == nullptr) {
542         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
543         return;
544     }
545     path->Close();
546 }
547 
OH_Drawing_PathOffset(OH_Drawing_Path * cPath,OH_Drawing_Path * dst,float dx,float dy)548 void OH_Drawing_PathOffset(OH_Drawing_Path* cPath, OH_Drawing_Path* dst, float dx, float dy)
549 {
550     Path* path = CastToPath(cPath);
551     if (path == nullptr) {
552         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
553         return;
554     }
555     Path* dstPath = CastToPath(const_cast<OH_Drawing_Path*>(dst));
556     path->Offset(dstPath, dx, dy);
557 }
558 
OH_Drawing_PathReset(OH_Drawing_Path * cPath)559 void OH_Drawing_PathReset(OH_Drawing_Path* cPath)
560 {
561     Path* path = CastToPath(cPath);
562     if (path == nullptr) {
563         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
564         return;
565     }
566     path->Reset();
567 }
568 
OH_Drawing_PathGetLength(OH_Drawing_Path * cPath,bool forceClosed)569 float OH_Drawing_PathGetLength(OH_Drawing_Path* cPath, bool forceClosed)
570 {
571     Path* path = CastToPath(cPath);
572     if (path == nullptr) {
573         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
574         return -1;
575     }
576     return path->GetLength(forceClosed);
577 }
578 
OH_Drawing_PathIsClosed(OH_Drawing_Path * cPath,bool forceClosed)579 bool OH_Drawing_PathIsClosed(OH_Drawing_Path* cPath, bool forceClosed)
580 {
581     Path* path = CastToPath(cPath);
582     if (path == nullptr) {
583         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
584         return false;
585     }
586     return path->IsClosed(forceClosed);
587 }
588 
OH_Drawing_PathGetPositionTangent(OH_Drawing_Path * cPath,bool forceClosed,float distance,OH_Drawing_Point2D * cPosition,OH_Drawing_Point2D * cTangent)589 bool OH_Drawing_PathGetPositionTangent(OH_Drawing_Path* cPath, bool forceClosed,
590     float distance, OH_Drawing_Point2D* cPosition, OH_Drawing_Point2D* cTangent)
591 {
592     Path* path = CastToPath(cPath);
593     Point* position = CastToPoint(cPosition);
594     Point* tangent = CastToPoint(cTangent);
595     if (path == nullptr || position == nullptr || tangent == nullptr) {
596         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
597         return false;
598     }
599     return path->GetPositionAndTangent(distance, *position, *tangent, forceClosed);
600 }
601 
OH_Drawing_PathGetSegment(OH_Drawing_Path * cPath,bool forceClosed,float start,float stop,bool startWithMoveTo,OH_Drawing_Path * cDst,bool * result)602 OH_Drawing_ErrorCode OH_Drawing_PathGetSegment(OH_Drawing_Path* cPath, bool forceClosed,
603     float start, float stop, bool startWithMoveTo, OH_Drawing_Path* cDst, bool* result)
604 {
605     Path* path = CastToPath(cPath);
606     Path* dst = CastToPath(cDst);
607     if (path == nullptr || dst == nullptr || result == nullptr) {
608         return OH_DRAWING_ERROR_INVALID_PARAMETER;
609     }
610     float length = path->GetLength(forceClosed);
611     if (start < 0) {
612         start = 0;
613     }
614     if (stop > length) {
615         stop = length;
616     }
617     if (start >= stop) {
618         *result = false;
619         return OH_DRAWING_SUCCESS;
620     }
621     *result = path->GetSegment(start, stop, dst, startWithMoveTo, forceClosed);
622     return OH_DRAWING_SUCCESS;
623 }
624 
OH_Drawing_PathOp(OH_Drawing_Path * cPath,const OH_Drawing_Path * src,OH_Drawing_PathOpMode op)625 bool OH_Drawing_PathOp(OH_Drawing_Path* cPath, const OH_Drawing_Path* src, OH_Drawing_PathOpMode op)
626 {
627     if (op < PATH_OP_MODE_DIFFERENCE || op > PATH_OP_MODE_REVERSE_DIFFERENCE) {
628         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
629         return false;
630     }
631     Path* path = CastToPath(cPath);
632     Path* srcPath = CastToPath(const_cast<OH_Drawing_Path*>(src));
633     if (path == nullptr || srcPath == nullptr) {
634         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
635         return false;
636     }
637     return path->Op(*path, *srcPath, static_cast<PathOp>(op));
638 }
639 
OH_Drawing_PathGetMatrix(OH_Drawing_Path * cPath,bool forceClosed,float distance,OH_Drawing_Matrix * cMatrix,OH_Drawing_PathMeasureMatrixFlags flag)640 bool OH_Drawing_PathGetMatrix(OH_Drawing_Path* cPath, bool forceClosed,
641     float distance, OH_Drawing_Matrix* cMatrix, OH_Drawing_PathMeasureMatrixFlags flag)
642 {
643     if (flag < GET_POSITION_MATRIX || flag > GET_POSITION_AND_TANGENT_MATRIX) {
644         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
645         return false;
646     }
647     Path* path = CastToPath(cPath);
648     Matrix* matrix = CastToMatrix(cMatrix);
649     if (path == nullptr || matrix == nullptr) {
650         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
651         return false;
652     }
653     return path->GetMatrix(forceClosed, distance, matrix, static_cast<PathMeasureMatrixFlags>(flag));
654 }
655 
OH_Drawing_PathApproximate(OH_Drawing_Path * cPath,float acceptableError,float * vals,uint32_t * count)656 OH_Drawing_ErrorCode OH_Drawing_PathApproximate(OH_Drawing_Path* cPath, float acceptableError,
657     float* vals, uint32_t* count)
658 {
659     Path* path = CastToPath(cPath);
660     if (path == nullptr || count == nullptr) {
661         return OH_DRAWING_ERROR_INVALID_PARAMETER;
662     }
663     if (acceptableError < 0.0f) {
664         return OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
665     }
666     std::vector<scalar> approximation;
667     path->Approximate(acceptableError, approximation);
668     uint32_t requiredSize = static_cast<uint32_t>(approximation.size());
669     *count = requiredSize;
670     if (vals == nullptr) {
671         return OH_DRAWING_SUCCESS;
672     }
673     for (uint32_t i = 0; i < requiredSize; i++) {
674         vals[i] = static_cast<float>(approximation[i]);
675     }
676     return OH_DRAWING_SUCCESS;
677 }
678 
OH_Drawing_PathInterpolate(OH_Drawing_Path * cPath,OH_Drawing_Path * cOther,float weight,bool * success,OH_Drawing_Path * cInterpolatedPath)679 OH_Drawing_ErrorCode OH_Drawing_PathInterpolate(OH_Drawing_Path* cPath, OH_Drawing_Path* cOther, float weight,
680     bool* success, OH_Drawing_Path* cInterpolatedPath)
681 {
682     Path* path = CastToPath(cPath);
683     Path* other = CastToPath(cOther);
684     Path* interpolatedPath = CastToPath(cInterpolatedPath);
685     if (path == nullptr || other == nullptr || interpolatedPath == nullptr || success == nullptr) {
686         return OH_DRAWING_ERROR_INVALID_PARAMETER;
687     }
688     if (weight < 0 || weight > 1) {
689         return OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
690     }
691     *success = path->Interpolate(*other, weight, *interpolatedPath);
692     return OH_DRAWING_SUCCESS;
693 }
694 
OH_Drawing_PathIsInterpolate(OH_Drawing_Path * cPath,OH_Drawing_Path * other,bool * result)695 OH_Drawing_ErrorCode OH_Drawing_PathIsInterpolate(OH_Drawing_Path* cPath, OH_Drawing_Path* other, bool* result)
696 {
697     Path* path = CastToPath(cPath);
698     Path* otherPath = CastToPath(other);
699     if (path == nullptr || otherPath == nullptr || result == nullptr) {
700         return OH_DRAWING_ERROR_INVALID_PARAMETER;
701     }
702     *result = path->IsInterpolate(*otherPath);
703     return OH_DRAWING_SUCCESS;
704 }
705 
OH_Drawing_PathGetBounds(OH_Drawing_Path * cPath,OH_Drawing_Rect * cRect)706 void OH_Drawing_PathGetBounds(OH_Drawing_Path* cPath, OH_Drawing_Rect* cRect)
707 {
708     Path* path = CastToPath(cPath);
709     Rect* rect = CastToRect(cRect);
710     if (path == nullptr || rect == nullptr) {
711         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
712         return;
713     }
714     *rect = path->GetBounds();
715 }