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