comparison SDL3/SDL_rect.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21
22 /**
23 * # CategoryRect
24 *
25 * Some helper functions for managing rectangles and 2D points, in both
26 * integer and floating point versions.
27 */
28
29 #ifndef SDL_rect_h_
30 #define SDL_rect_h_
31
32 #include <SDL3/SDL_stdinc.h>
33 #include <SDL3/SDL_error.h>
34
35 #include <SDL3/SDL_begin_code.h>
36 /* Set up for C function definitions, even when using C++ */
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 /**
42 * The structure that defines a point (using integers).
43 *
44 * \since This struct is available since SDL 3.2.0.
45 *
46 * \sa SDL_GetRectEnclosingPoints
47 * \sa SDL_PointInRect
48 */
49 typedef struct SDL_Point
50 {
51 int x;
52 int y;
53 } SDL_Point;
54
55 /**
56 * The structure that defines a point (using floating point values).
57 *
58 * \since This struct is available since SDL 3.2.0.
59 *
60 * \sa SDL_GetRectEnclosingPointsFloat
61 * \sa SDL_PointInRectFloat
62 */
63 typedef struct SDL_FPoint
64 {
65 float x;
66 float y;
67 } SDL_FPoint;
68
69
70 /**
71 * A rectangle, with the origin at the upper left (using integers).
72 *
73 * \since This struct is available since SDL 3.2.0.
74 *
75 * \sa SDL_RectEmpty
76 * \sa SDL_RectsEqual
77 * \sa SDL_HasRectIntersection
78 * \sa SDL_GetRectIntersection
79 * \sa SDL_GetRectAndLineIntersection
80 * \sa SDL_GetRectUnion
81 * \sa SDL_GetRectEnclosingPoints
82 */
83 typedef struct SDL_Rect
84 {
85 int x, y;
86 int w, h;
87 } SDL_Rect;
88
89
90 /**
91 * A rectangle stored using floating point values.
92 *
93 * The origin of the coordinate space is in the top-left, with increasing
94 * values moving down and right. The properties `x` and `y` represent the
95 * coordinates of the top-left corner of the rectangle.
96 *
97 * \since This struct is available since SDL 3.2.0.
98 *
99 * \sa SDL_RectEmptyFloat
100 * \sa SDL_RectsEqualFloat
101 * \sa SDL_RectsEqualEpsilon
102 * \sa SDL_HasRectIntersectionFloat
103 * \sa SDL_GetRectIntersectionFloat
104 * \sa SDL_GetRectAndLineIntersectionFloat
105 * \sa SDL_GetRectUnionFloat
106 * \sa SDL_GetRectEnclosingPointsFloat
107 * \sa SDL_PointInRectFloat
108 */
109 typedef struct SDL_FRect
110 {
111 float x;
112 float y;
113 float w;
114 float h;
115 } SDL_FRect;
116
117
118 /**
119 * Convert an SDL_Rect to SDL_FRect
120 *
121 * \param rect a pointer to an SDL_Rect.
122 * \param frect a pointer filled in with the floating point representation of
123 * `rect`.
124 *
125 * \threadsafety It is safe to call this function from any thread.
126 *
127 * \since This function is available since SDL 3.2.0.
128 */
129 SDL_FORCE_INLINE void SDL_RectToFRect(const SDL_Rect *rect, SDL_FRect *frect)
130 {
131 frect->x = SDL_static_cast(float, rect->x);
132 frect->y = SDL_static_cast(float, rect->y);
133 frect->w = SDL_static_cast(float, rect->w);
134 frect->h = SDL_static_cast(float, rect->h);
135 }
136
137 /**
138 * Determine whether a point resides inside a rectangle.
139 *
140 * A point is considered part of a rectangle if both `p` and `r` are not NULL,
141 * and `p`'s x and y coordinates are >= to the rectangle's top left corner,
142 * and < the rectangle's x+w and y+h. So a 1x1 rectangle considers point (0,0)
143 * as "inside" and (0,1) as not.
144 *
145 * Note that this is a forced-inline function in a header, and not a public
146 * API function available in the SDL library (which is to say, the code is
147 * embedded in the calling program and the linker and dynamic loader will not
148 * be able to find this function inside SDL itself).
149 *
150 * \param p the point to test.
151 * \param r the rectangle to test.
152 * \returns true if `p` is contained by `r`, false otherwise.
153 *
154 * \threadsafety It is safe to call this function from any thread.
155 *
156 * \since This function is available since SDL 3.2.0.
157 */
158 SDL_FORCE_INLINE bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
159 {
160 return ( p && r && (p->x >= r->x) && (p->x < (r->x + r->w)) &&
161 (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? true : false;
162 }
163
164 /**
165 * Determine whether a rectangle has no area.
166 *
167 * A rectangle is considered "empty" for this function if `r` is NULL, or if
168 * `r`'s width and/or height are <= 0.
169 *
170 * Note that this is a forced-inline function in a header, and not a public
171 * API function available in the SDL library (which is to say, the code is
172 * embedded in the calling program and the linker and dynamic loader will not
173 * be able to find this function inside SDL itself).
174 *
175 * \param r the rectangle to test.
176 * \returns true if the rectangle is "empty", false otherwise.
177 *
178 * \threadsafety It is safe to call this function from any thread.
179 *
180 * \since This function is available since SDL 3.2.0.
181 */
182 SDL_FORCE_INLINE bool SDL_RectEmpty(const SDL_Rect *r)
183 {
184 return ((!r) || (r->w <= 0) || (r->h <= 0)) ? true : false;
185 }
186
187 /**
188 * Determine whether two rectangles are equal.
189 *
190 * Rectangles are considered equal if both are not NULL and each of their x,
191 * y, width and height match.
192 *
193 * Note that this is a forced-inline function in a header, and not a public
194 * API function available in the SDL library (which is to say, the code is
195 * embedded in the calling program and the linker and dynamic loader will not
196 * be able to find this function inside SDL itself).
197 *
198 * \param a the first rectangle to test.
199 * \param b the second rectangle to test.
200 * \returns true if the rectangles are equal, false otherwise.
201 *
202 * \threadsafety It is safe to call this function from any thread.
203 *
204 * \since This function is available since SDL 3.2.0.
205 */
206 SDL_FORCE_INLINE bool SDL_RectsEqual(const SDL_Rect *a, const SDL_Rect *b)
207 {
208 return (a && b && (a->x == b->x) && (a->y == b->y) &&
209 (a->w == b->w) && (a->h == b->h)) ? true : false;
210 }
211
212 /**
213 * Determine whether two rectangles intersect.
214 *
215 * If either pointer is NULL the function will return false.
216 *
217 * \param A an SDL_Rect structure representing the first rectangle.
218 * \param B an SDL_Rect structure representing the second rectangle.
219 * \returns true if there is an intersection, false otherwise.
220 *
221 * \threadsafety It is safe to call this function from any thread.
222 *
223 * \since This function is available since SDL 3.2.0.
224 *
225 * \sa SDL_GetRectIntersection
226 */
227 extern SDL_DECLSPEC bool SDLCALL SDL_HasRectIntersection(const SDL_Rect *A, const SDL_Rect *B);
228
229 /**
230 * Calculate the intersection of two rectangles.
231 *
232 * If `result` is NULL then this function will return false.
233 *
234 * \param A an SDL_Rect structure representing the first rectangle.
235 * \param B an SDL_Rect structure representing the second rectangle.
236 * \param result an SDL_Rect structure filled in with the intersection of
237 * rectangles `A` and `B`.
238 * \returns true if there is an intersection, false otherwise.
239 *
240 * \since This function is available since SDL 3.2.0.
241 *
242 * \sa SDL_HasRectIntersection
243 */
244 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectIntersection(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result);
245
246 /**
247 * Calculate the union of two rectangles.
248 *
249 * \param A an SDL_Rect structure representing the first rectangle.
250 * \param B an SDL_Rect structure representing the second rectangle.
251 * \param result an SDL_Rect structure filled in with the union of rectangles
252 * `A` and `B`.
253 * \returns true on success or false on failure; call SDL_GetError() for more
254 * information.
255 *
256 * \since This function is available since SDL 3.2.0.
257 */
258 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectUnion(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result);
259
260 /**
261 * Calculate a minimal rectangle enclosing a set of points.
262 *
263 * If `clip` is not NULL then only points inside of the clipping rectangle are
264 * considered.
265 *
266 * \param points an array of SDL_Point structures representing points to be
267 * enclosed.
268 * \param count the number of structures in the `points` array.
269 * \param clip an SDL_Rect used for clipping or NULL to enclose all points.
270 * \param result an SDL_Rect structure filled in with the minimal enclosing
271 * rectangle.
272 * \returns true if any points were enclosed or false if all the points were
273 * outside of the clipping rectangle.
274 *
275 * \since This function is available since SDL 3.2.0.
276 */
277 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectEnclosingPoints(const SDL_Point *points, int count, const SDL_Rect *clip, SDL_Rect *result);
278
279 /**
280 * Calculate the intersection of a rectangle and line segment.
281 *
282 * This function is used to clip a line segment to a rectangle. A line segment
283 * contained entirely within the rectangle or that does not intersect will
284 * remain unchanged. A line segment that crosses the rectangle at either or
285 * both ends will be clipped to the boundary of the rectangle and the new
286 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
287 *
288 * \param rect an SDL_Rect structure representing the rectangle to intersect.
289 * \param X1 a pointer to the starting X-coordinate of the line.
290 * \param Y1 a pointer to the starting Y-coordinate of the line.
291 * \param X2 a pointer to the ending X-coordinate of the line.
292 * \param Y2 a pointer to the ending Y-coordinate of the line.
293 * \returns true if there is an intersection, false otherwise.
294 *
295 * \since This function is available since SDL 3.2.0.
296 */
297 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectAndLineIntersection(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2);
298
299
300 /* SDL_FRect versions... */
301
302 /**
303 * Determine whether a point resides inside a floating point rectangle.
304 *
305 * A point is considered part of a rectangle if both `p` and `r` are not NULL,
306 * and `p`'s x and y coordinates are >= to the rectangle's top left corner,
307 * and <= the rectangle's x+w and y+h. So a 1x1 rectangle considers point
308 * (0,0) and (0,1) as "inside" and (0,2) as not.
309 *
310 * Note that this is a forced-inline function in a header, and not a public
311 * API function available in the SDL library (which is to say, the code is
312 * embedded in the calling program and the linker and dynamic loader will not
313 * be able to find this function inside SDL itself).
314 *
315 * \param p the point to test.
316 * \param r the rectangle to test.
317 * \returns true if `p` is contained by `r`, false otherwise.
318 *
319 * \threadsafety It is safe to call this function from any thread.
320 *
321 * \since This function is available since SDL 3.2.0.
322 */
323 SDL_FORCE_INLINE bool SDL_PointInRectFloat(const SDL_FPoint *p, const SDL_FRect *r)
324 {
325 return ( p && r && (p->x >= r->x) && (p->x <= (r->x + r->w)) &&
326 (p->y >= r->y) && (p->y <= (r->y + r->h)) ) ? true : false;
327 }
328
329 /**
330 * Determine whether a floating point rectangle takes no space.
331 *
332 * A rectangle is considered "empty" for this function if `r` is NULL, or if
333 * `r`'s width and/or height are < 0.0f.
334 *
335 * Note that this is a forced-inline function in a header, and not a public
336 * API function available in the SDL library (which is to say, the code is
337 * embedded in the calling program and the linker and dynamic loader will not
338 * be able to find this function inside SDL itself).
339 *
340 * \param r the rectangle to test.
341 * \returns true if the rectangle is "empty", false otherwise.
342 *
343 * \threadsafety It is safe to call this function from any thread.
344 *
345 * \since This function is available since SDL 3.2.0.
346 */
347 SDL_FORCE_INLINE bool SDL_RectEmptyFloat(const SDL_FRect *r)
348 {
349 return ((!r) || (r->w < 0.0f) || (r->h < 0.0f)) ? true : false;
350 }
351
352 /**
353 * Determine whether two floating point rectangles are equal, within some
354 * given epsilon.
355 *
356 * Rectangles are considered equal if both are not NULL and each of their x,
357 * y, width and height are within `epsilon` of each other. If you don't know
358 * what value to use for `epsilon`, you should call the SDL_RectsEqualFloat
359 * function instead.
360 *
361 * Note that this is a forced-inline function in a header, and not a public
362 * API function available in the SDL library (which is to say, the code is
363 * embedded in the calling program and the linker and dynamic loader will not
364 * be able to find this function inside SDL itself).
365 *
366 * \param a the first rectangle to test.
367 * \param b the second rectangle to test.
368 * \param epsilon the epsilon value for comparison.
369 * \returns true if the rectangles are equal, false otherwise.
370 *
371 * \threadsafety It is safe to call this function from any thread.
372 *
373 * \since This function is available since SDL 3.2.0.
374 *
375 * \sa SDL_RectsEqualFloat
376 */
377 SDL_FORCE_INLINE bool SDL_RectsEqualEpsilon(const SDL_FRect *a, const SDL_FRect *b, float epsilon)
378 {
379 return (a && b && ((a == b) ||
380 ((SDL_fabsf(a->x - b->x) <= epsilon) &&
381 (SDL_fabsf(a->y - b->y) <= epsilon) &&
382 (SDL_fabsf(a->w - b->w) <= epsilon) &&
383 (SDL_fabsf(a->h - b->h) <= epsilon))))
384 ? true : false;
385 }
386
387 /**
388 * Determine whether two floating point rectangles are equal, within a default
389 * epsilon.
390 *
391 * Rectangles are considered equal if both are not NULL and each of their x,
392 * y, width and height are within SDL_FLT_EPSILON of each other. This is often
393 * a reasonable way to compare two floating point rectangles and deal with the
394 * slight precision variations in floating point calculations that tend to pop
395 * up.
396 *
397 * Note that this is a forced-inline function in a header, and not a public
398 * API function available in the SDL library (which is to say, the code is
399 * embedded in the calling program and the linker and dynamic loader will not
400 * be able to find this function inside SDL itself).
401 *
402 * \param a the first rectangle to test.
403 * \param b the second rectangle to test.
404 * \returns true if the rectangles are equal, false otherwise.
405 *
406 * \threadsafety It is safe to call this function from any thread.
407 *
408 * \since This function is available since SDL 3.2.0.
409 *
410 * \sa SDL_RectsEqualEpsilon
411 */
412 SDL_FORCE_INLINE bool SDL_RectsEqualFloat(const SDL_FRect *a, const SDL_FRect *b)
413 {
414 return SDL_RectsEqualEpsilon(a, b, SDL_FLT_EPSILON);
415 }
416
417 /**
418 * Determine whether two rectangles intersect with float precision.
419 *
420 * If either pointer is NULL the function will return false.
421 *
422 * \param A an SDL_FRect structure representing the first rectangle.
423 * \param B an SDL_FRect structure representing the second rectangle.
424 * \returns true if there is an intersection, false otherwise.
425 *
426 * \since This function is available since SDL 3.2.0.
427 *
428 * \sa SDL_GetRectIntersection
429 */
430 extern SDL_DECLSPEC bool SDLCALL SDL_HasRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B);
431
432 /**
433 * Calculate the intersection of two rectangles with float precision.
434 *
435 * If `result` is NULL then this function will return false.
436 *
437 * \param A an SDL_FRect structure representing the first rectangle.
438 * \param B an SDL_FRect structure representing the second rectangle.
439 * \param result an SDL_FRect structure filled in with the intersection of
440 * rectangles `A` and `B`.
441 * \returns true if there is an intersection, false otherwise.
442 *
443 * \since This function is available since SDL 3.2.0.
444 *
445 * \sa SDL_HasRectIntersectionFloat
446 */
447 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result);
448
449 /**
450 * Calculate the union of two rectangles with float precision.
451 *
452 * \param A an SDL_FRect structure representing the first rectangle.
453 * \param B an SDL_FRect structure representing the second rectangle.
454 * \param result an SDL_FRect structure filled in with the union of rectangles
455 * `A` and `B`.
456 * \returns true on success or false on failure; call SDL_GetError() for more
457 * information.
458 *
459 * \since This function is available since SDL 3.2.0.
460 */
461 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectUnionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result);
462
463 /**
464 * Calculate a minimal rectangle enclosing a set of points with float
465 * precision.
466 *
467 * If `clip` is not NULL then only points inside of the clipping rectangle are
468 * considered.
469 *
470 * \param points an array of SDL_FPoint structures representing points to be
471 * enclosed.
472 * \param count the number of structures in the `points` array.
473 * \param clip an SDL_FRect used for clipping or NULL to enclose all points.
474 * \param result an SDL_FRect structure filled in with the minimal enclosing
475 * rectangle.
476 * \returns true if any points were enclosed or false if all the points were
477 * outside of the clipping rectangle.
478 *
479 * \since This function is available since SDL 3.2.0.
480 */
481 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectEnclosingPointsFloat(const SDL_FPoint *points, int count, const SDL_FRect *clip, SDL_FRect *result);
482
483 /**
484 * Calculate the intersection of a rectangle and line segment with float
485 * precision.
486 *
487 * This function is used to clip a line segment to a rectangle. A line segment
488 * contained entirely within the rectangle or that does not intersect will
489 * remain unchanged. A line segment that crosses the rectangle at either or
490 * both ends will be clipped to the boundary of the rectangle and the new
491 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
492 *
493 * \param rect an SDL_FRect structure representing the rectangle to intersect.
494 * \param X1 a pointer to the starting X-coordinate of the line.
495 * \param Y1 a pointer to the starting Y-coordinate of the line.
496 * \param X2 a pointer to the ending X-coordinate of the line.
497 * \param Y2 a pointer to the ending Y-coordinate of the line.
498 * \returns true if there is an intersection, false otherwise.
499 *
500 * \since This function is available since SDL 3.2.0.
501 */
502 extern SDL_DECLSPEC bool SDLCALL SDL_GetRectAndLineIntersectionFloat(const SDL_FRect *rect, float *X1, float *Y1, float *X2, float *Y2);
503
504 /* Ends C function definitions when using C++ */
505 #ifdef __cplusplus
506 }
507 #endif
508 #include <SDL3/SDL_close_code.h>
509
510 #endif /* SDL_rect_h_ */