1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Basic classes for rectangles and vertex outlines */
19 
20 #ifndef INC_C4Rect
21 #define INC_C4Rect
22 
23 #define C4D_VertexCpyPos (C4D_MaxVertex/2)
24 
25 struct FLOAT_RECT { float left,right,top,bottom; };
26 
27 class C4Rect
28 {
29 public:
30 	int32_t x = 0, y = 0, Wdt = 0, Hgt = 0;
31 public:
32 	void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt);
33 	void Default();
34 	bool Overlap(C4Rect &rTarget);
35 	void Intersect(const C4Rect &r2);
36 	void Add(const C4Rect &r2);
37 	bool operator ==(const C4Rect &r2) const { return !((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); }
38 	bool operator !=(const C4Rect &r2) const { return 0 != ((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); }
39 
Contains(int32_t iX,int32_t iY)40 	bool Contains(int32_t iX, int32_t iY) const
41 	{ return iX>=x && iX<x+Wdt && iY>=y && iY<y+Hgt; }
Contains(int32_t iX,int32_t iY,int32_t iWdt,int32_t iHgt)42 	bool Contains(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt) const
43 	{ return iX>=x && iX+iWdt<x+Wdt && iY>=y && iY+iHgt<y+Hgt; }
Contains(const C4Rect & rect)44 	bool Contains(const C4Rect &rect) const
45 	{ return Contains(rect.x, rect.y, rect.Wdt, rect.Hgt); }
46 	bool IntersectsLine(int32_t iX, int32_t iY, int32_t iX2, int32_t iY2);
47 
Normalize()48 	void Normalize()
49 	{ if (Wdt < 0) { x+=Wdt+1; Wdt=-Wdt; } if (Hgt < 0) { y+=Hgt+1; Hgt=-Hgt; } }
50 
Enlarge(int32_t iByX,int32_t iByY)51 	void Enlarge(int32_t iByX, int32_t iByY)
52 	{ x -= iByX; y -= iByY; Wdt += 2*iByX; Hgt += 2*iByY; }
Enlarge(int32_t iBy)53 	void Enlarge(int32_t iBy)
54 	{ Enlarge(iBy, iBy); }
55 
GetMiddleX()56 	int32_t GetMiddleX() const { return x+Wdt/2; }
GetMiddleY()57 	int32_t GetMiddleY() const { return y + Hgt / 2; }
GetBottom()58 	int32_t GetBottom() const { return y + Hgt; }
GetTop()59 	int32_t GetTop() const { return y; }
GetLeft()60 	int32_t GetLeft() const { return x; }
GetRight()61 	int32_t GetRight() const { return x + Wdt; }
62 
63 	C4Rect() = default;
C4Rect(int32_t tx,int32_t ty,int32_t twdt,int32_t thgt)64 	C4Rect(int32_t tx, int32_t ty, int32_t twdt, int32_t thgt) // ctor
65 	{ x=tx; y=ty; Wdt=twdt; Hgt=thgt; }
C4Rect(const FLOAT_RECT & rcfOuter)66 	C4Rect(const FLOAT_RECT &rcfOuter) // set to surround floating point rectangle
67 	{
68 		x=static_cast<int32_t>(rcfOuter.left); y=static_cast<int32_t>(rcfOuter.top);
69 		Wdt=static_cast<int32_t>(ceilf(rcfOuter.right)-floorf(rcfOuter.left));
70 		Hgt=static_cast<int32_t>(ceilf(rcfOuter.bottom)-floorf(rcfOuter.top));
71 	}
72 
73 	void CompileFunc(StdCompiler *pComp);
74 };
75 
76 class C4TargetRect: public C4Rect
77 {
78 public:
79 	int32_t tx,ty;
80 public:
C4TargetRect(int32_t iX,int32_t iY,int32_t iWdt,int32_t iHgt,int32_t iTX,int32_t iTY)81 	C4TargetRect(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY)
82 			: C4Rect(iX, iY, iWdt, iHgt), tx(iTX), ty(iTY) { }
83 	C4TargetRect() = default; // default ctor; doesn't initialize
84 	void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY);
85 	void Default();
86 	bool ClipBy(C4TargetRect &rClip); // clip this rectangle by the given one (adding target positions) - return false if they don't overlap
87 
88 	void Set(const C4TargetFacet &rSrc); // copy contents from facet
89 
90 	void CompileFunc(StdCompiler *pComp);
91 };
92 
93 const C4Rect Rect0(0,0,0,0);
94 const C4TargetRect TargetRect0(0,0,0,0,0,0);
95 
96 // a bunch of rectangles
97 // rects NOT including pos+size-point
98 class C4RectList : public std::vector<C4Rect>
99 {
100 public:
AddRect(const C4Rect & rNewRect)101 	void AddRect(const C4Rect &rNewRect)
102 	{ push_back(rNewRect); }
RemoveIndexedRect(int32_t idx)103 	void RemoveIndexedRect(int32_t idx)
104 	{ if (idx<int32_t(GetCount()-1)) Get(idx)=Get(GetCount()-1); pop_back(); }
Clear()105 	void Clear() { clear(); }
GetCount()106 	size_t GetCount() const { return size(); }
Get(size_t idx)107 	C4Rect &Get(size_t idx) { return (*this)[idx]; } // access w/o range check
108 
109 	void ClipByRect(const C4Rect &rClip); // split up rectangles
110 };
111 
112 
113 #endif // INC_C4Rect
114