blob: e0e53264fde74aa2c427fc744eebd54ed9d073c8 [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;
bsalomon@google.comd302f142011-03-03 13:54:13 +000025
reed@google.comac10a2d2010-12-22 21:39:39 +000026 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 }
bsalomon@google.comd302f142011-03-03 13:54:13 +000050
reed@google.comac10a2d2010-12-22 21:39:39 +000051 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 }
bsalomon@google.comd302f142011-03-03 13:54:13 +000057
reed@google.comac10a2d2010-12-22 21:39:39 +000058 /**
59 * Make the largest representable rectangle
reed@google.comac10a2d2010-12-22 21:39:39 +000060 */
61 void setLargest() {
62 fLeft = fTop = GR_Int32Min;
63 fRight = fBottom = GR_Int32Max;
64 }
bsalomon@google.comd302f142011-03-03 13:54:13 +000065
reed@google.comac10a2d2010-12-22 21:39:39 +000066 bool quickReject(int l, int t, int r, int b) const {
67 return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
68 }
69
70 void unionWith(const GrIRect& r) {
71 if (fLeft > r.fLeft) fLeft = r.fLeft;
72 if (fTop > r.fTop) fTop = r.fTop;
73 if (fRight < r.fRight) fRight = r.fRight;
74 if (fBottom < r.fBottom) fBottom = r.fBottom;
75 }
76
bsalomon@google.comd302f142011-03-03 13:54:13 +000077 /**
78 * Sets this rect to the intersection with a clip rect. If there is no
79 * intersection then this rect will be made empty.
80 */
81 void intersectWith(const GrIRect& clipRect) {
82 if (fRight < clipRect.fLeft ||
83 fLeft > clipRect.fRight ||
84 fBottom < clipRect.fTop ||
85 fTop > clipRect.fBottom) {
86 this->setEmpty();
87 } else {
88 fLeft = GrMax(fLeft, clipRect.fLeft);
89 fRight = GrMin(fRight, clipRect.fRight);
90 fTop = GrMax(fTop, clipRect.fTop);
91 fBottom = GrMin(fBottom, clipRect.fBottom);
92 }
93 }
94
reed@google.comac10a2d2010-12-22 21:39:39 +000095 friend bool operator==(const GrIRect& a, const GrIRect& b) {
96 return 0 == memcmp(&a, &b, sizeof(a));
97 }
bsalomon@google.comd302f142011-03-03 13:54:13 +000098
reed@google.comac10a2d2010-12-22 21:39:39 +000099 friend bool operator!=(const GrIRect& a, const GrIRect& b) {
100 return 0 != memcmp(&a, &b, sizeof(a));
101 }
102
103 bool equalsLTRB(int l, int t, int r, int b) const {
104 return fLeft == l && fTop == t &&
105 fRight == r && fBottom == b;
106 }
107 bool equalsXYWH(int x, int y, int w, int h) const {
108 return fLeft == x && fTop == y &&
109 this->width() == w && this->height() == h;
110 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000111
reed@google.comac10a2d2010-12-22 21:39:39 +0000112 bool contains(const GrIRect& r) const {
113 return fLeft <= r.fLeft &&
114 fRight >= r.fRight &&
115 fTop <= r.fTop &&
116 fBottom >= r.fBottom;
117 }
118};
119
120struct GrIRect16 {
121 int16_t fLeft, fTop, fRight, fBottom;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000122
reed@google.comac10a2d2010-12-22 21:39:39 +0000123 int width() const { return fRight - fLeft; }
124 int height() const { return fBottom - fTop; }
125 int area() const { return this->width() * this->height(); }
126 bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000127
reed@google.comac10a2d2010-12-22 21:39:39 +0000128 void set(const GrIRect& r) {
129 fLeft = GrToS16(r.fLeft);
130 fTop = GrToS16(r.fTop);
131 fRight = GrToS16(r.fRight);
132 fBottom = GrToS16(r.fBottom);
133 }
134};
135
bsalomon@google.comd302f142011-03-03 13:54:13 +0000136/**
reed@google.comac10a2d2010-12-22 21:39:39 +0000137 * 2D Rect struct
138 */
139struct GrRect {
140 GrScalar fLeft, fTop, fRight, fBottom;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000141
reed@google.comac10a2d2010-12-22 21:39:39 +0000142 /**
143 * Uninitialized rectangle.
144 */
145 GrRect() {}
146
147 /**
148 * Initialize a rectangle to a point.
149 * @param pt the point used to initialize the rectanglee.
150 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000151 explicit GrRect(const GrPoint& pt) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000152 setToPoint(pt);
153 }
154
155 GrRect(GrScalar left, GrScalar top, GrScalar right, GrScalar bottom) {
156 fLeft = left;
157 fTop = top;
158 fRight = right;
159 fBottom = bottom;
160 }
161
162 explicit GrRect(const GrIRect& src) {
163 fLeft = GrIntToScalar(src.fLeft);
164 fTop = GrIntToScalar(src.fTop);
165 fRight = GrIntToScalar(src.fRight);
166 fBottom = GrIntToScalar(src.fBottom);
167 }
168
169 GrScalar x() const { return fLeft; }
170 GrScalar y() const { return fTop; }
171 GrScalar width() const { return fRight - fLeft; }
172 GrScalar height() const { return fBottom - fTop; }
173
174 GrScalar left() const { return fLeft; }
175 GrScalar top() const { return fTop; }
176 GrScalar right() const { return fRight; }
177 GrScalar bottom() const { return fBottom; }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000178
reed@google.comac10a2d2010-12-22 21:39:39 +0000179 GrScalar diagonalLengthSqd() const {
180 GrScalar w = width();
181 GrScalar h = height();
182 return GrMul(w, w) + GrMul(h, h);
183 }
184
185 GrScalar diagonalLength() const {
186 // TODO: fixed point sqrt
187 return GrFloatToScalar(sqrtf(GrScalarToFloat(diagonalLengthSqd())));
188 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000189
reed@google.comac10a2d2010-12-22 21:39:39 +0000190 /**
191 * Returns true if the width or height is <= 0
192 */
193 bool isEmpty() const {
194 return fLeft >= fRight || fTop >= fBottom;
195 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000196
reed@google.comac10a2d2010-12-22 21:39:39 +0000197 void setEmpty() {
198 fLeft = fTop = fRight = fBottom = 0;
199 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000200
reed@google.comac10a2d2010-12-22 21:39:39 +0000201 /**
202 * returns true if the rectangle is inverted either in x or y
203 */
204 bool isInverted() const {
205 return (fLeft > fRight) || (fTop > fBottom);
206 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000207
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000208 /**
209 * Does this rect contain a point.
210 */
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000211 bool contains(const GrPoint& point) const {
212 return point.fX >= fLeft && point.fX < fRight &&
213 point.fY >= fTop && point.fY < fBottom;
214 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000215
reed@google.comac10a2d2010-12-22 21:39:39 +0000216 /**
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000217 * Does this rect fully contain another rect.
218 */
219 bool contains(const GrRect& r) const {
220 return fLeft <= r.fLeft &&
221 fRight >= r.fRight &&
222 fTop <= r.fTop &&
223 fBottom >= r.fBottom;
224 }
225
226
227 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000228 * Initialize a rectangle to a point.
229 * @param pt the point used to initialize the rectangle.
230 */
231 void setToPoint(const GrPoint& pt) {
232 fLeft = pt.fX;
233 fTop = pt.fY;
234 fRight = pt.fX;
235 fBottom = pt.fY;
236 }
237
238 void set(const GrIRect& r) {
239 fLeft = GrIntToScalar(r.fLeft);
240 fTop = GrIntToScalar(r.fTop);
241 fRight = GrIntToScalar(r.fRight);
242 fBottom = GrIntToScalar(r.fBottom);
243 }
244
245 void roundOut(GrIRect* r) const {
246 r->setLTRB(GrScalarFloorToInt(fLeft),
247 GrScalarFloorToInt(fTop),
248 GrScalarCeilToInt(fRight),
249 GrScalarCeilToInt(fBottom));
250 }
251
252 /**
253 * Set the rect to the union of the array of points. If the array is empty
254 * the rect will be empty [0,0,0,0]
255 */
256 void setBounds(const GrPoint pts[], int count);
257
258 /**
259 * Make the largest representable rectangle
bsalomon@google.comd302f142011-03-03 13:54:13 +0000260 * Set the rect to fLeft = fTop = GR_ScalarMin and
reed@google.comac10a2d2010-12-22 21:39:39 +0000261 * fRight = fBottom = GR_ScalarMax.
262 */
263 void setLargest() {
264 fLeft = fTop = GR_ScalarMin;
265 fRight = fBottom = GR_ScalarMax;
266 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000267
reed@google.comac10a2d2010-12-22 21:39:39 +0000268 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000269 Set the rect to fLeft = fTop = GR_ScalarMax and
reed@google.comac10a2d2010-12-22 21:39:39 +0000270 fRight = fBottom = GR_ScalarMin.
271 Useful for initializing a bounding rectangle.
272 */
273 void setLargestInverted() {
274 fLeft = fTop = GR_ScalarMax;
275 fRight = fBottom = GR_ScalarMin;
276 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000277
278 void setLTRB(GrScalar left,
279 GrScalar top,
280 GrScalar right,
reed@google.comac10a2d2010-12-22 21:39:39 +0000281 GrScalar bottom) {
282 fLeft = left;
283 fTop = top;
284 fRight = right;
285 fBottom = bottom;
286 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000287
reed@google.comac10a2d2010-12-22 21:39:39 +0000288 void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
289 fLeft = x;
290 fTop = y;
291 fRight = x + width;
292 fBottom = y + height;
293 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000294
reed@google.comac10a2d2010-12-22 21:39:39 +0000295 /**
296 Expand the edges of the rectangle to include a point.
297 Useful for constructing a bounding rectangle.
298 @param pt the point used to grow the rectangle.
299 */
300 void growToInclude(const GrPoint& pt) {
301 fLeft = GrMin(pt.fX, fLeft);
302 fRight = GrMax(pt.fX, fRight);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000303
reed@google.comac10a2d2010-12-22 21:39:39 +0000304 fTop = GrMin(pt.fY, fTop);
305 fBottom = GrMax(pt.fY, fBottom);
306 }
307
308 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000309 * Grows a rect to include another rect.
310 * @param rect the rect to include
311 */
312 void growToInclude(const GrRect& rect) {
313 GrAssert(!rect.isEmpty());
314 fLeft = GrMin(rect.fLeft, fLeft);
315 fRight = GrMax(rect.fRight, fRight);
316
317 fTop = GrMin(rect.fTop, fTop);
318 fBottom = GrMax(rect.fBottom, fBottom);
319 }
320
321 /**
322 * Sets this rect to the intersection with a clip rect. If there is no
323 * intersection then this rect will be made empty.
324 */
325 void intersectWith(const GrRect& clipRect) {
326 if (fRight < clipRect.fLeft ||
327 fLeft > clipRect.fRight ||
328 fBottom < clipRect.fTop ||
329 fTop > clipRect.fBottom) {
330 this->setEmpty();
331 } else {
332 fLeft = GrMax(fLeft, clipRect.fLeft);
333 fRight = GrMin(fRight, clipRect.fRight);
334 fTop = GrMax(fTop, clipRect.fTop);
335 fBottom = GrMin(fBottom, clipRect.fBottom);
336 }
337 }
338
339 /**
reed@google.comac10a2d2010-12-22 21:39:39 +0000340 * Assigns 4 sequential points in order to construct a counter-clockwise
341 * triangle fan, given the corners of this rect. Returns the address of
342 * the next point, treating pts as an array.
343 */
344 GrPoint* setRectFan(GrPoint pts[4]) const {
345 pts->setRectFan(fLeft, fTop, fRight, fBottom);
346 return pts + 4;
347 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000348
349 bool operator ==(const GrRect& r) const {
350 return fLeft == r.fLeft &&
351 fTop == r.fTop &&
352 fRight == r.fRight &&
353 fBottom == r.fBottom;
354 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000355};
356
357#endif
358