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 }