1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup GHOST
22  */
23 
24 #include "GHOST_Rect.h"
25 
inset(GHOST_TInt32 i)26 void GHOST_Rect::inset(GHOST_TInt32 i)
27 {
28   if (i > 0) {
29     // Grow the rectangle
30     m_l -= i;
31     m_r += i;
32     m_t -= i;
33     m_b += i;
34   }
35   else if (i < 0) {
36     // Shrink the rectangle, check for insets larger than half the size
37     GHOST_TInt32 i2 = i * 2;
38     if (getWidth() > i2) {
39       m_l += i;
40       m_r -= i;
41     }
42     else {
43       m_l = m_l + ((m_r - m_l) / 2);
44       m_r = m_l;
45     }
46     if (getHeight() > i2) {
47       m_t += i;
48       m_b -= i;
49     }
50     else {
51       m_t = m_t + ((m_b - m_t) / 2);
52       m_b = m_t;
53     }
54   }
55 }
56 
getVisibility(GHOST_Rect & r) const57 GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect &r) const
58 {
59   bool lt = isInside(r.m_l, r.m_t);
60   bool rt = isInside(r.m_r, r.m_t);
61   bool lb = isInside(r.m_l, r.m_b);
62   bool rb = isInside(r.m_r, r.m_b);
63   GHOST_TVisibility v;
64   if (lt && rt && lb && rb) {
65     // All points inside, rectangle is inside this
66     v = GHOST_kFullyVisible;
67   }
68   else if (!(lt || rt || lb || rb)) {
69     // None of the points inside
70     // Check to see whether the rectangle is larger than this one
71     if ((r.m_l < m_l) && (r.m_t < m_t) && (r.m_r > m_r) && (r.m_b > m_b)) {
72       v = GHOST_kPartiallyVisible;
73     }
74     else {
75       v = GHOST_kNotVisible;
76     }
77   }
78   else {
79     // Some of the points inside, rectangle is partially inside
80     v = GHOST_kPartiallyVisible;
81   }
82   return v;
83 }
84 
setCenter(GHOST_TInt32 cx,GHOST_TInt32 cy)85 void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy)
86 {
87   GHOST_TInt32 offset = cx - (m_l + (m_r - m_l) / 2);
88   m_l += offset;
89   m_r += offset;
90   offset = cy - (m_t + (m_b - m_t) / 2);
91   m_t += offset;
92   m_b += offset;
93 }
94 
setCenter(GHOST_TInt32 cx,GHOST_TInt32 cy,GHOST_TInt32 w,GHOST_TInt32 h)95 void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h)
96 {
97   long w_2, h_2;
98 
99   w_2 = w >> 1;
100   h_2 = h >> 1;
101   m_l = cx - w_2;
102   m_t = cy - h_2;
103   m_r = m_l + w;
104   m_b = m_t + h;
105 }
106 
clip(GHOST_Rect & r) const107 bool GHOST_Rect::clip(GHOST_Rect &r) const
108 {
109   bool clipped = false;
110   if (r.m_l < m_l) {
111     r.m_l = m_l;
112     clipped = true;
113   }
114   if (r.m_t < m_t) {
115     r.m_t = m_t;
116     clipped = true;
117   }
118   if (r.m_r > m_r) {
119     r.m_r = m_r;
120     clipped = true;
121   }
122   if (r.m_b > m_b) {
123     r.m_b = m_b;
124     clipped = true;
125   }
126   return clipped;
127 }
128