1 /+
2 +            Copyright 2022 – 2023 Aya Partridge
3 +          Copyright 2018 - 2022 Michael D. Parker
4 + Distributed under the Boost Software License, Version 1.0.
5 +     (See accompanying file LICENSE_1_0.txt or copy at
6 +           http://www.boost.org/LICENSE_1_0.txt)
7 +/
8 module sdl.rect;
9 
10 import bindbc.sdl.config;
11 import bindbc.sdl.codegen;
12 
13 import sdl.stdinc;
14 
15 struct SDL_Point{
16 	int x;
17 	int y;
18 }
19 
20 struct SDL_Rect{
21 	int x, y;
22 	int w, h;
23 }
24 
25 static if(sdlSupport >= SDLSupport.v2_0_10){
26 	struct SDL_FPoint{
27 		float x, y;
28 	}
29 
30 	struct SDL_FRect{
31 		float x, y;
32 		float w, h;
33 	}
34 }
35 
36 pragma(inline, true) @nogc nothrow pure{
37 	// This macro was added to SDL_rect.h in 2.0.4, but hurts nothing to implement for all versions.
38 	bool SDL_PointInRect(const(SDL_Point)* p, const(SDL_Rect)* r){
39 		return (
40 			(p.x >= r.x) && (p.x < (r.x + r.w)) &&
41 			(p.y >= r.y) && (p.y < (r.y + r.h))
42 		);
43 	}
44 	bool SDL_RectEmpty(const(SDL_Rect)* r){
45 		return !r || (r.w <= 0) || (r.h <= 0);
46 	}
47 	bool SDL_RectEquals(const(SDL_Rect)* a, const(SDL_Rect)* b){
48 		return a && b &&
49 			(a.x == b.x) && (a.y == b.y) &&
50 			(a.w == b.w) && (a.h == b.h);
51 	}
52 	static if(sdlSupport >= SDLSupport.v2_0_22){
53 		bool SDL_PointInFRect(const(SDL_FPoint)* p, const(SDL_FRect)* r){
54 			return (
55 				(p.x >= r.x) && (p.x < (r.x + r.w)) &&
56 				(p.y >= r.y) && (p.y < (r.y + r.h))
57 			);
58 		}
59 		bool SDL_FRectEmpty(const(SDL_FRect)* x){
60 			return !x || (x.w <= 0) || (x.h <= 0);
61 		}
62 		bool SDL_FRectEqualsEpsilon(const(SDL_FRect)* a, const(SDL_FRect)* b, const float epsilon){
63 			import core.math: fabs;
64 			return a && b && ((a == b) ||
65 				(fabs(a.x - b.x) <= epsilon) && (fabs(a.y - b.y) <= epsilon) &&
66 				(fabs(a.w - b.w) <= epsilon) && (fabs(a.h - b.h) <= epsilon));
67 		}
68 		bool SDL_FRectEquals(const(SDL_FRect)* a, const(SDL_FRect)* b){
69 			return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON);
70 		}
71 	}
72 }
73 
74 mixin(joinFnBinds((){
75 	string[][] ret;
76 	ret ~= makeFnBinds([
77 		[q{SDL_bool}, q{SDL_HasIntersection}, q{const(SDL_Rect)* A, const(SDL_Rect)* B}],
78 		[q{SDL_bool}, q{SDL_IntersectRect}, q{const(SDL_Rect)* A, const(SDL_Rect)* B,SDL_Rect* result}],
79 		[q{void}, q{SDL_UnionRect}, q{const(SDL_Rect)* A, const(SDL_Rect)* B, SDL_Rect* result}],
80 		[q{SDL_bool}, q{SDL_EnclosePoints}, q{const(SDL_Point)* points, int count, const(SDL_Rect)* clip, SDL_Rect* result}],
81 		[q{SDL_bool}, q{SDL_IntersectRectAndLine}, q{const(SDL_Rect)* rect, int* X1, int* Y1, int* X2, int* Y2}],
82 	]);
83 	static if(sdlSupport >= SDLSupport.v2_0_22){
84 		ret ~= makeFnBinds([
85 			[q{SDL_bool}, q{SDL_HasIntersectionF}, q{const(SDL_FRect)* A, const(SDL_FRect)* B}],
86 			[q{SDL_bool}, q{SDL_IntersectFRect}, q{const(SDL_FRect)* A, const(SDL_FRect)* B, SDL_FRect* result}],
87 			[q{SDL_bool}, q{SDL_UnionFRect}, q{const(SDL_FRect)* A, const(SDL_FRect)* B, SDL_FRect* result}],
88 			[q{SDL_bool}, q{SDL_EncloseFPoints}, q{const(SDL_FPoint)* points, int count, const(SDL_FRect)* clip, SDL_FRect* result}],
89 			[q{SDL_bool}, q{SDL_IntersectFRectAndLine}, q{const(SDL_FRect)* rect, float* X1, float* Y1, float* X2, float* Y2}],
90 		]);
91 	}
92 	return ret;
93 }()));