blob: 5192ebdf183ee61379a84fa9d3473e56f073c940 [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 */
134 GrRect(GrPoint pt) {
135 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 }
190
191 /**
192 * Initialize a rectangle to a point.
193 * @param pt the point used to initialize the rectangle.
194 */
195 void setToPoint(const GrPoint& pt) {
196 fLeft = pt.fX;
197 fTop = pt.fY;
198 fRight = pt.fX;
199 fBottom = pt.fY;
200 }
201
202 void set(const GrIRect& r) {
203 fLeft = GrIntToScalar(r.fLeft);
204 fTop = GrIntToScalar(r.fTop);
205 fRight = GrIntToScalar(r.fRight);
206 fBottom = GrIntToScalar(r.fBottom);
207 }
208
209 void roundOut(GrIRect* r) const {
210 r->setLTRB(GrScalarFloorToInt(fLeft),
211 GrScalarFloorToInt(fTop),
212 GrScalarCeilToInt(fRight),
213 GrScalarCeilToInt(fBottom));
214 }
215
216 /**
217 * Set the rect to the union of the array of points. If the array is empty
218 * the rect will be empty [0,0,0,0]
219 */
220 void setBounds(const GrPoint pts[], int count);
221
222 /**
223 * Make the largest representable rectangle
224 * Set the rect to fLeft = fTop = GR_ScalarMin and
225 * fRight = fBottom = GR_ScalarMax.
226 */
227 void setLargest() {
228 fLeft = fTop = GR_ScalarMin;
229 fRight = fBottom = GR_ScalarMax;
230 }
231
232 /**
233 Set the rect to fLeft = fTop = GR_ScalarMax and
234 fRight = fBottom = GR_ScalarMin.
235 Useful for initializing a bounding rectangle.
236 */
237 void setLargestInverted() {
238 fLeft = fTop = GR_ScalarMax;
239 fRight = fBottom = GR_ScalarMin;
240 }
241
242 void setLTRB(GrScalar left,
243 GrScalar top,
244 GrScalar right,
245 GrScalar bottom) {
246 fLeft = left;
247 fTop = top;
248 fRight = right;
249 fBottom = bottom;
250 }
251
252 void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
253 fLeft = x;
254 fTop = y;
255 fRight = x + width;
256 fBottom = y + height;
257 }
258
259 /**
260 Expand the edges of the rectangle to include a point.
261 Useful for constructing a bounding rectangle.
262 @param pt the point used to grow the rectangle.
263 */
264 void growToInclude(const GrPoint& pt) {
265 fLeft = GrMin(pt.fX, fLeft);
266 fRight = GrMax(pt.fX, fRight);
267
268 fTop = GrMin(pt.fY, fTop);
269 fBottom = GrMax(pt.fY, fBottom);
270 }
271
272 /**
273 * Assigns 4 sequential points in order to construct a counter-clockwise
274 * triangle fan, given the corners of this rect. Returns the address of
275 * the next point, treating pts as an array.
276 */
277 GrPoint* setRectFan(GrPoint pts[4]) const {
278 pts->setRectFan(fLeft, fTop, fRight, fBottom);
279 return pts + 4;
280 }
281};
282
283#endif
284