SDL 3.0
SDL_rect.h
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2026 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
38extern "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 */
49typedef 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 */
63typedef struct SDL_FPoint
64{
65 float x;
66 float y;
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 */
83typedef 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 */
109typedef 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 */
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 */
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 */
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 */
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 */
227extern 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 * \threadsafety It is safe to call this function from any thread.
241 *
242 * \since This function is available since SDL 3.2.0.
243 *
244 * \sa SDL_HasRectIntersection
245 */
246extern SDL_DECLSPEC bool SDLCALL SDL_GetRectIntersection(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result);
247
248/**
249 * Calculate the union of two rectangles.
250 *
251 * \param A an SDL_Rect structure representing the first rectangle.
252 * \param B an SDL_Rect structure representing the second rectangle.
253 * \param result an SDL_Rect structure filled in with the union of rectangles
254 * `A` and `B`.
255 * \returns true on success or false on failure; call SDL_GetError() for more
256 * information.
257 *
258 * \threadsafety It is safe to call this function from any thread.
259 *
260 * \since This function is available since SDL 3.2.0.
261 */
262extern SDL_DECLSPEC bool SDLCALL SDL_GetRectUnion(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result);
263
264/**
265 * Calculate a minimal rectangle enclosing a set of points.
266 *
267 * If `clip` is not NULL then only points inside of the clipping rectangle are
268 * considered.
269 *
270 * \param points an array of SDL_Point structures representing points to be
271 * enclosed.
272 * \param count the number of structures in the `points` array.
273 * \param clip an SDL_Rect used for clipping or NULL to enclose all points.
274 * \param result an SDL_Rect structure filled in with the minimal enclosing
275 * rectangle.
276 * \returns true if any points were enclosed or false if all the points were
277 * outside of the clipping rectangle.
278 *
279 * \threadsafety It is safe to call this function from any thread.
280 *
281 * \since This function is available since SDL 3.2.0.
282 */
283extern SDL_DECLSPEC bool SDLCALL SDL_GetRectEnclosingPoints(const SDL_Point *points, int count, const SDL_Rect *clip, SDL_Rect *result);
284
285/**
286 * Calculate the intersection of a rectangle and line segment.
287 *
288 * This function is used to clip a line segment to a rectangle. A line segment
289 * contained entirely within the rectangle or that does not intersect will
290 * remain unchanged. A line segment that crosses the rectangle at either or
291 * both ends will be clipped to the boundary of the rectangle and the new
292 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
293 *
294 * \param rect an SDL_Rect structure representing the rectangle to intersect.
295 * \param X1 a pointer to the starting X-coordinate of the line.
296 * \param Y1 a pointer to the starting Y-coordinate of the line.
297 * \param X2 a pointer to the ending X-coordinate of the line.
298 * \param Y2 a pointer to the ending Y-coordinate of the line.
299 * \returns true if there is an intersection, false otherwise.
300 *
301 * \threadsafety It is safe to call this function from any thread.
302 *
303 * \since This function is available since SDL 3.2.0.
304 */
305extern SDL_DECLSPEC bool SDLCALL SDL_GetRectAndLineIntersection(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2);
306
307
308/* SDL_FRect versions... */
309
310/**
311 * Determine whether a point resides inside a floating point rectangle.
312 *
313 * A point is considered part of a rectangle if both `p` and `r` are not NULL,
314 * and `p`'s x and y coordinates are >= to the rectangle's top left corner,
315 * and <= the rectangle's x+w and y+h. So a 1x1 rectangle considers point
316 * (0,0) and (0,1) as "inside" and (0,2) as not.
317 *
318 * Note that this is a forced-inline function in a header, and not a public
319 * API function available in the SDL library (which is to say, the code is
320 * embedded in the calling program and the linker and dynamic loader will not
321 * be able to find this function inside SDL itself).
322 *
323 * \param p the point to test.
324 * \param r the rectangle to test.
325 * \returns true if `p` is contained by `r`, false otherwise.
326 *
327 * \threadsafety It is safe to call this function from any thread.
328 *
329 * \since This function is available since SDL 3.2.0.
330 */
332{
333 return ( p && r && (p->x >= r->x) && (p->x <= (r->x + r->w)) &&
334 (p->y >= r->y) && (p->y <= (r->y + r->h)) ) ? true : false;
335}
336
337/**
338 * Determine whether a floating point rectangle takes no space.
339 *
340 * A rectangle is considered "empty" for this function if `r` is NULL, or if
341 * `r`'s width and/or height are < 0.0f.
342 *
343 * Note that this is a forced-inline function in a header, and not a public
344 * API function available in the SDL library (which is to say, the code is
345 * embedded in the calling program and the linker and dynamic loader will not
346 * be able to find this function inside SDL itself).
347 *
348 * \param r the rectangle to test.
349 * \returns true if the rectangle is "empty", false otherwise.
350 *
351 * \threadsafety It is safe to call this function from any thread.
352 *
353 * \since This function is available since SDL 3.2.0.
354 */
356{
357 return ((!r) || (r->w < 0.0f) || (r->h < 0.0f)) ? true : false;
358}
359
360/**
361 * Determine whether two floating point rectangles are equal, within some
362 * given epsilon.
363 *
364 * Rectangles are considered equal if both are not NULL and each of their x,
365 * y, width and height are within `epsilon` of each other. If you don't know
366 * what value to use for `epsilon`, you should call the SDL_RectsEqualFloat
367 * function instead.
368 *
369 * Note that this is a forced-inline function in a header, and not a public
370 * API function available in the SDL library (which is to say, the code is
371 * embedded in the calling program and the linker and dynamic loader will not
372 * be able to find this function inside SDL itself).
373 *
374 * \param a the first rectangle to test.
375 * \param b the second rectangle to test.
376 * \param epsilon the epsilon value for comparison.
377 * \returns true if the rectangles are equal, false otherwise.
378 *
379 * \threadsafety It is safe to call this function from any thread.
380 *
381 * \since This function is available since SDL 3.2.0.
382 *
383 * \sa SDL_RectsEqualFloat
384 */
385SDL_FORCE_INLINE bool SDL_RectsEqualEpsilon(const SDL_FRect *a, const SDL_FRect *b, float epsilon)
386{
387 return (a && b && ((a == b) ||
388 ((SDL_fabsf(a->x - b->x) <= epsilon) &&
389 (SDL_fabsf(a->y - b->y) <= epsilon) &&
390 (SDL_fabsf(a->w - b->w) <= epsilon) &&
391 (SDL_fabsf(a->h - b->h) <= epsilon))))
392 ? true : false;
393}
394
395/**
396 * Determine whether two floating point rectangles are equal, within a default
397 * epsilon.
398 *
399 * Rectangles are considered equal if both are not NULL and each of their x,
400 * y, width and height are within SDL_FLT_EPSILON of each other. This is often
401 * a reasonable way to compare two floating point rectangles and deal with the
402 * slight precision variations in floating point calculations that tend to pop
403 * up.
404 *
405 * Note that this is a forced-inline function in a header, and not a public
406 * API function available in the SDL library (which is to say, the code is
407 * embedded in the calling program and the linker and dynamic loader will not
408 * be able to find this function inside SDL itself).
409 *
410 * \param a the first rectangle to test.
411 * \param b the second rectangle to test.
412 * \returns true if the rectangles are equal, false otherwise.
413 *
414 * \threadsafety It is safe to call this function from any thread.
415 *
416 * \since This function is available since SDL 3.2.0.
417 *
418 * \sa SDL_RectsEqualEpsilon
419 */
424
425/**
426 * Determine whether two rectangles intersect with float precision.
427 *
428 * If either pointer is NULL the function will return false.
429 *
430 * \param A an SDL_FRect structure representing the first rectangle.
431 * \param B an SDL_FRect structure representing the second rectangle.
432 * \returns true if there is an intersection, false otherwise.
433 *
434 * \threadsafety It is safe to call this function from any thread.
435 *
436 * \since This function is available since SDL 3.2.0.
437 *
438 * \sa SDL_GetRectIntersection
439 */
440extern SDL_DECLSPEC bool SDLCALL SDL_HasRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B);
441
442/**
443 * Calculate the intersection of two rectangles with float precision.
444 *
445 * If `result` is NULL then this function will return false.
446 *
447 * \param A an SDL_FRect structure representing the first rectangle.
448 * \param B an SDL_FRect structure representing the second rectangle.
449 * \param result an SDL_FRect structure filled in with the intersection of
450 * rectangles `A` and `B`.
451 * \returns true if there is an intersection, false otherwise.
452 *
453 * \threadsafety It is safe to call this function from any thread.
454 *
455 * \since This function is available since SDL 3.2.0.
456 *
457 * \sa SDL_HasRectIntersectionFloat
458 */
459extern SDL_DECLSPEC bool SDLCALL SDL_GetRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result);
460
461/**
462 * Calculate the union of two rectangles with float precision.
463 *
464 * \param A an SDL_FRect structure representing the first rectangle.
465 * \param B an SDL_FRect structure representing the second rectangle.
466 * \param result an SDL_FRect structure filled in with the union of rectangles
467 * `A` and `B`.
468 * \returns true on success or false on failure; call SDL_GetError() for more
469 * information.
470 *
471 * \threadsafety It is safe to call this function from any thread.
472 *
473 * \since This function is available since SDL 3.2.0.
474 */
475extern SDL_DECLSPEC bool SDLCALL SDL_GetRectUnionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result);
476
477/**
478 * Calculate a minimal rectangle enclosing a set of points with float
479 * precision.
480 *
481 * If `clip` is not NULL then only points inside of the clipping rectangle are
482 * considered.
483 *
484 * \param points an array of SDL_FPoint structures representing points to be
485 * enclosed.
486 * \param count the number of structures in the `points` array.
487 * \param clip an SDL_FRect used for clipping or NULL to enclose all points.
488 * \param result an SDL_FRect structure filled in with the minimal enclosing
489 * rectangle.
490 * \returns true if any points were enclosed or false if all the points were
491 * outside of the clipping rectangle.
492 *
493 * \threadsafety It is safe to call this function from any thread.
494 *
495 * \since This function is available since SDL 3.2.0.
496 */
497extern SDL_DECLSPEC bool SDLCALL SDL_GetRectEnclosingPointsFloat(const SDL_FPoint *points, int count, const SDL_FRect *clip, SDL_FRect *result);
498
499/**
500 * Calculate the intersection of a rectangle and line segment with float
501 * precision.
502 *
503 * This function is used to clip a line segment to a rectangle. A line segment
504 * contained entirely within the rectangle or that does not intersect will
505 * remain unchanged. A line segment that crosses the rectangle at either or
506 * both ends will be clipped to the boundary of the rectangle and the new
507 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
508 *
509 * \param rect an SDL_FRect structure representing the rectangle to intersect.
510 * \param X1 a pointer to the starting X-coordinate of the line.
511 * \param Y1 a pointer to the starting Y-coordinate of the line.
512 * \param X2 a pointer to the ending X-coordinate of the line.
513 * \param Y2 a pointer to the ending Y-coordinate of the line.
514 * \returns true if there is an intersection, false otherwise.
515 *
516 * \threadsafety It is safe to call this function from any thread.
517 *
518 * \since This function is available since SDL 3.2.0.
519 */
520extern SDL_DECLSPEC bool SDLCALL SDL_GetRectAndLineIntersectionFloat(const SDL_FRect *rect, float *X1, float *Y1, float *X2, float *Y2);
521
522/* Ends C function definitions when using C++ */
523#ifdef __cplusplus
524}
525#endif
526#include <SDL3/SDL_close_code.h>
527
528#endif /* SDL_rect_h_ */
#define SDL_FORCE_INLINE
SDL_FORCE_INLINE void SDL_RectToFRect(const SDL_Rect *rect, SDL_FRect *frect)
Definition SDL_rect.h:129
bool SDL_GetRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result)
bool SDL_GetRectIntersection(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
bool SDL_GetRectEnclosingPoints(const SDL_Point *points, int count, const SDL_Rect *clip, SDL_Rect *result)
bool SDL_GetRectUnionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result)
bool SDL_HasRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B)
SDL_FORCE_INLINE bool SDL_RectEmptyFloat(const SDL_FRect *r)
Definition SDL_rect.h:355
SDL_FORCE_INLINE bool SDL_RectsEqualFloat(const SDL_FRect *a, const SDL_FRect *b)
Definition SDL_rect.h:420
SDL_FORCE_INLINE bool SDL_RectsEqual(const SDL_Rect *a, const SDL_Rect *b)
Definition SDL_rect.h:206
SDL_FORCE_INLINE bool SDL_RectEmpty(const SDL_Rect *r)
Definition SDL_rect.h:182
bool SDL_GetRectAndLineIntersectionFloat(const SDL_FRect *rect, float *X1, float *Y1, float *X2, float *Y2)
SDL_FORCE_INLINE bool SDL_PointInRectFloat(const SDL_FPoint *p, const SDL_FRect *r)
Definition SDL_rect.h:331
bool SDL_GetRectEnclosingPointsFloat(const SDL_FPoint *points, int count, const SDL_FRect *clip, SDL_FRect *result)
bool SDL_GetRectAndLineIntersection(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2)
SDL_FORCE_INLINE bool SDL_RectsEqualEpsilon(const SDL_FRect *a, const SDL_FRect *b, float epsilon)
Definition SDL_rect.h:385
bool SDL_GetRectUnion(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
SDL_FORCE_INLINE bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
Definition SDL_rect.h:158
bool SDL_HasRectIntersection(const SDL_Rect *A, const SDL_Rect *B)
#define true
Definition SDL_stdinc.h:101
#define SDL_static_cast(type, expression)
Definition SDL_stdinc.h:345
#define SDL_FLT_EPSILON
Definition SDL_stdinc.h:544
float SDL_fabsf(float x)
float x
Definition SDL_rect.h:65
float y
Definition SDL_rect.h:66
float h
Definition SDL_rect.h:114
float x
Definition SDL_rect.h:111
float w
Definition SDL_rect.h:113
float y
Definition SDL_rect.h:112
int h
Definition SDL_rect.h:86
int w
Definition SDL_rect.h:86
int y
Definition SDL_rect.h:85
int x
Definition SDL_rect.h:85