SDL 3.0
SDL_rect.h
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2024 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 * interger 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.0.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.0.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.0.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, with the origin at the upper left (using floating point
92 * values).
93 *
94 * \since This struct is available since SDL 3.0.0.
95 *
96 * \sa SDL_RectEmptyFloat
97 * \sa SDL_RectsEqualFloat
98 * \sa SDL_RectsEqualEpsilon
99 * \sa SDL_HasRectIntersectionFloat
100 * \sa SDL_GetRectIntersectionFloat
101 * \sa SDL_GetRectAndLineIntersectionFloat
102 * \sa SDL_GetRectUnionFloat
103 * \sa SDL_GetRectEnclosingPointsFloat
104 * \sa SDL_PointInRectFloat
105 */
106typedef struct SDL_FRect
107{
108 float x;
109 float y;
110 float w;
111 float h;
112} SDL_FRect;
113
114
115/**
116 * Determine whether a point resides inside a rectangle.
117 *
118 * A point is considered part of a rectangle if both `p` and `r` are not NULL,
119 * and `p`'s x and y coordinates are >= to the rectangle's top left corner,
120 * and < the rectangle's x+w and y+h. So a 1x1 rectangle considers point (0,0)
121 * as "inside" and (0,1) as not.
122 *
123 * Note that this is a forced-inline function in a header, and not a public
124 * API function available in the SDL library (which is to say, the code is
125 * embedded in the calling program and the linker and dynamic loader will not
126 * be able to find this function inside SDL itself).
127 *
128 * \param p the point to test.
129 * \param r the rectangle to test.
130 * \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
131 *
132 * \threadsafety It is safe to call this function from any thread.
133 *
134 * \since This function is available since SDL 3.0.0.
135 */
137{
138 return ( p && r && (p->x >= r->x) && (p->x < (r->x + r->w)) &&
139 (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE;
140}
141
142/**
143 * Determine whether a rectangle has no area.
144 *
145 * A rectangle is considered "empty" for this function if `r` is NULL, or if
146 * `r`'s width and/or height are <= 0.
147 *
148 * Note that this is a forced-inline function in a header, and not a public
149 * API function available in the SDL library (which is to say, the code is
150 * embedded in the calling program and the linker and dynamic loader will not
151 * be able to find this function inside SDL itself).
152 *
153 * \param r the rectangle to test.
154 * \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
155 *
156 * \threadsafety It is safe to call this function from any thread.
157 *
158 * \since This function is available since SDL 3.0.0.
159 */
161{
162 return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE;
163}
164
165/**
166 * Determine whether two rectangles are equal.
167 *
168 * Rectangles are considered equal if both are not NULL and each of their x,
169 * y, width and height match.
170 *
171 * Note that this is a forced-inline function in a header, and not a public
172 * API function available in the SDL library (which is to say, the code is
173 * embedded in the calling program and the linker and dynamic loader will not
174 * be able to find this function inside SDL itself).
175 *
176 * \param a the first rectangle to test.
177 * \param b the second rectangle to test.
178 * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
179 *
180 * \threadsafety It is safe to call this function from any thread.
181 *
182 * \since This function is available since SDL 3.0.0.
183 */
185{
186 return (a && b && (a->x == b->x) && (a->y == b->y) &&
187 (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE;
188}
189
190/**
191 * Determine whether two rectangles intersect.
192 *
193 * If either pointer is NULL the function will return SDL_FALSE.
194 *
195 * \param A an SDL_Rect structure representing the first rectangle.
196 * \param B an SDL_Rect structure representing the second rectangle.
197 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
198 *
199 * \threadsafety It is safe to call this function from any thread.
200 *
201 * \since This function is available since SDL 3.0.0.
202 *
203 * \sa SDL_GetRectIntersection
204 */
205extern SDL_DECLSPEC SDL_bool SDLCALL SDL_HasRectIntersection(const SDL_Rect * A,
206 const SDL_Rect * B);
207
208/**
209 * Calculate the intersection of two rectangles.
210 *
211 * If `result` is NULL then this function will return SDL_FALSE.
212 *
213 * \param A an SDL_Rect structure representing the first rectangle.
214 * \param B an SDL_Rect structure representing the second rectangle.
215 * \param result an SDL_Rect structure filled in with the intersection of
216 * rectangles `A` and `B`.
217 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
218 *
219 * \since This function is available since SDL 3.0.0.
220 *
221 * \sa SDL_HasRectIntersection
222 */
223extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetRectIntersection(const SDL_Rect * A,
224 const SDL_Rect * B,
225 SDL_Rect * result);
226
227/**
228 * Calculate the union of two rectangles.
229 *
230 * \param A an SDL_Rect structure representing the first rectangle.
231 * \param B an SDL_Rect structure representing the second rectangle.
232 * \param result an SDL_Rect structure filled in with the union of rectangles
233 * `A` and `B`.
234 * \returns 0 on success or a negative error code on failure; call
235 * SDL_GetError() for more information.
236 *
237 * \since This function is available since SDL 3.0.0.
238 */
239extern SDL_DECLSPEC int SDLCALL SDL_GetRectUnion(const SDL_Rect * A,
240 const SDL_Rect * B,
241 SDL_Rect * result);
242
243/**
244 * Calculate a minimal rectangle enclosing a set of points.
245 *
246 * If `clip` is not NULL then only points inside of the clipping rectangle are
247 * considered.
248 *
249 * \param points an array of SDL_Point structures representing points to be
250 * enclosed.
251 * \param count the number of structures in the `points` array.
252 * \param clip an SDL_Rect used for clipping or NULL to enclose all points.
253 * \param result an SDL_Rect structure filled in with the minimal enclosing
254 * rectangle.
255 * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the
256 * points were outside of the clipping rectangle.
257 *
258 * \since This function is available since SDL 3.0.0.
259 */
260extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetRectEnclosingPoints(const SDL_Point * points,
261 int count,
262 const SDL_Rect * clip,
263 SDL_Rect * result);
264
265/**
266 * Calculate the intersection of a rectangle and line segment.
267 *
268 * This function is used to clip a line segment to a rectangle. A line segment
269 * contained entirely within the rectangle or that does not intersect will
270 * remain unchanged. A line segment that crosses the rectangle at either or
271 * both ends will be clipped to the boundary of the rectangle and the new
272 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
273 *
274 * \param rect an SDL_Rect structure representing the rectangle to intersect.
275 * \param X1 a pointer to the starting X-coordinate of the line.
276 * \param Y1 a pointer to the starting Y-coordinate of the line.
277 * \param X2 a pointer to the ending X-coordinate of the line.
278 * \param Y2 a pointer to the ending Y-coordinate of the line.
279 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
280 *
281 * \since This function is available since SDL 3.0.0.
282 */
283extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetRectAndLineIntersection(const SDL_Rect *
284 rect, int *X1,
285 int *Y1, int *X2,
286 int *Y2);
287
288
289/* SDL_FRect versions... */
290
291/**
292 * Determine whether a point resides inside a floating point rectangle.
293 *
294 * A point is considered part of a rectangle if both `p` and `r` are not NULL,
295 * and `p`'s x and y coordinates are >= to the rectangle's top left corner,
296 * and <= the rectangle's x+w and y+h. So a 1x1 rectangle considers point
297 * (0,0) and (0,1) as "inside" and (0,2) as not.
298 *
299 * Note that this is a forced-inline function in a header, and not a public
300 * API function available in the SDL library (which is to say, the code is
301 * embedded in the calling program and the linker and dynamic loader will not
302 * be able to find this function inside SDL itself).
303 *
304 * \param p the point to test.
305 * \param r the rectangle to test.
306 * \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
307 *
308 * \threadsafety It is safe to call this function from any thread.
309 *
310 * \since This function is available since SDL 3.0.0.
311 */
313{
314 return ( p && r && (p->x >= r->x) && (p->x <= (r->x + r->w)) &&
315 (p->y >= r->y) && (p->y <= (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE;
316}
317
318/**
319 * Determine whether a floating point rectangle can contain any point.
320 *
321 * A rectangle is considered "empty" for this function if `r` is NULL, or if
322 * `r`'s width and/or height are < 0.0f.
323 *
324 * Note that this is a forced-inline function in a header, and not a public
325 * API function available in the SDL library (which is to say, the code is
326 * embedded in the calling program and the linker and dynamic loader will not
327 * be able to find this function inside SDL itself).
328 *
329 * \param r the rectangle to test.
330 * \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
331 *
332 * \threadsafety It is safe to call this function from any thread.
333 *
334 * \since This function is available since SDL 3.0.0.
335 */
337{
338 return ((!r) || (r->w < 0.0f) || (r->h < 0.0f)) ? SDL_TRUE : SDL_FALSE;
339}
340
341/**
342 * Determine whether two floating point rectangles are equal, within some
343 * given epsilon.
344 *
345 * Rectangles are considered equal if both are not NULL and each of their x,
346 * y, width and height are within `epsilon` of each other. If you don't know
347 * what value to use for `epsilon`, you should call the SDL_RectsEqualFloat
348 * function instead.
349 *
350 * Note that this is a forced-inline function in a header, and not a public
351 * API function available in the SDL library (which is to say, the code is
352 * embedded in the calling program and the linker and dynamic loader will not
353 * be able to find this function inside SDL itself).
354 *
355 * \param a the first rectangle to test.
356 * \param b the second rectangle to test.
357 * \param epsilon the epsilon value for comparison.
358 * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
359 *
360 * \threadsafety It is safe to call this function from any thread.
361 *
362 * \since This function is available since SDL 3.0.0.
363 *
364 * \sa SDL_RectsEqualFloat
365 */
366SDL_FORCE_INLINE SDL_bool SDL_RectsEqualEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon)
367{
368 return (a && b && ((a == b) ||
369 ((SDL_fabsf(a->x - b->x) <= epsilon) &&
370 (SDL_fabsf(a->y - b->y) <= epsilon) &&
371 (SDL_fabsf(a->w - b->w) <= epsilon) &&
372 (SDL_fabsf(a->h - b->h) <= epsilon))))
374}
375
376/**
377 * Determine whether two floating point rectangles are equal, within a default
378 * epsilon.
379 *
380 * Rectangles are considered equal if both are not NULL and each of their x,
381 * y, width and height are within SDL_FLT_EPSILON of each other. This is often
382 * a reasonable way to compare two floating point rectangles and deal with the
383 * slight precision variations in floating point calculations that tend to pop
384 * up.
385 *
386 * Note that this is a forced-inline function in a header, and not a public
387 * API function available in the SDL library (which is to say, the code is
388 * embedded in the calling program and the linker and dynamic loader will not
389 * be able to find this function inside SDL itself).
390 *
391 * \param a the first rectangle to test.
392 * \param b the second rectangle to test.
393 * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
394 *
395 * \threadsafety It is safe to call this function from any thread.
396 *
397 * \since This function is available since SDL 3.0.0.
398 *
399 * \sa SDL_RectsEqualEpsilon
400 */
405
406/**
407 * Determine whether two rectangles intersect with float precision.
408 *
409 * If either pointer is NULL the function will return SDL_FALSE.
410 *
411 * \param A an SDL_FRect structure representing the first rectangle.
412 * \param B an SDL_FRect structure representing the second rectangle.
413 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
414 *
415 * \since This function is available since SDL 3.0.0.
416 *
417 * \sa SDL_GetRectIntersection
418 */
419extern SDL_DECLSPEC SDL_bool SDLCALL SDL_HasRectIntersectionFloat(const SDL_FRect * A,
420 const SDL_FRect * B);
421
422/**
423 * Calculate the intersection of two rectangles with float precision.
424 *
425 * If `result` is NULL then this function will return SDL_FALSE.
426 *
427 * \param A an SDL_FRect structure representing the first rectangle.
428 * \param B an SDL_FRect structure representing the second rectangle.
429 * \param result an SDL_FRect structure filled in with the intersection of
430 * rectangles `A` and `B`.
431 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
432 *
433 * \since This function is available since SDL 3.0.0.
434 *
435 * \sa SDL_HasRectIntersectionFloat
436 */
437extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetRectIntersectionFloat(const SDL_FRect * A,
438 const SDL_FRect * B,
439 SDL_FRect * result);
440
441/**
442 * Calculate the union of two rectangles with float precision.
443 *
444 * \param A an SDL_FRect structure representing the first rectangle.
445 * \param B an SDL_FRect structure representing the second rectangle.
446 * \param result an SDL_FRect structure filled in with the union of rectangles
447 * `A` and `B`.
448 * \returns 0 on success or a negative error code on failure; call
449 * SDL_GetError() for more information.
450 *
451 * \since This function is available since SDL 3.0.0.
452 */
453extern SDL_DECLSPEC int SDLCALL SDL_GetRectUnionFloat(const SDL_FRect * A,
454 const SDL_FRect * B,
455 SDL_FRect * result);
456
457/**
458 * Calculate a minimal rectangle enclosing a set of points with float
459 * precision.
460 *
461 * If `clip` is not NULL then only points inside of the clipping rectangle are
462 * considered.
463 *
464 * \param points an array of SDL_FPoint structures representing points to be
465 * enclosed.
466 * \param count the number of structures in the `points` array.
467 * \param clip an SDL_FRect used for clipping or NULL to enclose all points.
468 * \param result an SDL_FRect structure filled in with the minimal enclosing
469 * rectangle.
470 * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the
471 * points were outside of the clipping rectangle.
472 *
473 * \since This function is available since SDL 3.0.0.
474 */
475extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetRectEnclosingPointsFloat(const SDL_FPoint * points,
476 int count,
477 const SDL_FRect * clip,
478 SDL_FRect * result);
479
480/**
481 * Calculate the intersection of a rectangle and line segment with float
482 * precision.
483 *
484 * This function is used to clip a line segment to a rectangle. A line segment
485 * contained entirely within the rectangle or that does not intersect will
486 * remain unchanged. A line segment that crosses the rectangle at either or
487 * both ends will be clipped to the boundary of the rectangle and the new
488 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
489 *
490 * \param rect an SDL_FRect structure representing the rectangle to intersect.
491 * \param X1 a pointer to the starting X-coordinate of the line.
492 * \param Y1 a pointer to the starting Y-coordinate of the line.
493 * \param X2 a pointer to the ending X-coordinate of the line.
494 * \param Y2 a pointer to the ending Y-coordinate of the line.
495 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
496 *
497 * \since This function is available since SDL 3.0.0.
498 */
499extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetRectAndLineIntersectionFloat(const SDL_FRect *
500 rect, float *X1,
501 float *Y1, float *X2,
502 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_ */
#define SDL_FORCE_INLINE
SDL_bool SDL_GetRectEnclosingPoints(const SDL_Point *points, int count, const SDL_Rect *clip, SDL_Rect *result)
SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
Definition SDL_rect.h:136
int SDL_GetRectUnion(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
SDL_bool SDL_HasRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B)
SDL_bool SDL_GetRectAndLineIntersectionFloat(const SDL_FRect *rect, float *X1, float *Y1, float *X2, float *Y2)
SDL_FORCE_INLINE SDL_bool SDL_RectEmptyFloat(const SDL_FRect *r)
Definition SDL_rect.h:336
SDL_bool SDL_GetRectAndLineIntersection(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2)
SDL_FORCE_INLINE SDL_bool SDL_RectsEqualFloat(const SDL_FRect *a, const SDL_FRect *b)
Definition SDL_rect.h:401
SDL_FORCE_INLINE SDL_bool SDL_RectsEqual(const SDL_Rect *a, const SDL_Rect *b)
Definition SDL_rect.h:184
int SDL_GetRectUnionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result)
SDL_bool SDL_GetRectIntersectionFloat(const SDL_FRect *A, const SDL_FRect *B, SDL_FRect *result)
SDL_bool SDL_HasRectIntersection(const SDL_Rect *A, const SDL_Rect *B)
SDL_bool SDL_GetRectIntersection(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
Definition SDL_rect.h:160
SDL_bool SDL_GetRectEnclosingPointsFloat(const SDL_FPoint *points, int count, const SDL_FRect *clip, SDL_FRect *result)
SDL_FORCE_INLINE SDL_bool SDL_RectsEqualEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon)
Definition SDL_rect.h:366
SDL_FORCE_INLINE SDL_bool SDL_PointInRectFloat(const SDL_FPoint *p, const SDL_FRect *r)
Definition SDL_rect.h:312
#define SDL_TRUE
Definition SDL_stdinc.h:203
#define SDL_FALSE
Definition SDL_stdinc.h:194
int SDL_bool
Definition SDL_stdinc.h:213
#define SDL_FLT_EPSILON
Definition SDL_stdinc.h:327
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:111
float x
Definition SDL_rect.h:108
float w
Definition SDL_rect.h:110
float y
Definition SDL_rect.h:109
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