|
1 |
|
2 /* |
|
3 * Copyright 2006 The Android Open Source Project |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #include "SkRect.h" |
|
11 |
|
12 void SkIRect::join(int32_t left, int32_t top, int32_t right, int32_t bottom) { |
|
13 // do nothing if the params are empty |
|
14 if (left >= right || top >= bottom) { |
|
15 return; |
|
16 } |
|
17 |
|
18 // if we are empty, just assign |
|
19 if (fLeft >= fRight || fTop >= fBottom) { |
|
20 this->set(left, top, right, bottom); |
|
21 } else { |
|
22 if (left < fLeft) fLeft = left; |
|
23 if (top < fTop) fTop = top; |
|
24 if (right > fRight) fRight = right; |
|
25 if (bottom > fBottom) fBottom = bottom; |
|
26 } |
|
27 } |
|
28 |
|
29 void SkIRect::sort() { |
|
30 if (fLeft > fRight) { |
|
31 SkTSwap<int32_t>(fLeft, fRight); |
|
32 } |
|
33 if (fTop > fBottom) { |
|
34 SkTSwap<int32_t>(fTop, fBottom); |
|
35 } |
|
36 } |
|
37 |
|
38 ///////////////////////////////////////////////////////////////////////////// |
|
39 |
|
40 void SkRect::sort() { |
|
41 if (fLeft > fRight) { |
|
42 SkTSwap<SkScalar>(fLeft, fRight); |
|
43 } |
|
44 if (fTop > fBottom) { |
|
45 SkTSwap<SkScalar>(fTop, fBottom); |
|
46 } |
|
47 } |
|
48 |
|
49 void SkRect::toQuad(SkPoint quad[4]) const { |
|
50 SkASSERT(quad); |
|
51 |
|
52 quad[0].set(fLeft, fTop); |
|
53 quad[1].set(fRight, fTop); |
|
54 quad[2].set(fRight, fBottom); |
|
55 quad[3].set(fLeft, fBottom); |
|
56 } |
|
57 |
|
58 bool SkRect::setBoundsCheck(const SkPoint pts[], int count) { |
|
59 SkASSERT((pts && count > 0) || count == 0); |
|
60 |
|
61 bool isFinite = true; |
|
62 |
|
63 if (count <= 0) { |
|
64 sk_bzero(this, sizeof(SkRect)); |
|
65 } else { |
|
66 SkScalar l, t, r, b; |
|
67 |
|
68 l = r = pts[0].fX; |
|
69 t = b = pts[0].fY; |
|
70 |
|
71 // If all of the points are finite, accum should stay 0. If we encounter |
|
72 // a NaN or infinity, then accum should become NaN. |
|
73 float accum = 0; |
|
74 accum *= l; accum *= t; |
|
75 |
|
76 for (int i = 1; i < count; i++) { |
|
77 SkScalar x = pts[i].fX; |
|
78 SkScalar y = pts[i].fY; |
|
79 |
|
80 accum *= x; accum *= y; |
|
81 |
|
82 // we use if instead of if/else, so we can generate min/max |
|
83 // float instructions (at least on SSE) |
|
84 if (x < l) l = x; |
|
85 if (x > r) r = x; |
|
86 |
|
87 if (y < t) t = y; |
|
88 if (y > b) b = y; |
|
89 } |
|
90 |
|
91 SkASSERT(!accum || !SkScalarIsFinite(accum)); |
|
92 if (accum) { |
|
93 l = t = r = b = 0; |
|
94 isFinite = false; |
|
95 } |
|
96 this->set(l, t, r, b); |
|
97 } |
|
98 |
|
99 return isFinite; |
|
100 } |
|
101 |
|
102 bool SkRect::intersect(SkScalar left, SkScalar top, SkScalar right, |
|
103 SkScalar bottom) { |
|
104 if (left < right && top < bottom && !this->isEmpty() && // check for empties |
|
105 fLeft < right && left < fRight && fTop < bottom && top < fBottom) |
|
106 { |
|
107 if (fLeft < left) fLeft = left; |
|
108 if (fTop < top) fTop = top; |
|
109 if (fRight > right) fRight = right; |
|
110 if (fBottom > bottom) fBottom = bottom; |
|
111 return true; |
|
112 } |
|
113 return false; |
|
114 } |
|
115 |
|
116 bool SkRect::intersect(const SkRect& r) { |
|
117 SkASSERT(&r); |
|
118 return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); |
|
119 } |
|
120 |
|
121 bool SkRect::intersect2(const SkRect& r) { |
|
122 SkASSERT(&r); |
|
123 SkScalar L = SkMaxScalar(fLeft, r.fLeft); |
|
124 SkScalar R = SkMinScalar(fRight, r.fRight); |
|
125 if (L >= R) { |
|
126 return false; |
|
127 } |
|
128 SkScalar T = SkMaxScalar(fTop, r.fTop); |
|
129 SkScalar B = SkMinScalar(fBottom, r.fBottom); |
|
130 if (T >= B) { |
|
131 return false; |
|
132 } |
|
133 this->set(L, T, R, B); |
|
134 return true; |
|
135 } |
|
136 |
|
137 bool SkRect::intersect(const SkRect& a, const SkRect& b) { |
|
138 SkASSERT(&a && &b); |
|
139 |
|
140 if (!a.isEmpty() && !b.isEmpty() && |
|
141 a.fLeft < b.fRight && b.fLeft < a.fRight && |
|
142 a.fTop < b.fBottom && b.fTop < a.fBottom) { |
|
143 fLeft = SkMaxScalar(a.fLeft, b.fLeft); |
|
144 fTop = SkMaxScalar(a.fTop, b.fTop); |
|
145 fRight = SkMinScalar(a.fRight, b.fRight); |
|
146 fBottom = SkMinScalar(a.fBottom, b.fBottom); |
|
147 return true; |
|
148 } |
|
149 return false; |
|
150 } |
|
151 |
|
152 void SkRect::join(SkScalar left, SkScalar top, SkScalar right, |
|
153 SkScalar bottom) { |
|
154 // do nothing if the params are empty |
|
155 if (left >= right || top >= bottom) { |
|
156 return; |
|
157 } |
|
158 |
|
159 // if we are empty, just assign |
|
160 if (fLeft >= fRight || fTop >= fBottom) { |
|
161 this->set(left, top, right, bottom); |
|
162 } else { |
|
163 if (left < fLeft) fLeft = left; |
|
164 if (top < fTop) fTop = top; |
|
165 if (right > fRight) fRight = right; |
|
166 if (bottom > fBottom) fBottom = bottom; |
|
167 } |
|
168 } |