1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #ifndef BLEND2D_BLGEOMETRY_H |
8 | #define BLEND2D_BLGEOMETRY_H |
9 | |
10 | #include "./blapi.h" |
11 | |
12 | BL_DIAGNOSTIC_PUSH(BL_DIAGNOSTIC_NO_SHADOW) |
13 | |
14 | //! \addtogroup blend2d_api_geometry |
15 | //! \{ |
16 | |
17 | // ============================================================================ |
18 | // [Constants] |
19 | // ============================================================================ |
20 | |
21 | //! Direction of a geometry used by geometric primitives and paths. |
22 | BL_DEFINE_ENUM(BLGeometryDirection) { |
23 | //! No direction specified. |
24 | BL_GEOMETRY_DIRECTION_NONE = 0, |
25 | //! Clockwise direction. |
26 | BL_GEOMETRY_DIRECTION_CW = 1, |
27 | //! Counter-clockwise direction. |
28 | BL_GEOMETRY_DIRECTION_CCW = 2 |
29 | }; |
30 | |
31 | //! Geometry type. |
32 | //! |
33 | //! Geometry describes a shape or path that can be either rendered or added to |
34 | //! a BLPath container. Both `BLPath` and `BLContext` provide functionality |
35 | //! to work with all geometry types. Please note that each type provided here |
36 | //! requires to pass a matching struct or class to the function that consumes |
37 | //! a `geometryType` and `geometryData` arguments. |
38 | BL_DEFINE_ENUM(BLGeometryType) { |
39 | //! No geometry provided. |
40 | BL_GEOMETRY_TYPE_NONE = 0, |
41 | //! BLBoxI struct. |
42 | BL_GEOMETRY_TYPE_BOXI = 1, |
43 | //! BLBox struct. |
44 | BL_GEOMETRY_TYPE_BOXD = 2, |
45 | //! BLRectI struct. |
46 | BL_GEOMETRY_TYPE_RECTI = 3, |
47 | //! BLRect struct. |
48 | BL_GEOMETRY_TYPE_RECTD = 4, |
49 | //! BLCircle struct. |
50 | BL_GEOMETRY_TYPE_CIRCLE = 5, |
51 | //! BLEllipse struct. |
52 | BL_GEOMETRY_TYPE_ELLIPSE = 6, |
53 | //! BLRoundRect struct. |
54 | BL_GEOMETRY_TYPE_ROUND_RECT = 7, |
55 | //! BLArc struct. |
56 | BL_GEOMETRY_TYPE_ARC = 8, |
57 | //! BLArc struct representing chord. |
58 | BL_GEOMETRY_TYPE_CHORD = 9, |
59 | //! BLArc struct representing pie. |
60 | BL_GEOMETRY_TYPE_PIE = 10, |
61 | //! BLLine struct. |
62 | BL_GEOMETRY_TYPE_LINE = 11, |
63 | //! BLTriangle struct. |
64 | BL_GEOMETRY_TYPE_TRIANGLE = 12, |
65 | //! BLArrayView<BLPointI> representing a polyline. |
66 | BL_GEOMETRY_TYPE_POLYLINEI = 13, |
67 | //! BLArrayView<BLPoint> representing a polyline. |
68 | BL_GEOMETRY_TYPE_POLYLINED = 14, |
69 | //! BLArrayView<BLPointI> representing a polygon. |
70 | BL_GEOMETRY_TYPE_POLYGONI = 15, |
71 | //! BLArrayView<BLPoint> representing a polygon. |
72 | BL_GEOMETRY_TYPE_POLYGOND = 16, |
73 | //! BLArrayView<BLBoxI> struct. |
74 | BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXI = 17, |
75 | //! BLArrayView<BLBox> struct. |
76 | BL_GEOMETRY_TYPE_ARRAY_VIEW_BOXD = 18, |
77 | //! BLArrayView<BLRectI> struct. |
78 | BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTI = 19, |
79 | //! BLArrayView<BLRect> struct. |
80 | BL_GEOMETRY_TYPE_ARRAY_VIEW_RECTD = 20, |
81 | //! BLPath (or BLPathCore). |
82 | BL_GEOMETRY_TYPE_PATH = 21, |
83 | //! BLRegion (or BLRegionCore). |
84 | BL_GEOMETRY_TYPE_REGION = 22, |
85 | |
86 | //! Count of geometry types. |
87 | BL_GEOMETRY_TYPE_COUNT = 23 |
88 | }; |
89 | |
90 | //! Fill rule. |
91 | BL_DEFINE_ENUM(BLFillRule) { |
92 | //! Non-zero fill-rule. |
93 | BL_FILL_RULE_NON_ZERO = 0, |
94 | //! Even-odd fill-rule. |
95 | BL_FILL_RULE_EVEN_ODD = 1, |
96 | |
97 | //! Count of fill rule types. |
98 | BL_FILL_RULE_COUNT = 2 |
99 | }; |
100 | |
101 | //! Hit-test result. |
102 | BL_DEFINE_ENUM(BLHitTest) { |
103 | //!< Fully in. |
104 | BL_HIT_TEST_IN = 0, |
105 | //!< Partially in/out. |
106 | BL_HIT_TEST_PART = 1, |
107 | //!< Fully out. |
108 | BL_HIT_TEST_OUT = 2, |
109 | |
110 | //!< Hit test failed (invalid argument, NaNs, etc). |
111 | BL_HIT_TEST_INVALID = 0xFFFFFFFFu |
112 | }; |
113 | |
114 | // ============================================================================ |
115 | // [BLPointI] |
116 | // ============================================================================ |
117 | |
118 | //! Point specified as [x, y] using `int` as a storage type. |
119 | struct BLPointI { |
120 | int x; |
121 | int y; |
122 | |
123 | // -------------------------------------------------------------------------- |
124 | #ifdef __cplusplus |
125 | |
126 | BL_INLINE BLPointI() noexcept = default; |
127 | constexpr BLPointI(const BLPointI&) noexcept = default; |
128 | |
129 | constexpr BLPointI(int x, int y) noexcept |
130 | : x(x), |
131 | y(y) {} |
132 | |
133 | BL_INLINE bool operator==(const BLPointI& other) const noexcept { return equals(other); } |
134 | BL_INLINE bool operator!=(const BLPointI& other) const noexcept { return !equals(other); } |
135 | |
136 | BL_INLINE void reset() noexcept { reset(0, 0); } |
137 | BL_INLINE void reset(const BLPointI& other) noexcept { reset(other.x, other.y); } |
138 | BL_INLINE void reset(int x, int y) noexcept { |
139 | this->x = x; |
140 | this->y = y; |
141 | } |
142 | |
143 | BL_INLINE bool equals(const BLPointI& other) const noexcept { |
144 | return blEquals(this->x, other.x) & |
145 | blEquals(this->y, other.y) ; |
146 | } |
147 | |
148 | #endif |
149 | // -------------------------------------------------------------------------- |
150 | }; |
151 | |
152 | // ============================================================================ |
153 | // [BLSizeI] |
154 | // ============================================================================ |
155 | |
156 | //! Size specified as [w, h] using `int` as a storage type. |
157 | struct BLSizeI { |
158 | int w; |
159 | int h; |
160 | |
161 | // -------------------------------------------------------------------------- |
162 | #ifdef __cplusplus |
163 | |
164 | BL_INLINE BLSizeI() noexcept = default; |
165 | constexpr BLSizeI(const BLSizeI&) noexcept = default; |
166 | |
167 | constexpr BLSizeI(int w, int h) noexcept |
168 | : w(w), |
169 | h(h) {} |
170 | |
171 | BL_INLINE bool operator==(const BLSizeI& other) const noexcept { return equals(other); } |
172 | BL_INLINE bool operator!=(const BLSizeI& other) const noexcept { return !equals(other); } |
173 | |
174 | BL_INLINE void reset() noexcept { reset(0, 0); } |
175 | BL_INLINE void reset(const BLSizeI& other) noexcept { reset(other.w, other.h); } |
176 | BL_INLINE void reset(int w, int h) noexcept { |
177 | this->w = w; |
178 | this->h = h; |
179 | } |
180 | |
181 | BL_INLINE bool equals(const BLSizeI& other) const noexcept { |
182 | return blEquals(this->w, other.w) & |
183 | blEquals(this->h, other.h) ; |
184 | } |
185 | |
186 | #endif |
187 | // -------------------------------------------------------------------------- |
188 | }; |
189 | |
190 | // ============================================================================ |
191 | // [BLBoxI] |
192 | // ============================================================================ |
193 | |
194 | //! Box specified as [x0, y0, x1, y1] using `int` as a storage type. |
195 | struct BLBoxI { |
196 | int x0; |
197 | int y0; |
198 | int x1; |
199 | int y1; |
200 | |
201 | // -------------------------------------------------------------------------- |
202 | #ifdef __cplusplus |
203 | |
204 | BL_INLINE BLBoxI() noexcept = default; |
205 | constexpr BLBoxI(const BLBoxI&) noexcept = default; |
206 | |
207 | constexpr BLBoxI(int x0, int y0, int x1, int y1) noexcept |
208 | : x0(x0), |
209 | y0(y0), |
210 | x1(x1), |
211 | y1(y1) {} |
212 | |
213 | BL_INLINE bool operator==(const BLBoxI& other) const noexcept { return equals(other); } |
214 | BL_INLINE bool operator!=(const BLBoxI& other) const noexcept { return !equals(other); } |
215 | |
216 | BL_INLINE void reset() noexcept { reset(0, 0, 0, 0); } |
217 | BL_INLINE void reset(const BLBoxI& other) noexcept { reset(other.x0, other.y0, other.x1, other.y1); } |
218 | BL_INLINE void reset(int x0, int y0, int x1, int y1) noexcept { |
219 | this->x0 = x0; |
220 | this->y0 = y0; |
221 | this->x1 = x1; |
222 | this->y1 = y1; |
223 | } |
224 | |
225 | BL_INLINE bool equals(const BLBoxI& other) const noexcept { |
226 | return blEquals(this->x0, other.x0) & |
227 | blEquals(this->y0, other.y0) & |
228 | blEquals(this->x1, other.x1) & |
229 | blEquals(this->y1, other.y1) ; |
230 | } |
231 | |
232 | BL_INLINE bool contains(int x, int y) const noexcept { |
233 | return (x >= this->x0) & |
234 | (y >= this->y0) & |
235 | (x < this->x1) & |
236 | (y < this->y1) ; |
237 | } |
238 | BL_INLINE bool contains(const BLPointI& pt) const noexcept { return contains(pt.x, pt.y); } |
239 | |
240 | #endif |
241 | // -------------------------------------------------------------------------- |
242 | }; |
243 | |
244 | // ============================================================================ |
245 | // [BLRectI] |
246 | // ============================================================================ |
247 | |
248 | //! Rectangle specified as [x, y, w, h] using `int` as a storage type. |
249 | struct BLRectI { |
250 | int x; |
251 | int y; |
252 | int w; |
253 | int h; |
254 | |
255 | // -------------------------------------------------------------------------- |
256 | #ifdef __cplusplus |
257 | |
258 | BL_INLINE BLRectI() noexcept = default; |
259 | constexpr BLRectI(const BLRectI&) noexcept = default; |
260 | |
261 | constexpr BLRectI(int x, int y, int w, int h) noexcept |
262 | : x(x), |
263 | y(y), |
264 | w(w), |
265 | h(h) {} |
266 | |
267 | BL_INLINE bool operator==(const BLRectI& other) const noexcept { return equals(other); } |
268 | BL_INLINE bool operator!=(const BLRectI& other) const noexcept { return !equals(other); } |
269 | |
270 | BL_INLINE void reset() noexcept { reset(0, 0, 0, 0); } |
271 | BL_INLINE void reset(const BLRectI& other) noexcept { reset(other.x, other.y, other.w, other.h); } |
272 | BL_INLINE void reset(int x, int y, int w, int h) noexcept { |
273 | this->x = x; |
274 | this->y = y; |
275 | this->w = w; |
276 | this->h = h; |
277 | } |
278 | |
279 | BL_INLINE bool equals(const BLRectI& other) const noexcept { |
280 | return blEquals(this->x, other.x) & |
281 | blEquals(this->y, other.y) & |
282 | blEquals(this->w, other.w) & |
283 | blEquals(this->h, other.h) ; |
284 | } |
285 | |
286 | #endif |
287 | // -------------------------------------------------------------------------- |
288 | }; |
289 | |
290 | // ============================================================================ |
291 | // [BLPoint] |
292 | // ============================================================================ |
293 | |
294 | //! Point specified as [x, y] using `double` as a storage type. |
295 | struct BLPoint { |
296 | double x; |
297 | double y; |
298 | |
299 | // -------------------------------------------------------------------------- |
300 | #ifdef __cplusplus |
301 | |
302 | BL_INLINE BLPoint() noexcept = default; |
303 | constexpr BLPoint(const BLPoint&) noexcept = default; |
304 | |
305 | constexpr BLPoint(const BLPointI& other) noexcept |
306 | : x(other.x), |
307 | y(other.y) {} |
308 | |
309 | constexpr BLPoint(double x, double y) noexcept |
310 | : x(x), |
311 | y(y) {} |
312 | |
313 | BL_INLINE bool operator==(const BLPoint& other) const noexcept { return equals(other); } |
314 | BL_INLINE bool operator!=(const BLPoint& other) const noexcept { return !equals(other); } |
315 | |
316 | BL_INLINE void reset() noexcept { reset(0, 0); } |
317 | BL_INLINE void reset(const BLPoint& other) noexcept { reset(other.x, other.y); } |
318 | BL_INLINE void reset(double x, double y) noexcept { |
319 | this->x = x; |
320 | this->y = y; |
321 | } |
322 | |
323 | BL_INLINE bool equals(const BLPoint& other) const noexcept { |
324 | return blEquals(this->x, other.x) & |
325 | blEquals(this->y, other.y) ; |
326 | } |
327 | |
328 | #endif |
329 | // -------------------------------------------------------------------------- |
330 | }; |
331 | |
332 | // ============================================================================ |
333 | // [BLSize] |
334 | // ============================================================================ |
335 | |
336 | //! Size specified as [w, h] using `double` as a storage type. |
337 | struct BLSize { |
338 | double w; |
339 | double h; |
340 | |
341 | // -------------------------------------------------------------------------- |
342 | #ifdef __cplusplus |
343 | |
344 | BL_INLINE BLSize() noexcept = default; |
345 | constexpr BLSize(const BLSize&) noexcept = default; |
346 | |
347 | constexpr BLSize(double w, double h) noexcept |
348 | : w(w), |
349 | h(h) {} |
350 | |
351 | constexpr BLSize(const BLSizeI& other) noexcept |
352 | : w(other.w), |
353 | h(other.h) {} |
354 | |
355 | BL_INLINE bool operator==(const BLSize& other) const noexcept { return equals(other); } |
356 | BL_INLINE bool operator!=(const BLSize& other) const noexcept { return !equals(other); } |
357 | |
358 | BL_INLINE void reset() noexcept { reset(0, 0); } |
359 | BL_INLINE void reset(const BLSize& other) noexcept { reset(other.w, other.h); } |
360 | BL_INLINE void reset(double w, double h) noexcept { |
361 | this->w = w; |
362 | this->h = h; |
363 | } |
364 | |
365 | BL_INLINE bool equals(const BLSize& other) const noexcept { |
366 | return blEquals(this->w, other.w) & |
367 | blEquals(this->h, other.h) ; |
368 | } |
369 | |
370 | #endif |
371 | // -------------------------------------------------------------------------- |
372 | }; |
373 | |
374 | // ============================================================================ |
375 | // [BLBox] |
376 | // ============================================================================ |
377 | |
378 | //! Box specified as [x0, y0, x1, y1] using `double` as a storage type. |
379 | struct BLBox { |
380 | double x0; |
381 | double y0; |
382 | double x1; |
383 | double y1; |
384 | |
385 | // -------------------------------------------------------------------------- |
386 | #ifdef __cplusplus |
387 | |
388 | BL_INLINE BLBox() noexcept = default; |
389 | constexpr BLBox(const BLBox&) noexcept = default; |
390 | |
391 | constexpr BLBox(const BLBoxI& other) noexcept |
392 | : x0(other.x0), |
393 | y0(other.y0), |
394 | x1(other.x1), |
395 | y1(other.y1) {} |
396 | |
397 | constexpr BLBox(double x0, double y0, double x1, double y1) noexcept |
398 | : x0(x0), |
399 | y0(y0), |
400 | x1(x1), |
401 | y1(y1) {} |
402 | |
403 | BL_INLINE bool operator==(const BLBox& other) const noexcept { return equals(other); } |
404 | BL_INLINE bool operator!=(const BLBox& other) const noexcept { return !equals(other); } |
405 | |
406 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0, 0.0); } |
407 | BL_INLINE void reset(const BLBox& other) noexcept { reset(other.x0, other.y0, other.x1, other.y1); } |
408 | BL_INLINE void reset(double x0, double y0, double x1, double y1) noexcept { |
409 | this->x0 = x0; |
410 | this->y0 = y0; |
411 | this->x1 = x1; |
412 | this->y1 = y1; |
413 | } |
414 | |
415 | BL_INLINE bool equals(const BLBox& other) const noexcept { |
416 | return blEquals(this->x0, other.x0) & |
417 | blEquals(this->y0, other.y0) & |
418 | blEquals(this->x1, other.x1) & |
419 | blEquals(this->y1, other.y1) ; |
420 | } |
421 | |
422 | BL_INLINE bool contains(double x, double y) const noexcept { |
423 | return (x >= this->x0) & |
424 | (y >= this->y0) & |
425 | (x < this->x1) & |
426 | (y < this->y1) ; |
427 | } |
428 | BL_INLINE bool contains(const BLPoint& pt) const noexcept { return contains(pt.x, pt.y); } |
429 | |
430 | #endif |
431 | // -------------------------------------------------------------------------- |
432 | }; |
433 | |
434 | // ============================================================================ |
435 | // [BLRect] |
436 | // ============================================================================ |
437 | |
438 | //! Rectangle specified as [x, y, w, h] using `double` as a storage type. |
439 | struct BLRect { |
440 | double x; |
441 | double y; |
442 | double w; |
443 | double h; |
444 | |
445 | // -------------------------------------------------------------------------- |
446 | #ifdef __cplusplus |
447 | |
448 | BL_INLINE BLRect() noexcept = default; |
449 | constexpr BLRect(const BLRect&) noexcept = default; |
450 | |
451 | constexpr BLRect(const BLRectI& other) noexcept |
452 | : x(other.x), |
453 | y(other.y), |
454 | w(other.w), |
455 | h(other.h) {} |
456 | |
457 | constexpr BLRect(double x, double y, double w, double h) noexcept |
458 | : x(x), y(y), w(w), h(h) {} |
459 | |
460 | BL_INLINE bool operator==(const BLRect& other) const noexcept { return equals(other); } |
461 | BL_INLINE bool operator!=(const BLRect& other) const noexcept { return !equals(other); } |
462 | |
463 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0, 0.0); } |
464 | BL_INLINE void reset(const BLRect& other) noexcept { reset(other.x, other.y, other.w, other.h); } |
465 | BL_INLINE void reset(double x, double y, double w, double h) noexcept { |
466 | this->x = x; |
467 | this->y = y; |
468 | this->w = w; |
469 | this->h = h; |
470 | } |
471 | |
472 | BL_INLINE bool equals(const BLRect& other) const noexcept { |
473 | return blEquals(this->x, other.x) & |
474 | blEquals(this->y, other.y) & |
475 | blEquals(this->w, other.w) & |
476 | blEquals(this->h, other.h) ; |
477 | } |
478 | |
479 | #endif |
480 | // -------------------------------------------------------------------------- |
481 | }; |
482 | |
483 | // ============================================================================ |
484 | // [BLLine] |
485 | // ============================================================================ |
486 | |
487 | //! Line specified as [x0, y0, x1, y1] using `double` as a storage type. |
488 | struct BLLine { |
489 | double x0, y0; |
490 | double x1, y1; |
491 | |
492 | // -------------------------------------------------------------------------- |
493 | #ifdef __cplusplus |
494 | |
495 | BL_INLINE BLLine() noexcept = default; |
496 | constexpr BLLine(const BLLine&) noexcept = default; |
497 | |
498 | constexpr BLLine(double x0, double y0, double x1, double y1) noexcept |
499 | : x0(x0), y0(y0), x1(x1), y1(y1) {} |
500 | |
501 | BL_INLINE bool operator==(const BLLine& other) const noexcept { return equals(other); } |
502 | BL_INLINE bool operator!=(const BLLine& other) const noexcept { return !equals(other); } |
503 | |
504 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0, 0.0); } |
505 | BL_INLINE void reset(const BLLine& other) noexcept { reset(other.x0, other.y0, other.x1, other.y1); } |
506 | BL_INLINE void reset(double x0, double y0, double x1, double y1) noexcept { |
507 | this->x0 = x0; |
508 | this->y0 = y0; |
509 | this->x1 = x1; |
510 | this->y1 = y1; |
511 | } |
512 | |
513 | BL_INLINE bool equals(const BLLine& other) const noexcept { |
514 | return (this->x0 == other.x0) & (this->y0 == other.y0) & |
515 | (this->x1 == other.x1) & (this->y1 == other.y1) ; |
516 | } |
517 | #endif |
518 | // -------------------------------------------------------------------------- |
519 | }; |
520 | |
521 | // ============================================================================ |
522 | // [BLTriangle] |
523 | // ============================================================================ |
524 | |
525 | //! Triangle data specified as [x0, y0, x1, y1, x2, y2] using `double` as a storage type. |
526 | struct BLTriangle { |
527 | double x0, y0; |
528 | double x1, y1; |
529 | double x2, y2; |
530 | |
531 | // -------------------------------------------------------------------------- |
532 | #ifdef __cplusplus |
533 | |
534 | BL_INLINE BLTriangle() noexcept = default; |
535 | constexpr BLTriangle(const BLTriangle&) noexcept = default; |
536 | |
537 | constexpr BLTriangle(double x0, double y0, double x1, double y1, double x2, double y2) noexcept |
538 | : x0(x0), y0(y0), x1(x1), y1(y1), x2(x2), y2(y2) {} |
539 | |
540 | BL_INLINE bool operator==(const BLTriangle& other) const noexcept { return equals(other); } |
541 | BL_INLINE bool operator!=(const BLTriangle& other) const noexcept { return !equals(other); } |
542 | |
543 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); } |
544 | BL_INLINE void reset(const BLTriangle& other) noexcept { reset(other.x0, other.y0, other.x1, other.y1, other.x2, other.y2); } |
545 | BL_INLINE void reset(double x0, double y0, double x1, double y1, double x2, double y2) noexcept { |
546 | this->x0 = x0; |
547 | this->y0 = y0; |
548 | this->x1 = x1; |
549 | this->y1 = y1; |
550 | this->x2 = x2; |
551 | this->y2 = y2; |
552 | } |
553 | |
554 | BL_INLINE bool equals(const BLTriangle& other) const noexcept { |
555 | return (this->x0 == other.x0) & (this->y0 == other.y0) & |
556 | (this->x1 == other.x1) & (this->y1 == other.y1) & |
557 | (this->x2 == other.x2) & (this->y2 == other.y2) ; |
558 | } |
559 | #endif |
560 | // -------------------------------------------------------------------------- |
561 | }; |
562 | |
563 | // ============================================================================ |
564 | // [BLRoundRect] |
565 | // ============================================================================ |
566 | |
567 | //! Rounded rectangle specified as [x, y, w, h, rx, ry] using `double` as a storage type. |
568 | struct BLRoundRect { |
569 | double x, y, w, h; |
570 | double rx, ry; |
571 | |
572 | // -------------------------------------------------------------------------- |
573 | #ifdef __cplusplus |
574 | |
575 | BL_INLINE BLRoundRect() noexcept = default; |
576 | constexpr BLRoundRect(const BLRoundRect&) noexcept = default; |
577 | |
578 | constexpr BLRoundRect(const BLRect& rect, double r) noexcept |
579 | : x(rect.x), y(rect.y), w(rect.w), h(rect.h), rx(r), ry(r) {} |
580 | |
581 | constexpr BLRoundRect(const BLRect& rect, double rx, double ry) noexcept |
582 | : x(rect.x), y(rect.y), w(rect.w), h(rect.h), rx(rx), ry(ry) {} |
583 | |
584 | constexpr BLRoundRect(double x, double y, double w, double h, double r) noexcept |
585 | : x(x), y(y), w(w), h(h), rx(r), ry(r) {} |
586 | |
587 | constexpr BLRoundRect(double x, double y, double w, double h, double rx, double ry) noexcept |
588 | : x(x), y(y), w(w), h(h), rx(rx), ry(ry) {} |
589 | |
590 | BL_INLINE bool operator==(const BLRoundRect& other) const noexcept { return equals(other); } |
591 | BL_INLINE bool operator!=(const BLRoundRect& other) const noexcept { return !equals(other); } |
592 | |
593 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); } |
594 | BL_INLINE void reset(const BLRoundRect& other) noexcept { reset(other.x, other.y, other.w, other.h, other.rx, other.ry); } |
595 | BL_INLINE void reset(double x, double y, double w, double h, double r) noexcept { reset(x, y, w, h, r, r); } |
596 | |
597 | BL_INLINE void reset(double x, double y, double w, double h, double rx, double ry) noexcept { |
598 | this->x = x; |
599 | this->y = y; |
600 | this->w = w; |
601 | this->h = h; |
602 | this->rx = rx; |
603 | this->ry = ry; |
604 | } |
605 | |
606 | BL_INLINE bool equals(const BLRoundRect& other) const noexcept { |
607 | return (this->x == other.x ) & (this->y == other.y ) & |
608 | (this->w == other.w ) & (this->h == other.h ) & |
609 | (this->rx == other.rx) & (this->rx == other.ry) ; |
610 | } |
611 | #endif |
612 | // -------------------------------------------------------------------------- |
613 | }; |
614 | |
615 | // ============================================================================ |
616 | // [BLCircle] |
617 | // ============================================================================ |
618 | |
619 | //! Circle specified as [cx, cy, r] using `double` as a storage type. |
620 | struct BLCircle { |
621 | double cx, cy; |
622 | double r; |
623 | |
624 | // -------------------------------------------------------------------------- |
625 | #ifdef __cplusplus |
626 | |
627 | BL_INLINE BLCircle() noexcept = default; |
628 | constexpr BLCircle(const BLCircle&) noexcept = default; |
629 | |
630 | constexpr BLCircle(double cx, double cy, double r) noexcept |
631 | : cx(cx), cy(cy), r(r) {} |
632 | |
633 | BL_INLINE bool operator==(const BLCircle& other) const noexcept { return equals(other); } |
634 | BL_INLINE bool operator!=(const BLCircle& other) const noexcept { return !equals(other); } |
635 | |
636 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0); } |
637 | BL_INLINE void reset(const BLCircle& other) noexcept { reset(other.cx, other.cy, other.r); } |
638 | BL_INLINE void reset(double cx, double cy, double r) noexcept { |
639 | this->cx = cx; |
640 | this->cy = cy; |
641 | this->r = r; |
642 | } |
643 | |
644 | BL_INLINE bool equals(const BLCircle& other) const noexcept { |
645 | return (this->cx == other.cx) & (this->cy == other.cy) & (this->r == other.r); |
646 | } |
647 | #endif |
648 | // -------------------------------------------------------------------------- |
649 | }; |
650 | |
651 | // ============================================================================ |
652 | // [BLEllipse] |
653 | // ============================================================================ |
654 | |
655 | //! Ellipse specified as [cx, cy, rx, ry] using `double` as a storage type. |
656 | struct BLEllipse { |
657 | double cx, cy; |
658 | double rx, ry; |
659 | |
660 | // -------------------------------------------------------------------------- |
661 | #ifdef __cplusplus |
662 | |
663 | BL_INLINE BLEllipse() noexcept = default; |
664 | constexpr BLEllipse(const BLEllipse&) noexcept = default; |
665 | |
666 | constexpr BLEllipse(double cx, double cy, double r) noexcept |
667 | : cx(cx), cy(cy), rx(r), ry(r) {} |
668 | |
669 | constexpr BLEllipse(double cx, double cy, double rx, double ry) noexcept |
670 | : cx(cx), cy(cy), rx(rx), ry(ry) {} |
671 | |
672 | BL_INLINE bool operator==(const BLEllipse& other) const noexcept { return equals(other); } |
673 | BL_INLINE bool operator!=(const BLEllipse& other) const noexcept { return !equals(other); } |
674 | |
675 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0, 0.0); } |
676 | BL_INLINE void reset(const BLEllipse& other) noexcept { reset(other.cx, other.cy, other.rx, other.ry); } |
677 | BL_INLINE void reset(double cx, double cy, double r) noexcept { reset(cx, cy, r, r); } |
678 | |
679 | BL_INLINE void reset(double cx, double cy, double rx, double ry) noexcept { |
680 | this->cx = cx; |
681 | this->cy = cy; |
682 | this->rx = rx; |
683 | this->ry = ry; |
684 | } |
685 | |
686 | BL_INLINE bool equals(const BLEllipse& other) const noexcept { |
687 | return (this->cx == other.cx) & (this->cy == other.cy) & |
688 | (this->rx == other.rx) & (this->ry == other.ry) ; |
689 | } |
690 | #endif |
691 | // -------------------------------------------------------------------------- |
692 | }; |
693 | |
694 | // ============================================================================ |
695 | // [BLArc] |
696 | // ============================================================================ |
697 | |
698 | //! Arc specified as [cx, cy, rx, ry, start, sweep[ using `double` as a storage type. |
699 | struct BLArc { |
700 | double cx, cy; |
701 | double rx, ry; |
702 | double start; |
703 | double sweep; |
704 | |
705 | // -------------------------------------------------------------------------- |
706 | #ifdef __cplusplus |
707 | |
708 | BL_INLINE BLArc() noexcept = default; |
709 | constexpr BLArc(const BLArc&) noexcept = default; |
710 | |
711 | constexpr BLArc(double cx, double cy, double rx, double ry, double start, double sweep) noexcept |
712 | : cx(cx), cy(cy), rx(rx), ry(ry), start(start), sweep(sweep) {} |
713 | |
714 | BL_INLINE bool operator==(const BLArc& other) const noexcept { return equals(other); } |
715 | BL_INLINE bool operator!=(const BLArc& other) const noexcept { return !equals(other); } |
716 | |
717 | BL_INLINE void reset() noexcept { reset(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); } |
718 | BL_INLINE void reset(const BLArc& other) noexcept { reset(other.cx, other.cy, other.rx, other.ry, other.start, other.sweep); } |
719 | BL_INLINE void reset(double cx, double cy, double rx, double ry, double start, double sweep) noexcept { |
720 | this->cx = cx; |
721 | this->cy = cy; |
722 | this->rx = rx; |
723 | this->ry = ry; |
724 | this->start = start; |
725 | this->sweep = sweep; |
726 | } |
727 | |
728 | BL_INLINE bool equals(const BLArc& other) const noexcept { |
729 | return (this->cx == other.cx ) & |
730 | (this->cy == other.cy ) & |
731 | (this->rx == other.rx ) & |
732 | (this->ry == other.ry ) & |
733 | (this->start == other.start) & |
734 | (this->sweep == other.sweep) ; |
735 | } |
736 | #endif |
737 | // -------------------------------------------------------------------------- |
738 | }; |
739 | |
740 | //! \} |
741 | |
742 | // ============================================================================ |
743 | // [Globals Functions] |
744 | // ============================================================================ |
745 | |
746 | #ifdef __cplusplus |
747 | //! \addtogroup blend2d_api_geometry |
748 | //! \{ |
749 | |
750 | //! \name Global Specializations |
751 | //! \{ |
752 | |
753 | template<> BL_INLINE constexpr BLPoint blAbs(const BLPoint& a) noexcept { return BLPoint(blAbs(a.x), blAbs(a.y)); } |
754 | template<> BL_INLINE constexpr BLPoint blMin(const BLPoint& a, const BLPoint& b) noexcept { return BLPoint(blMin(a.x, b.x), blMin(a.y, b.y)); } |
755 | template<> BL_INLINE constexpr BLPoint blMax(const BLPoint& a, const BLPoint& b) noexcept { return BLPoint(blMax(a.x, b.x), blMax(a.y, b.y)); } |
756 | |
757 | template<> BL_INLINE constexpr BLSize blAbs(const BLSize& a) noexcept { return BLSize(blAbs(a.w), blAbs(a.h)); } |
758 | template<> BL_INLINE constexpr BLSize blMin(const BLSize& a, const BLSize& b) noexcept { return BLSize(blMin(a.w, b.w), blMin(a.h, b.h)); } |
759 | template<> BL_INLINE constexpr BLSize blMax(const BLSize& a, const BLSize& b) noexcept { return BLSize(blMax(a.w, b.w), blMax(a.h, b.h)); } |
760 | |
761 | static BL_INLINE constexpr BLPoint blMin(const BLPoint& a, double b) noexcept { return BLPoint(blMin(a.x, b), blMin(a.y, b)); } |
762 | static BL_INLINE constexpr BLPoint blMin(double a, const BLPoint& b) noexcept { return BLPoint(blMin(a, b.x), blMin(a, b.y)); } |
763 | |
764 | static BL_INLINE constexpr BLPoint blMax(const BLPoint& a, double b) noexcept { return BLPoint(blMax(a.x, b), blMax(a.y, b)); } |
765 | static BL_INLINE constexpr BLPoint blMax(double a, const BLPoint& b) noexcept { return BLPoint(blMax(a, b.x), blMax(a, b.y)); } |
766 | |
767 | static BL_INLINE constexpr BLPoint blClamp(const BLPoint& a, double b, double c) noexcept { return blMin(c, blMax(b, a)); } |
768 | |
769 | //! \} |
770 | |
771 | //! \name Overloaded Operators |
772 | //! \{ |
773 | |
774 | static BL_INLINE constexpr BLPointI operator-(const BLPointI& self) noexcept { return BLPointI(-self.x, -self.y); } |
775 | |
776 | static BL_INLINE constexpr BLPointI operator+(const BLPointI& a, int b) noexcept { return BLPointI(a.x + b, a.y + b); } |
777 | static BL_INLINE constexpr BLPointI operator-(const BLPointI& a, int b) noexcept { return BLPointI(a.x - b, a.y - b); } |
778 | static BL_INLINE constexpr BLPointI operator*(const BLPointI& a, int b) noexcept { return BLPointI(a.x * b, a.y * b); } |
779 | |
780 | static BL_INLINE constexpr BLPointI operator+(int a, const BLPointI& b) noexcept { return BLPointI(a + b.x, a + b.y); } |
781 | static BL_INLINE constexpr BLPointI operator-(int a, const BLPointI& b) noexcept { return BLPointI(a - b.x, a - b.y); } |
782 | static BL_INLINE constexpr BLPointI operator*(int a, const BLPointI& b) noexcept { return BLPointI(a * b.x, a * b.y); } |
783 | |
784 | static BL_INLINE constexpr BLPointI operator+(const BLPointI& a, const BLPointI& b) noexcept { return BLPointI(a.x + b.x, a.y + b.y); } |
785 | static BL_INLINE constexpr BLPointI operator-(const BLPointI& a, const BLPointI& b) noexcept { return BLPointI(a.x - b.x, a.y - b.y); } |
786 | static BL_INLINE constexpr BLPointI operator*(const BLPointI& a, const BLPointI& b) noexcept { return BLPointI(a.x * b.x, a.y * b.y); } |
787 | |
788 | static BL_INLINE BLPointI& operator+=(BLPointI& a, int b) noexcept { a.reset(a.x + b, a.y + b); return a; } |
789 | static BL_INLINE BLPointI& operator-=(BLPointI& a, int b) noexcept { a.reset(a.x - b, a.y - b); return a; } |
790 | static BL_INLINE BLPointI& operator*=(BLPointI& a, int b) noexcept { a.reset(a.x * b, a.y * b); return a; } |
791 | static BL_INLINE BLPointI& operator/=(BLPointI& a, int b) noexcept { a.reset(a.x / b, a.y / b); return a; } |
792 | |
793 | static BL_INLINE BLPointI& operator+=(BLPointI& a, const BLPointI& b) noexcept { a.reset(a.x + b.x, a.y + b.y); return a; } |
794 | static BL_INLINE BLPointI& operator-=(BLPointI& a, const BLPointI& b) noexcept { a.reset(a.x - b.x, a.y - b.y); return a; } |
795 | static BL_INLINE BLPointI& operator*=(BLPointI& a, const BLPointI& b) noexcept { a.reset(a.x * b.x, a.y * b.y); return a; } |
796 | static BL_INLINE BLPointI& operator/=(BLPointI& a, const BLPointI& b) noexcept { a.reset(a.x / b.x, a.y / b.y); return a; } |
797 | |
798 | static BL_INLINE constexpr BLPoint operator-(const BLPoint& a) noexcept { return BLPoint(-a.x, -a.y); } |
799 | |
800 | static BL_INLINE constexpr BLPoint operator+(const BLPoint& a, double b) noexcept { return BLPoint(a.x + b, a.y + b); } |
801 | static BL_INLINE constexpr BLPoint operator-(const BLPoint& a, double b) noexcept { return BLPoint(a.x - b, a.y - b); } |
802 | static BL_INLINE constexpr BLPoint operator*(const BLPoint& a, double b) noexcept { return BLPoint(a.x * b, a.y * b); } |
803 | static BL_INLINE constexpr BLPoint operator/(const BLPoint& a, double b) noexcept { return BLPoint(a.x / b, a.y / b); } |
804 | |
805 | static BL_INLINE constexpr BLPoint operator+(double a, const BLPoint& b) noexcept { return BLPoint(a + b.x, a + b.y); } |
806 | static BL_INLINE constexpr BLPoint operator-(double a, const BLPoint& b) noexcept { return BLPoint(a - b.x, a - b.y); } |
807 | static BL_INLINE constexpr BLPoint operator*(double a, const BLPoint& b) noexcept { return BLPoint(a * b.x, a * b.y); } |
808 | static BL_INLINE constexpr BLPoint operator/(double a, const BLPoint& b) noexcept { return BLPoint(a / b.x, a / b.y); } |
809 | |
810 | static BL_INLINE constexpr BLPoint operator+(const BLPoint& a, const BLPoint& b) noexcept { return BLPoint(a.x + b.x, a.y + b.y); } |
811 | static BL_INLINE constexpr BLPoint operator-(const BLPoint& a, const BLPoint& b) noexcept { return BLPoint(a.x - b.x, a.y - b.y); } |
812 | static BL_INLINE constexpr BLPoint operator*(const BLPoint& a, const BLPoint& b) noexcept { return BLPoint(a.x * b.x, a.y * b.y); } |
813 | static BL_INLINE constexpr BLPoint operator/(const BLPoint& a, const BLPoint& b) noexcept { return BLPoint(a.x / b.x, a.y / b.y); } |
814 | |
815 | static BL_INLINE BLPoint& operator+=(BLPoint& a, double b) noexcept { a.reset(a.x + b, a.y + b); return a; } |
816 | static BL_INLINE BLPoint& operator-=(BLPoint& a, double b) noexcept { a.reset(a.x - b, a.y - b); return a; } |
817 | static BL_INLINE BLPoint& operator*=(BLPoint& a, double b) noexcept { a.reset(a.x * b, a.y * b); return a; } |
818 | static BL_INLINE BLPoint& operator/=(BLPoint& a, double b) noexcept { a.reset(a.x / b, a.y / b); return a; } |
819 | |
820 | static BL_INLINE BLPoint& operator+=(BLPoint& a, const BLPoint& b) noexcept { a.reset(a.x + b.x, a.y + b.y); return a; } |
821 | static BL_INLINE BLPoint& operator-=(BLPoint& a, const BLPoint& b) noexcept { a.reset(a.x - b.x, a.y - b.y); return a; } |
822 | static BL_INLINE BLPoint& operator*=(BLPoint& a, const BLPoint& b) noexcept { a.reset(a.x * b.x, a.y * b.y); return a; } |
823 | static BL_INLINE BLPoint& operator/=(BLPoint& a, const BLPoint& b) noexcept { a.reset(a.x / b.x, a.y / b.y); return a; } |
824 | |
825 | static BL_INLINE BLBox operator+(double a, const BLBox& b) noexcept { return BLBox(a + b.x0, a + b.y0, a + b.x1, a + b.y1); } |
826 | static BL_INLINE BLBox operator-(double a, const BLBox& b) noexcept { return BLBox(a - b.x0, a - b.y0, a - b.x1, a - b.y1); } |
827 | static BL_INLINE BLBox operator*(double a, const BLBox& b) noexcept { return BLBox(a * b.x0, a * b.y0, a * b.x1, a * b.y1); } |
828 | static BL_INLINE BLBox operator/(double a, const BLBox& b) noexcept { return BLBox(a / b.x0, a / b.y0, a / b.x1, a / b.y1); } |
829 | |
830 | static BL_INLINE BLBox operator+(const BLBox& a, double b) noexcept { return BLBox(a.x0 + b, a.y0 + b, a.x1 + b, a.y1 + b); } |
831 | static BL_INLINE BLBox operator-(const BLBox& a, double b) noexcept { return BLBox(a.x0 - b, a.y0 - b, a.x1 - b, a.y1 - b); } |
832 | static BL_INLINE BLBox operator*(const BLBox& a, double b) noexcept { return BLBox(a.x0 * b, a.y0 * b, a.x1 * b, a.y1 * b); } |
833 | static BL_INLINE BLBox operator/(const BLBox& a, double b) noexcept { return BLBox(a.x0 / b, a.y0 / b, a.x1 / b, a.y1 / b); } |
834 | |
835 | static BL_INLINE BLBox operator+(const BLPoint& a, const BLBox& b) noexcept { return BLBox(a.x + b.x0, a.y + b.y0, a.x + b.x1, a.y + b.y1); } |
836 | static BL_INLINE BLBox operator-(const BLPoint& a, const BLBox& b) noexcept { return BLBox(a.x - b.x0, a.y - b.y0, a.x - b.x1, a.y - b.y1); } |
837 | static BL_INLINE BLBox operator*(const BLPoint& a, const BLBox& b) noexcept { return BLBox(a.x * b.x0, a.y * b.y0, a.x * b.x1, a.y * b.y1); } |
838 | static BL_INLINE BLBox operator/(const BLPoint& a, const BLBox& b) noexcept { return BLBox(a.x / b.x0, a.y / b.y0, a.x / b.x1, a.y / b.y1); } |
839 | |
840 | static BL_INLINE BLBox operator+(const BLBox& a, const BLPoint& b) noexcept { return BLBox(a.x0 + b.x, a.y0 + b.y, a.x1 + b.x, a.y1 + b.y); } |
841 | static BL_INLINE BLBox operator-(const BLBox& a, const BLPoint& b) noexcept { return BLBox(a.x0 - b.x, a.y0 - b.y, a.x1 - b.x, a.y1 - b.y); } |
842 | static BL_INLINE BLBox operator*(const BLBox& a, const BLPoint& b) noexcept { return BLBox(a.x0 * b.x, a.y0 * b.y, a.x1 * b.x, a.y1 * b.y); } |
843 | static BL_INLINE BLBox operator/(const BLBox& a, const BLPoint& b) noexcept { return BLBox(a.x0 / b.x, a.y0 / b.y, a.x1 / b.x, a.y1 / b.y); } |
844 | |
845 | static BL_INLINE BLBox& operator+=(BLBox& a, double b) noexcept { a.reset(a.x0 + b, a.y0 + b, a.x1 + b, a.y1 + b); return a; } |
846 | static BL_INLINE BLBox& operator-=(BLBox& a, double b) noexcept { a.reset(a.x0 - b, a.y0 - b, a.x1 - b, a.y1 - b); return a; } |
847 | static BL_INLINE BLBox& operator*=(BLBox& a, double b) noexcept { a.reset(a.x0 * b, a.y0 * b, a.x1 * b, a.y1 * b); return a; } |
848 | static BL_INLINE BLBox& operator/=(BLBox& a, double b) noexcept { a.reset(a.x0 / b, a.y0 / b, a.x1 / b, a.y1 / b); return a; } |
849 | |
850 | static BL_INLINE BLBox& operator+=(BLBox& a, const BLPoint& b) noexcept { a.reset(a.x0 + b.x, a.y0 + b.y, a.x1 + b.x, a.y1 + b.y); return a; } |
851 | static BL_INLINE BLBox& operator-=(BLBox& a, const BLPoint& b) noexcept { a.reset(a.x0 - b.x, a.y0 - b.y, a.x1 - b.x, a.y1 - b.y); return a; } |
852 | static BL_INLINE BLBox& operator*=(BLBox& a, const BLPoint& b) noexcept { a.reset(a.x0 * b.x, a.y0 * b.y, a.x1 * b.x, a.y1 * b.y); return a; } |
853 | static BL_INLINE BLBox& operator/=(BLBox& a, const BLPoint& b) noexcept { a.reset(a.x0 / b.x, a.y0 / b.y, a.x1 / b.x, a.y1 / b.y); return a; } |
854 | |
855 | //! \} |
856 | |
857 | //! \} |
858 | #endif |
859 | |
860 | BL_DIAGNOSTIC_POP |
861 | |
862 | #endif // BLEND2D_BLGEOMETRY_H |
863 | |