blob: e98913a57c7161b0a582ce7971b0dfb41d453759 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#ifndef GrRect_DEFINED
19#define GrRect_DEFINED
20
21#include "GrPoint.h"
22
23struct GrIRect {
24 int32_t fLeft, fTop, fRight, fBottom;
25
26 GrIRect() {}
27 GrIRect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
28 fLeft = left;
29 fTop = top;
30 fRight = right;
31 fBottom = bottom;
32 }
33
34 int32_t x() const { return fLeft; }
35 int32_t y() const { return fTop; }
36 int32_t width() const { return fRight - fLeft; }
37 int32_t height() const { return fBottom - fTop; }
38
39 bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
40 bool isInverted() const { return fLeft > fRight || fTop > fBottom; }
41
42 void setEmpty() { fLeft = fTop = fRight = fBottom = 0; }
43
44 void setXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
45 fLeft = x;
46 fTop = y;
47 fRight = x + w;
48 fBottom = y + h;
49 }
50
51 void setLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
52 fLeft = l;
53 fTop = t;
54 fRight = r;
55 fBottom = b;
56 }
57
58 /**
59 * Make the largest representable rectangle
60
61 */
62 void setLargest() {
63 fLeft = fTop = GR_Int32Min;
64 fRight = fBottom = GR_Int32Max;
65 }
66
67 bool quickReject(int l, int t, int r, int b) const {
68 return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
69 }
70
71 void unionWith(const GrIRect& r) {
72 if (fLeft > r.fLeft) fLeft = r.fLeft;
73 if (fTop > r.fTop) fTop = r.fTop;
74 if (fRight < r.fRight) fRight = r.fRight;
75 if (fBottom < r.fBottom) fBottom = r.fBottom;
76 }
77
78 friend bool operator==(const GrIRect& a, const GrIRect& b) {
79 return 0 == memcmp(&a, &b, sizeof(a));
80 }
81
82 friend bool operator!=(const GrIRect& a, const GrIRect& b) {
83 return 0 != memcmp(&a, &b, sizeof(a));
84 }
85
86 bool equalsLTRB(int l, int t, int r, int b) const {
87 return fLeft == l && fTop == t &&
88 fRight == r && fBottom == b;
89 }
90 bool equalsXYWH(int x, int y, int w, int h) const {
91 return fLeft == x && fTop == y &&
92 this->width() == w && this->height() == h;
93 }
94
95 bool contains(const GrIRect& r) const {
96 return fLeft <= r.fLeft &&
97 fRight >= r.fRight &&
98 fTop <= r.fTop &&
99 fBottom >= r.fBottom;
100 }
101};
102
103struct GrIRect16 {
104 int16_t fLeft, fTop, fRight, fBottom;
105
106 int width() const { return fRight - fLeft; }
107 int height() const { return fBottom - fTop; }
108 int area() const { return this->width() * this->height(); }
109 bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
110
111 void set(const GrIRect& r) {
112 fLeft = GrToS16(r.fLeft);
113 fTop = GrToS16(r.fTop);
114 fRight = GrToS16(r.fRight);
115 fBottom = GrToS16(r.fBottom);
116 }
117};
118
119/**
120 * 2D Rect struct
121 */
122struct GrRect {
123 GrScalar fLeft, fTop, fRight, fBottom;
124
125 /**
126 * Uninitialized rectangle.
127 */
128 GrRect() {}
129
130 /**
131 * Initialize a rectangle to a point.
132 * @param pt the point used to initialize the rectanglee.
133 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000134 explicit GrRect(const GrPoint& pt) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000135 setToPoint(pt);
136 }
137
138 GrRect(GrScalar left, GrScalar top, GrScalar right, GrScalar bottom) {
139 fLeft = left;
140 fTop = top;
141 fRight = right;
142 fBottom = bottom;
143 }
144
145 explicit GrRect(const GrIRect& src) {
146 fLeft = GrIntToScalar(src.fLeft);
147 fTop = GrIntToScalar(src.fTop);
148 fRight = GrIntToScalar(src.fRight);
149 fBottom = GrIntToScalar(src.fBottom);
150 }
151
152 GrScalar x() const { return fLeft; }
153 GrScalar y() const { return fTop; }
154 GrScalar width() const { return fRight - fLeft; }
155 GrScalar height() const { return fBottom - fTop; }
156
157 GrScalar left() const { return fLeft; }
158 GrScalar top() const { return fTop; }
159 GrScalar right() const { return fRight; }
160 GrScalar bottom() const { return fBottom; }
161
162 GrScalar diagonalLengthSqd() const {
163 GrScalar w = width();
164 GrScalar h = height();
165 return GrMul(w, w) + GrMul(h, h);
166 }
167
168 GrScalar diagonalLength() const {
169 // TODO: fixed point sqrt
170 return GrFloatToScalar(sqrtf(GrScalarToFloat(diagonalLengthSqd())));
171 }
172
173 /**
174 * Returns true if the width or height is <= 0
175 */
176 bool isEmpty() const {
177 return fLeft >= fRight || fTop >= fBottom;
178 }
179
180 void setEmpty() {
181 fLeft = fTop = fRight = fBottom = 0;
182 }
183
184 /**
185 * returns true if the rectangle is inverted either in x or y
186 */
187 bool isInverted() const {
188 return (fLeft > fRight) || (fTop > fBottom);
189 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000190
191 bool contains(const GrPoint& point) const {
192 return point.fX >= fLeft && point.fX < fRight &&
193 point.fY >= fTop && point.fY < fBottom;
194 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000195
196 /**
197 * Initialize a rectangle to a point.
198 * @param pt the point used to initialize the rectangle.
199 */
200 void setToPoint(const GrPoint& pt) {
201 fLeft = pt.fX;
202 fTop = pt.fY;
203 fRight = pt.fX;
204 fBottom = pt.fY;
205 }
206
207 void set(const GrIRect& r) {
208 fLeft = GrIntToScalar(r.fLeft);
209 fTop = GrIntToScalar(r.fTop);
210 fRight = GrIntToScalar(r.fRight);
211 fBottom = GrIntToScalar(r.fBottom);
212 }
213
214 void roundOut(GrIRect* r) const {
215 r->setLTRB(GrScalarFloorToInt(fLeft),
216 GrScalarFloorToInt(fTop),
217 GrScalarCeilToInt(fRight),
218 GrScalarCeilToInt(fBottom));
219 }
220
221 /**
222 * Set the rect to the union of the array of points. If the array is empty
223 * the rect will be empty [0,0,0,0]
224 */
225 void setBounds(const GrPoint pts[], int count);
226
227 /**
228 * Make the largest representable rectangle
229 * Set the rect to fLeft = fTop = GR_ScalarMin and
230 * fRight = fBottom = GR_ScalarMax.
231 */
232 void setLargest() {
233 fLeft = fTop = GR_ScalarMin;
234 fRight = fBottom = GR_ScalarMax;
235 }
236
237 /**
238 Set the rect to fLeft = fTop = GR_ScalarMax and
239 fRight = fBottom = GR_ScalarMin.
240 Useful for initializing a bounding rectangle.
241 */
242 void setLargestInverted() {
243 fLeft = fTop = GR_ScalarMax;
244 fRight = fBottom = GR_ScalarMin;
245 }
246
247 void setLTRB(GrScalar left,
248 GrScalar top,
249 GrScalar right,
250 GrScalar bottom) {
251 fLeft = left;
252 fTop = top;
253 fRight = right;
254 fBottom = bottom;
255 }
256
257 void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
258 fLeft = x;
259 fTop = y;
260 fRight = x + width;
261 fBottom = y + height;
262 }
263
264 /**
265 Expand the edges of the rectangle to include a point.
266 Useful for constructing a bounding rectangle.
267 @param pt the point used to grow the rectangle.
268 */
269 void growToInclude(const GrPoint& pt) {
270 fLeft = GrMin(pt.fX, fLeft);
271 fRight = GrMax(pt.fX, fRight);
272
273 fTop = GrMin(pt.fY, fTop);
274 fBottom = GrMax(pt.fY, fBottom);
275 }
276
277 /**
278 * Assigns 4 sequential points in order to construct a counter-clockwise
279 * triangle fan, given the corners of this rect. Returns the address of
280 * the next point, treating pts as an array.
281 */
282 GrPoint* setRectFan(GrPoint pts[4]) const {
283 pts->setRectFan(fLeft, fTop, fRight, fBottom);
284 return pts + 4;
285 }
286};
287
288#endif
289