1 /********************************************************************************
2 * *
3 * R e c t a n g l e C l a s s *
4 * *
5 *********************************************************************************
6 * Copyright (C) 1994,2020 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as published by *
10 * the Free Software Foundation; either version 3 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/> *
20 ********************************************************************************/
21 #include "xincs.h"
22 #include "fxver.h"
23 #include "fxdefs.h"
24 #include "fxmath.h"
25 #include "FXArray.h"
26 #include "FXHash.h"
27 #include "FXStream.h"
28 #include "FXSize.h"
29 #include "FXPoint.h"
30 #include "FXRectangle.h"
31
32 using namespace FX;
33
34 /*******************************************************************************/
35
36 namespace FX {
37
38 // Fast inlines
_max(FXshort a,FXshort b)39 static inline FXshort _max(FXshort a,FXshort b){ return a>b?a:b; }
_min(FXshort a,FXshort b)40 static inline FXshort _min(FXshort a,FXshort b){ return a<b?a:b; }
41
42
43 // Grow by amount
grow(FXshort margin)44 FXRectangle& FXRectangle::grow(FXshort margin){
45 x-=margin;
46 y-=margin;
47 w+=(margin+margin);
48 h+=(margin+margin);
49 return *this;
50 }
51
52
53 // Grow by different amounts horizontally and vertically
grow(FXshort hormargin,FXshort vermargin)54 FXRectangle& FXRectangle::grow(FXshort hormargin,FXshort vermargin){
55 x-=hormargin;
56 y-=vermargin;
57 w+=(hormargin+hormargin);
58 h+=(vermargin+vermargin);
59 return *this;
60 }
61
62
63 // Grow by different amounts on all sides
grow(FXshort leftmargin,FXshort rightmargin,FXshort topmargin,FXshort bottommargin)64 FXRectangle& FXRectangle::grow(FXshort leftmargin,FXshort rightmargin,FXshort topmargin,FXshort bottommargin){
65 x-=leftmargin;
66 y-=topmargin;
67 w+=(leftmargin+rightmargin);
68 h+=(topmargin+bottommargin);
69 return *this;
70 }
71
72
73 // Shrink by amount
shrink(FXshort margin)74 FXRectangle& FXRectangle::shrink(FXshort margin){
75 x+=margin;
76 y+=margin;
77 w-=(margin+margin);
78 h-=(margin+margin);
79 return *this;
80 }
81
82
83 // Shrink by different amounts horizontally and vertically
shrink(FXshort hormargin,FXshort vermargin)84 FXRectangle& FXRectangle::shrink(FXshort hormargin,FXshort vermargin){
85 x+=hormargin;
86 y+=vermargin;
87 w-=(hormargin+hormargin);
88 h-=(vermargin+vermargin);
89 return *this;
90 }
91
92
93 // Shrink by different amounts on all sides
shrink(FXshort leftmargin,FXshort rightmargin,FXshort topmargin,FXshort bottommargin)94 FXRectangle& FXRectangle::shrink(FXshort leftmargin,FXshort rightmargin,FXshort topmargin,FXshort bottommargin){
95 x+=leftmargin;
96 y+=topmargin;
97 w-=(leftmargin+rightmargin);
98 h-=(topmargin+bottommargin);
99 return *this;
100 }
101
102
103 // Union with rectangle
operator +=(const FXRectangle & r)104 FXRectangle& FXRectangle::operator+=(const FXRectangle &r){
105 w=_max(x+w,r.x+r.w); x=_min(x,r.x); w-=x;
106 h=_max(y+h,r.y+r.h); y=_min(y,r.y); h-=y;
107 return *this;
108 }
109
110
111 // Intersection with rectangle
operator *=(const FXRectangle & r)112 FXRectangle& FXRectangle::operator*=(const FXRectangle &r){
113 w=_min(x+w,r.x+r.w); x=_max(x,r.x); w-=x;
114 h=_min(y+h,r.y+r.h); y=_max(y,r.y); h-=y;
115 return *this;
116 }
117
118
119 // Union between rectangles
operator +(const FXRectangle & r) const120 FXRectangle FXRectangle::operator+(const FXRectangle& r) const {
121 FXshort xx=_min(x,r.x);
122 FXshort ww=_max(x+w,r.x+r.w)-xx;
123 FXshort yy=_min(y,r.y);
124 FXshort hh=_max(y+h,r.y+r.h)-yy;
125 return FXRectangle(xx,yy,ww,hh);
126 }
127
128
129 // Intersection between rectangles
operator *(const FXRectangle & r) const130 FXRectangle FXRectangle::operator*(const FXRectangle& r) const {
131 FXshort xx=_max(x,r.x);
132 FXshort ww=_min(x+w,r.x+r.w)-xx;
133 FXshort yy=_max(y,r.y);
134 FXshort hh=_min(y+h,r.y+r.h)-yy;
135 return FXRectangle(xx,yy,ww,hh);
136 }
137
138
139 // Pieces of this rectangle after taking a bite out of it
bite(FXRectangle pieces[],const FXRectangle & b) const140 void FXRectangle::bite(FXRectangle pieces[],const FXRectangle& b) const {
141 pieces[0].x=pieces[1].x=x;
142 pieces[0].y=pieces[3].y=y;
143 pieces[2].w=pieces[3].w=x+w;
144 pieces[1].h=pieces[2].h=y+h;
145 pieces[1].w=pieces[2].x=b.x;
146 pieces[0].h=pieces[1].y=b.y;
147 pieces[0].w=pieces[3].x=b.x+b.w;
148 pieces[2].y=pieces[3].h=b.y+b.h;
149 if(pieces[1].w<pieces[1].x) pieces[1].w=pieces[2].x=pieces[1].x;
150 if(pieces[0].h<pieces[0].y) pieces[0].h=pieces[1].y=pieces[0].y;
151 if(pieces[3].x>pieces[3].w) pieces[3].x=pieces[0].w=pieces[3].w;
152 if(pieces[2].y>pieces[2].h) pieces[2].y=pieces[3].h=pieces[2].h;
153 if(pieces[1].w>pieces[3].x) pieces[1].w=pieces[2].x=pieces[3].x;
154 if(pieces[0].h>pieces[2].y) pieces[0].h=pieces[1].y=pieces[2].y;
155 if(pieces[3].x<pieces[1].w) pieces[3].x=pieces[0].w=pieces[1].w;
156 if(pieces[2].y<pieces[0].h) pieces[2].y=pieces[3].h=pieces[0].h;
157 pieces[0].w-=pieces[0].x;
158 pieces[0].h-=pieces[0].y;
159 pieces[1].w-=pieces[1].x;
160 pieces[1].h-=pieces[1].y;
161 pieces[2].w-=pieces[2].x;
162 pieces[2].h-=pieces[2].y;
163 pieces[3].w-=pieces[3].x;
164 pieces[3].h-=pieces[3].y;
165 }
166
167
168 // Save object to a stream
operator <<(FXStream & store,const FXRectangle & r)169 FXStream& operator<<(FXStream& store,const FXRectangle& r){
170 store << r.x << r.y << r.w << r.h;
171 return store;
172 }
173
174
175 // Load object from a stream
operator >>(FXStream & store,FXRectangle & r)176 FXStream& operator>>(FXStream& store,FXRectangle& r){
177 store >> r.x >> r.y >> r.w >> r.h;
178 return store;
179 }
180
181 }
182