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 * Header file for SDL_rect definition and management functions.
26 */
27
28#ifndef SDL_rect_h_
29#define SDL_rect_h_
30
31#include "SDL_stdinc.h"
32#include "SDL_error.h"
33#include "SDL_pixels.h"
34#include "SDL_rwops.h"
35
36#include "begin_code.h"
37/* Set up for C function definitions, even when using C++ */
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/**
43 * The structure that defines a point (integer)
44 *
45 * \sa SDL_EnclosePoints
46 * \sa SDL_PointInRect
47 */
48typedef struct SDL_Point
49{
50 int x;
51 int y;
52} SDL_Point;
53
54/**
55 * The structure that defines a point (floating point)
56 *
57 * \sa SDL_EncloseFPoints
58 * \sa SDL_PointInFRect
59 */
60typedef struct SDL_FPoint
61{
62 float x;
63 float y;
64} SDL_FPoint;
65
66
67/**
68 * A rectangle, with the origin at the upper left (integer).
69 *
70 * \sa SDL_RectEmpty
71 * \sa SDL_RectEquals
72 * \sa SDL_HasIntersection
73 * \sa SDL_IntersectRect
74 * \sa SDL_IntersectRectAndLine
75 * \sa SDL_UnionRect
76 * \sa SDL_EnclosePoints
77 */
78typedef struct SDL_Rect
79{
80 int x, y;
81 int w, h;
82} SDL_Rect;
83
84
85/**
86 * A rectangle, with the origin at the upper left (floating point).
87 *
88 * \sa SDL_FRectEmpty
89 * \sa SDL_FRectEquals
90 * \sa SDL_FRectEqualsEpsilon
91 * \sa SDL_HasIntersectionF
92 * \sa SDL_IntersectFRect
93 * \sa SDL_IntersectFRectAndLine
94 * \sa SDL_UnionFRect
95 * \sa SDL_EncloseFPoints
96 * \sa SDL_PointInFRect
97 */
98typedef struct SDL_FRect
99{
100 float x;
101 float y;
102 float w;
103 float h;
104} SDL_FRect;
105
106
107/**
108 * Returns true if point resides inside a rectangle.
109 *
110 * \param p the point to test.
111 * \param r the rectangle to test.
112 * \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
113 */
114SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r)
115{
116 return ( (p->x >= r->x) && (p->x < (r->x + r->w)) &&
117 (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE;
118}
119
120/**
121 * Returns true if the rectangle has no area.
122 *
123 * \param r the rectangle to test.
124 * \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
125 */
126SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
127{
128 return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE;
129}
130
131/**
132 * Returns true if the two rectangles are equal.
133 *
134 * \param a the first rectangle to test.
135 * \param b the second rectangle to test.
136 * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
137 */
138SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b)
139{
140 return (a && b && (a->x == b->x) && (a->y == b->y) &&
141 (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE;
142}
143
144/**
145 * Determine whether two rectangles intersect.
146 *
147 * If either pointer is NULL the function will return SDL_FALSE.
148 *
149 * \param A an SDL_Rect structure representing the first rectangle.
150 * \param B an SDL_Rect structure representing the second rectangle.
151 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
152 *
153 * \since This function is available since SDL 2.0.0.
154 *
155 * \sa SDL_IntersectRect
156 */
157extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A,
158 const SDL_Rect * B);
159
160/**
161 * Calculate the intersection of two rectangles.
162 *
163 * If `result` is NULL then this function will return SDL_FALSE.
164 *
165 * \param A an SDL_Rect structure representing the first rectangle.
166 * \param B an SDL_Rect structure representing the second rectangle.
167 * \param result an SDL_Rect structure filled in with the intersection of
168 * rectangles `A` and `B`.
169 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
170 *
171 * \since This function is available since SDL 2.0.0.
172 *
173 * \sa SDL_HasIntersection
174 */
175extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A,
176 const SDL_Rect * B,
177 SDL_Rect * result);
178
179/**
180 * Calculate the union of two rectangles.
181 *
182 * \param A an SDL_Rect structure representing the first rectangle.
183 * \param B an SDL_Rect structure representing the second rectangle.
184 * \param result an SDL_Rect structure filled in with the union of rectangles
185 * `A` and `B`.
186 *
187 * \since This function is available since SDL 2.0.0.
188 */
189extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A,
190 const SDL_Rect * B,
191 SDL_Rect * result);
192
193/**
194 * Calculate a minimal rectangle enclosing a set of points.
195 *
196 * If `clip` is not NULL then only points inside of the clipping rectangle are
197 * considered.
198 *
199 * \param points an array of SDL_Point structures representing points to be
200 * enclosed.
201 * \param count the number of structures in the `points` array.
202 * \param clip an SDL_Rect used for clipping or NULL to enclose all points.
203 * \param result an SDL_Rect structure filled in with the minimal enclosing
204 * rectangle.
205 * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the
206 * points were outside of the clipping rectangle.
207 *
208 * \since This function is available since SDL 2.0.0.
209 */
210extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points,
211 int count,
212 const SDL_Rect * clip,
213 SDL_Rect * result);
214
215/**
216 * Calculate the intersection of a rectangle and line segment.
217 *
218 * This function is used to clip a line segment to a rectangle. A line segment
219 * contained entirely within the rectangle or that does not intersect will
220 * remain unchanged. A line segment that crosses the rectangle at either or
221 * both ends will be clipped to the boundary of the rectangle and the new
222 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
223 *
224 * \param rect an SDL_Rect structure representing the rectangle to intersect.
225 * \param X1 a pointer to the starting X-coordinate of the line.
226 * \param Y1 a pointer to the starting Y-coordinate of the line.
227 * \param X2 a pointer to the ending X-coordinate of the line.
228 * \param Y2 a pointer to the ending Y-coordinate of the line.
229 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
230 *
231 * \since This function is available since SDL 2.0.0.
232 */
233extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect *
234 rect, int *X1,
235 int *Y1, int *X2,
236 int *Y2);
237
238
239/* SDL_FRect versions... */
240
241/**
242 * Returns true if point resides inside a rectangle.
243 *
244 * \param p the point to test.
245 * \param r the rectangle to test.
246 * \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise.
247 */
248SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect *r)
249{
250 return ( (p->x >= r->x) && (p->x < (r->x + r->w)) &&
251 (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE;
252}
253
254/**
255 * Returns true if the rectangle has no area.
256 *
257 * \param r the rectangle to test.
258 * \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise.
259 */
260SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
261{
262 return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE;
263}
264
265/**
266 * Returns true if the two rectangles are equal, within some given epsilon.
267 *
268 * \param a the first rectangle to test.
269 * \param b the second rectangle to test.
270 * \param epsilon the epsilon value for comparison.
271 * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
272 *
273 * \since This function is available since SDL 2.0.22.
274 */
275SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon)
276{
277 return (a && b && ((a == b) ||
278 ((SDL_fabsf(x: a->x - b->x) <= epsilon) &&
279 (SDL_fabsf(x: a->y - b->y) <= epsilon) &&
280 (SDL_fabsf(x: a->w - b->w) <= epsilon) &&
281 (SDL_fabsf(x: a->h - b->h) <= epsilon))))
282 ? SDL_TRUE : SDL_FALSE;
283}
284
285/**
286 * Returns true if the two rectangles are equal, using a default epsilon.
287 *
288 * \param a the first rectangle to test.
289 * \param b the second rectangle to test.
290 * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise.
291 *
292 * \since This function is available since SDL 2.0.22.
293 */
294SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b)
295{
296 return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON);
297}
298
299/**
300 * Determine whether two rectangles intersect with float precision.
301 *
302 * If either pointer is NULL the function will return SDL_FALSE.
303 *
304 * \param A an SDL_FRect structure representing the first rectangle.
305 * \param B an SDL_FRect structure representing the second rectangle.
306 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
307 *
308 * \since This function is available since SDL 2.0.22.
309 *
310 * \sa SDL_IntersectRect
311 */
312extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersectionF(const SDL_FRect * A,
313 const SDL_FRect * B);
314
315/**
316 * Calculate the intersection of two rectangles with float precision.
317 *
318 * If `result` is NULL then this function will return SDL_FALSE.
319 *
320 * \param A an SDL_FRect structure representing the first rectangle.
321 * \param B an SDL_FRect structure representing the second rectangle.
322 * \param result an SDL_FRect structure filled in with the intersection of
323 * rectangles `A` and `B`.
324 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
325 *
326 * \since This function is available since SDL 2.0.22.
327 *
328 * \sa SDL_HasIntersectionF
329 */
330extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRect(const SDL_FRect * A,
331 const SDL_FRect * B,
332 SDL_FRect * result);
333
334/**
335 * Calculate the union of two rectangles with float precision.
336 *
337 * \param A an SDL_FRect structure representing the first rectangle.
338 * \param B an SDL_FRect structure representing the second rectangle.
339 * \param result an SDL_FRect structure filled in with the union of rectangles
340 * `A` and `B`.
341 *
342 * \since This function is available since SDL 2.0.22.
343 */
344extern DECLSPEC void SDLCALL SDL_UnionFRect(const SDL_FRect * A,
345 const SDL_FRect * B,
346 SDL_FRect * result);
347
348/**
349 * Calculate a minimal rectangle enclosing a set of points with float
350 * precision.
351 *
352 * If `clip` is not NULL then only points inside of the clipping rectangle are
353 * considered.
354 *
355 * \param points an array of SDL_FPoint structures representing points to be
356 * enclosed.
357 * \param count the number of structures in the `points` array.
358 * \param clip an SDL_FRect used for clipping or NULL to enclose all points.
359 * \param result an SDL_FRect structure filled in with the minimal enclosing
360 * rectangle.
361 * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the
362 * points were outside of the clipping rectangle.
363 *
364 * \since This function is available since SDL 2.0.22.
365 */
366extern DECLSPEC SDL_bool SDLCALL SDL_EncloseFPoints(const SDL_FPoint * points,
367 int count,
368 const SDL_FRect * clip,
369 SDL_FRect * result);
370
371/**
372 * Calculate the intersection of a rectangle and line segment with float
373 * precision.
374 *
375 * This function is used to clip a line segment to a rectangle. A line segment
376 * contained entirely within the rectangle or that does not intersect will
377 * remain unchanged. A line segment that crosses the rectangle at either or
378 * both ends will be clipped to the boundary of the rectangle and the new
379 * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
380 *
381 * \param rect an SDL_FRect structure representing the rectangle to intersect.
382 * \param X1 a pointer to the starting X-coordinate of the line.
383 * \param Y1 a pointer to the starting Y-coordinate of the line.
384 * \param X2 a pointer to the ending X-coordinate of the line.
385 * \param Y2 a pointer to the ending Y-coordinate of the line.
386 * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
387 *
388 * \since This function is available since SDL 2.0.22.
389 */
390extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRectAndLine(const SDL_FRect *
391 rect, float *X1,
392 float *Y1, float *X2,
393 float *Y2);
394
395/* Ends C function definitions when using C++ */
396#ifdef __cplusplus
397}
398#endif
399#include "close_code.h"
400
401#endif /* SDL_rect_h_ */
402
403/* vi: set ts=4 sw=4 expandtab: */
404