OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2012 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 #ifndef SkPathOpsTypes_DEFINED | |
8 #define SkPathOpsTypes_DEFINED | |
9 | |
10 #include <float.h> // for FLT_EPSILON | |
11 #include <math.h> // for fabs, sqrt | |
12 | |
13 #include "SkFloatingPoint.h" | |
14 #include "SkPathOpsDebug.h" | |
15 #include "SkScalar.h" | |
16 | |
17 // FIXME: move these into SkTypes.h | |
18 template <typename T> inline T SkTMax(T a, T b) { | |
19 if (a < b) | |
whunt
2013/03/22 18:16:06
min and max can be performance critical operations
caryclark
2013/03/22 19:38:51
Noted.
| |
20 a = b; | |
21 return a; | |
22 } | |
23 | |
24 template <typename T> inline T SkTMin(T a, T b) { | |
25 if (a > b) | |
26 a = b; | |
27 return a; | |
28 } | |
29 | |
30 // FIXME: move this into SkFloatingPoint.h | |
31 #define sk_double_isnan(a) sk_float_isnan(a) | |
32 | |
33 // FIXME: move this into SkPaths.h or just use the equivalent in SkRegion.h | |
34 enum SkPathOp { | |
35 kDifference_PathOp, //!< subtract the op region from the first region | |
36 kIntersect_PathOp, //!< intersect the two regions | |
37 kUnion_PathOp, //!< union (inclusive-or) the two regions | |
38 kXOR_PathOp, //!< exclusive-or the two regions | |
39 /** subtract the first region from the op region */ | |
40 kReverseDifference_PathOp, // FIXME: unsupported | |
41 kReplace_PathOp //!< replace the dst region with the op region FIXME: u nsupported | |
42 }; | |
43 | |
44 enum SkPathOpsMask { | |
45 kWinding_PathOpsMask = -1, | |
46 kNo_PathOpsMask = 0, | |
47 kEvenOdd_PathOpsMask = 1 | |
48 }; | |
49 | |
50 extern bool AlmostEqualUlps(float A, float B); | |
51 inline bool AlmostEqualUlps(double A, double B) { | |
52 return AlmostEqualUlps(SkDoubleToScalar(A), SkDoubleToScalar(B)); | |
53 } | |
54 | |
55 // FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23) | |
56 // DBL_EPSILON == 2.22045e-16 | |
57 const double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON; | |
58 const double FLT_EPSILON_HALF = FLT_EPSILON / 2; | |
59 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; | |
60 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); | |
61 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON; | |
62 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // FIXME: tune -- allow a few b its of error | |
63 const double ROUGH_EPSILON = FLT_EPSILON * 64; | |
64 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; | |
65 | |
66 inline bool approximately_zero(double x) { | |
67 return fabs(x) < FLT_EPSILON; | |
68 } | |
69 | |
70 inline bool precisely_zero(double x) { | |
71 return fabs(x) < DBL_EPSILON_ERR; | |
72 } | |
73 | |
74 inline bool approximately_zero(float x) { | |
75 return fabs(x) < FLT_EPSILON; | |
76 } | |
77 | |
78 inline bool approximately_zero_cubed(double x) { | |
79 return fabs(x) < FLT_EPSILON_CUBED; | |
80 } | |
81 | |
82 inline bool approximately_zero_half(double x) { | |
83 return fabs(x) < FLT_EPSILON_HALF; | |
84 } | |
85 | |
86 inline bool approximately_zero_squared(double x) { | |
87 return fabs(x) < FLT_EPSILON_SQUARED; | |
88 } | |
89 | |
90 inline bool approximately_zero_sqrt(double x) { | |
91 return fabs(x) < FLT_EPSILON_SQRT; | |
92 } | |
93 | |
94 inline bool approximately_zero_inverse(double x) { | |
95 return fabs(x) > FLT_EPSILON_INVERSE; | |
96 } | |
97 | |
98 // OPTIMIZATION: if called multiple times with the same denom, we want to pass 1 /y instead | |
99 inline bool approximately_zero_when_compared_to(double x, double y) { | |
100 return x == 0 || fabs(x / y) < FLT_EPSILON; | |
101 } | |
102 | |
103 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use | |
104 // AlmostEqualUlps instead. | |
105 inline bool approximately_equal(double x, double y) { | |
106 return approximately_zero(x - y); | |
107 } | |
108 | |
109 inline bool precisely_equal(double x, double y) { | |
110 return precisely_zero(x - y); | |
111 } | |
112 | |
113 inline bool approximately_equal_half(double x, double y) { | |
114 return approximately_zero_half(x - y); | |
115 } | |
116 | |
117 inline bool approximately_equal_squared(double x, double y) { | |
118 return approximately_equal(x, y); | |
119 } | |
120 | |
121 inline bool approximately_greater(double x, double y) { | |
122 return x - FLT_EPSILON >= y; | |
123 } | |
124 | |
125 inline bool approximately_greater_or_equal(double x, double y) { | |
126 return x + FLT_EPSILON > y; | |
127 } | |
128 | |
129 inline bool approximately_lesser(double x, double y) { | |
130 return x + FLT_EPSILON <= y; | |
131 } | |
132 | |
133 inline bool approximately_lesser_or_equal(double x, double y) { | |
134 return x - FLT_EPSILON < y; | |
135 } | |
136 | |
137 inline double approximately_pin(double x) { | |
138 return approximately_zero(x) ? 0 : x; | |
139 } | |
140 | |
141 inline float approximately_pin(float x) { | |
142 return approximately_zero(x) ? 0 : x; | |
143 } | |
144 | |
145 inline bool approximately_greater_than_one(double x) { | |
146 return x > 1 - FLT_EPSILON; | |
147 } | |
148 | |
149 inline bool precisely_greater_than_one(double x) { | |
150 return x > 1 - DBL_EPSILON_ERR; | |
151 } | |
152 | |
153 inline bool approximately_less_than_zero(double x) { | |
154 return x < FLT_EPSILON; | |
155 } | |
156 | |
157 inline bool precisely_less_than_zero(double x) { | |
158 return x < DBL_EPSILON_ERR; | |
159 } | |
160 | |
161 inline bool approximately_negative(double x) { | |
162 return x < FLT_EPSILON; | |
163 } | |
164 | |
165 inline bool precisely_negative(double x) { | |
166 return x < DBL_EPSILON_ERR; | |
167 } | |
168 | |
169 inline bool approximately_one_or_less(double x) { | |
170 return x < 1 + FLT_EPSILON; | |
171 } | |
172 | |
173 inline bool approximately_positive(double x) { | |
174 return x > -FLT_EPSILON; | |
175 } | |
176 | |
177 inline bool approximately_positive_squared(double x) { | |
178 return x > -(FLT_EPSILON_SQUARED); | |
179 } | |
180 | |
181 inline bool approximately_zero_or_more(double x) { | |
182 return x > -FLT_EPSILON; | |
183 } | |
184 | |
185 inline bool approximately_between(double a, double b, double c) { | |
186 return a <= c ? approximately_negative(a - b) && approximately_negative(b - c) | |
187 : approximately_negative(b - a) && approximately_negative(c - b); | |
188 } | |
189 | |
190 // returns true if (a <= b <= c) || (a >= b >= c) | |
191 inline bool between(double a, double b, double c) { | |
192 SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)); | |
193 return (a - b) * (c - b) <= 0; | |
194 } | |
195 | |
196 inline bool more_roughly_equal(double x, double y) { | |
197 return fabs(x - y) < MORE_ROUGH_EPSILON; | |
198 } | |
199 | |
200 inline bool roughly_equal(double x, double y) { | |
201 return fabs(x - y) < ROUGH_EPSILON; | |
202 } | |
203 | |
204 struct SkDPoint; | |
205 struct SkDVector; | |
206 struct SkDLine; | |
207 struct SkDQuad; | |
208 struct SkDTriangle; | |
209 struct SkDCubic; | |
210 struct SkDRect; | |
211 | |
212 inline double SkDInterp(double A, double B, double t) { | |
213 return A + (B - A) * t; | |
214 } | |
215 | |
216 double SkDCubeRoot(double x); | |
217 | |
218 /* Returns -1 if negative, 0 if zero, 1 if positive | |
219 */ | |
220 inline int SkDSign(double x) { | |
221 return (x > 0) - (x < 0); | |
222 } | |
223 | |
224 /* Returns 0 if negative, 1 if zero, 2 if positive | |
225 */ | |
226 inline int SKDSide(double x) { | |
227 return (x > 0) + (x >= 0); | |
228 } | |
229 | |
230 /* Returns 1 if negative, 2 if zero, 4 if positive | |
231 */ | |
232 inline int SkDSideBit(double x) { | |
233 return 1 << SKDSide(x); | |
234 } | |
235 | |
236 /* Given the set [0, 1, 2, 3], and two of the four members, compute an XOR mask | |
237 that computes the other two. Note that: | |
238 | |
239 one ^ two == 3 for (0, 3), (1, 2) | |
240 one ^ two < 3 for (0, 1), (0, 2), (1, 3), (2, 3) | |
241 3 - (one ^ two) is either 0, 1, or 2 | |
242 1 >> 3 - (one ^ two) is either 0 or 1 | |
243 thus: | |
244 returned == 2 for (0, 3), (1, 2) | |
245 returned == 3 for (0, 1), (0, 2), (1, 3), (2, 3) | |
246 given that: | |
247 (0, 3) ^ 2 -> (2, 1) (1, 2) ^ 2 -> (3, 0) | |
248 (0, 1) ^ 3 -> (3, 2) (0, 2) ^ 3 -> (3, 1) (1, 3) ^ 3 -> (2, 0) (2, 3) ^ 3 -> (1, 0) | |
249 */ | |
250 inline int SkOtherTwo(int one, int two) { | |
251 return 1 >> 3 - (one ^ two) ^ 3; | |
whunt
2013/03/22 18:16:06
I believe:
((one ^ two) & 1) + 1
will yield you th
caryclark
2013/03/22 19:38:51
This function is no longer used. It's been removed
whunt
2013/03/22 19:50:10
Sad =(, it was an interesting bit-twiddling proble
| |
252 } | |
253 | |
254 #endif | |
OLD | NEW |