OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkMatrix.h" | 8 #include "SkMatrix.h" |
9 #include "SkFloatBits.h" | 9 #include "SkFloatBits.h" |
10 #include "SkOnce.h" | 10 #include "SkOnce.h" |
11 #include "SkString.h" | 11 #include "SkString.h" |
12 | 12 |
13 #define kMatrix22Elem SK_Scalar1 | 13 // In a few places, we performed the following |
14 // a * b + c * d + e | |
15 // as | |
16 // a * b + (c * d + e) | |
17 // | |
18 // sdot and scross are indended to capture these compound operations into a | |
19 // function, with an eye toward considering upscaling the intermediates to | |
20 // doubles for more precision (as we do in concat and invert). | |
21 // | |
22 // However, these few lines that performed the last add before the "dot", cause | |
23 // tiny image differences, so we guard that change until we see the impact on | |
24 // chrome's layouttests. | |
25 // | |
26 #define SK_LEGACY_MATRIX_MATH_ORDER | |
14 | 27 |
15 static inline float SkDoubleToFloat(double x) { | 28 static inline float SkDoubleToFloat(double x) { |
16 return static_cast<float>(x); | 29 return static_cast<float>(x); |
17 } | 30 } |
18 | 31 |
19 /* [scale-x skew-x trans-x] [X] [X'] | 32 /* [scale-x skew-x trans-x] [X] [X'] |
20 [skew-y scale-y trans-y] * [Y] = [Y'] | 33 [skew-y scale-y trans-y] * [Y] = [Y'] |
21 [persp-0 persp-1 persp-2] [1] [1 ] | 34 [persp-0 persp-1 persp-2] [1] [1 ] |
22 */ | 35 */ |
23 | 36 |
24 void SkMatrix::reset() { | 37 void SkMatrix::reset() { |
25 fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; | 38 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1; |
26 fMat[kMSkewX] = fMat[kMSkewY] = | 39 fMat[kMSkewX] = fMat[kMSkewY] = |
27 fMat[kMTransX] = fMat[kMTransY] = | 40 fMat[kMTransX] = fMat[kMTransY] = |
28 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 41 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
29 fMat[kMPersp2] = kMatrix22Elem; | |
30 | 42 |
31 this->setTypeMask(kIdentity_Mask | kRectStaysRect_Mask); | 43 this->setTypeMask(kIdentity_Mask | kRectStaysRect_Mask); |
32 } | 44 } |
33 | 45 |
34 // this guy aligns with the masks, so we can compute a mask from a varaible 0/1 | 46 // this guy aligns with the masks, so we can compute a mask from a varaible 0/1 |
35 enum { | 47 enum { |
36 kTranslate_Shift, | 48 kTranslate_Shift, |
37 kScale_Shift, | 49 kScale_Shift, |
38 kAffine_Shift, | 50 kAffine_Shift, |
39 kPerspective_Shift, | 51 kPerspective_Shift, |
40 kRectStaysRect_Shift | 52 kRectStaysRect_Shift |
41 }; | 53 }; |
42 | 54 |
43 static const int32_t kScalar1Int = 0x3f800000; | 55 static const int32_t kScalar1Int = 0x3f800000; |
44 | 56 |
45 uint8_t SkMatrix::computePerspectiveTypeMask() const { | 57 uint8_t SkMatrix::computePerspectiveTypeMask() const { |
46 // Benchmarking suggests that replacing this set of SkScalarAs2sCompliment | 58 // Benchmarking suggests that replacing this set of SkScalarAs2sCompliment |
47 // is a win, but replacing those below is not. We don't yet understand | 59 // is a win, but replacing those below is not. We don't yet understand |
48 // that result. | 60 // that result. |
49 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || | 61 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || fMat[kMPersp2] != 1) { |
50 fMat[kMPersp2] != kMatrix22Elem) { | |
51 // If this is a perspective transform, we return true for all other | 62 // If this is a perspective transform, we return true for all other |
52 // transform flags - this does not disable any optimizations, respects | 63 // transform flags - this does not disable any optimizations, respects |
53 // the rule that the type mask must be conservative, and speeds up | 64 // the rule that the type mask must be conservative, and speeds up |
54 // type mask computation. | 65 // type mask computation. |
55 return SkToU8(kORableMasks); | 66 return SkToU8(kORableMasks); |
56 } | 67 } |
57 | 68 |
58 return SkToU8(kOnlyPerspectiveValid_Mask | kUnknown_Mask); | 69 return SkToU8(kOnlyPerspectiveValid_Mask | kUnknown_Mask); |
59 } | 70 } |
60 | 71 |
61 uint8_t SkMatrix::computeTypeMask() const { | 72 uint8_t SkMatrix::computeTypeMask() const { |
62 unsigned mask = 0; | 73 unsigned mask = 0; |
63 | 74 |
64 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || | 75 if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || fMat[kMPersp2] != 1) { |
65 fMat[kMPersp2] != kMatrix22Elem) { | |
66 // Once it is determined that that this is a perspective transform, | 76 // Once it is determined that that this is a perspective transform, |
67 // all other flags are moot as far as optimizations are concerned. | 77 // all other flags are moot as far as optimizations are concerned. |
68 return SkToU8(kORableMasks); | 78 return SkToU8(kORableMasks); |
69 } | 79 } |
70 | 80 |
71 if (fMat[kMTransX] != 0 || fMat[kMTransY] != 0) { | 81 if (fMat[kMTransX] != 0 || fMat[kMTransY] != 0) { |
72 mask |= kTranslate_Mask; | 82 mask |= kTranslate_Mask; |
73 } | 83 } |
74 | 84 |
75 int m00 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleX]); | 85 int m00 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleX]); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
202 vec[0].set(mx, sx); | 212 vec[0].set(mx, sx); |
203 vec[1].set(sy, my); | 213 vec[1].set(sy, my); |
204 | 214 |
205 return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && | 215 return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && |
206 SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), | 216 SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), |
207 SkScalarSquare(tol)); | 217 SkScalarSquare(tol)); |
208 } | 218 } |
209 | 219 |
210 /////////////////////////////////////////////////////////////////////////////// | 220 /////////////////////////////////////////////////////////////////////////////// |
211 | 221 |
222 static inline SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d) { | |
223 return a * b + c * d; | |
224 } | |
225 | |
226 static inline SkScalar sdot3(SkScalar a, SkScalar b, SkScalar c, SkScalar d, | |
mtklein
2014/01/30 19:14:55
Don't think calling this sdot would hurt if you're
reed1
2014/01/30 20:53:48
Done.
| |
227 SkScalar e, SkScalar f) { | |
228 return a * b + c * d + e * f; | |
229 } | |
230 | |
231 static inline SkScalar scross(SkScalar a, SkScalar b, SkScalar c, SkScalar d) { | |
232 return a * b - c * d; | |
233 } | |
234 | |
212 void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) { | 235 void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) { |
213 if (dx || dy) { | 236 if (dx || dy) { |
214 fMat[kMTransX] = dx; | 237 fMat[kMTransX] = dx; |
215 fMat[kMTransY] = dy; | 238 fMat[kMTransY] = dy; |
216 | 239 |
217 fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; | 240 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1; |
218 fMat[kMSkewX] = fMat[kMSkewY] = | 241 fMat[kMSkewX] = fMat[kMSkewY] = |
219 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 242 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
220 fMat[kMPersp2] = kMatrix22Elem; | |
221 | 243 |
222 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); | 244 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); |
223 } else { | 245 } else { |
224 this->reset(); | 246 this->reset(); |
225 } | 247 } |
226 } | 248 } |
227 | 249 |
228 bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { | 250 bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { |
229 if (this->hasPerspective()) { | 251 if (this->hasPerspective()) { |
230 SkMatrix m; | 252 SkMatrix m; |
231 m.setTranslate(dx, dy); | 253 m.setTranslate(dx, dy); |
232 return this->preConcat(m); | 254 return this->preConcat(m); |
233 } | 255 } |
234 | 256 |
235 if (dx || dy) { | 257 if (dx || dy) { |
236 fMat[kMTransX] += SkScalarMul(fMat[kMScaleX], dx) + | 258 fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy); |
237 SkScalarMul(fMat[kMSkewX], dy); | 259 fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy); |
238 fMat[kMTransY] += SkScalarMul(fMat[kMSkewY], dx) + | |
239 SkScalarMul(fMat[kMScaleY], dy); | |
240 | 260 |
241 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 261 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
242 } | 262 } |
243 return true; | 263 return true; |
244 } | 264 } |
245 | 265 |
246 bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { | 266 bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { |
247 if (this->hasPerspective()) { | 267 if (this->hasPerspective()) { |
248 SkMatrix m; | 268 SkMatrix m; |
249 m.setTranslate(dx, dy); | 269 m.setTranslate(dx, dy); |
250 return this->postConcat(m); | 270 return this->postConcat(m); |
251 } | 271 } |
252 | 272 |
253 if (dx || dy) { | 273 if (dx || dy) { |
254 fMat[kMTransX] += dx; | 274 fMat[kMTransX] += dx; |
255 fMat[kMTransY] += dy; | 275 fMat[kMTransY] += dy; |
256 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 276 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
257 } | 277 } |
258 return true; | 278 return true; |
259 } | 279 } |
260 | 280 |
261 /////////////////////////////////////////////////////////////////////////////// | 281 /////////////////////////////////////////////////////////////////////////////// |
262 | 282 |
263 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 283 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
264 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 284 if (1 == sx && 1 == sy) { |
265 this->reset(); | 285 this->reset(); |
266 } else { | 286 } else { |
267 fMat[kMScaleX] = sx; | 287 fMat[kMScaleX] = sx; |
268 fMat[kMScaleY] = sy; | 288 fMat[kMScaleY] = sy; |
269 fMat[kMTransX] = px - SkScalarMul(sx, px); | 289 fMat[kMTransX] = px - sx * px; |
270 fMat[kMTransY] = py - SkScalarMul(sy, py); | 290 fMat[kMTransY] = py - sy * py; |
271 fMat[kMPersp2] = kMatrix22Elem; | 291 fMat[kMPersp2] = 1; |
272 | 292 |
273 fMat[kMSkewX] = fMat[kMSkewY] = | 293 fMat[kMSkewX] = fMat[kMSkewY] = |
274 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 294 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
275 | 295 |
276 this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask); | 296 this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask); |
277 } | 297 } |
278 } | 298 } |
279 | 299 |
280 void SkMatrix::setScale(SkScalar sx, SkScalar sy) { | 300 void SkMatrix::setScale(SkScalar sx, SkScalar sy) { |
281 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 301 if (1 == sx && 1 == sy) { |
282 this->reset(); | 302 this->reset(); |
283 } else { | 303 } else { |
284 fMat[kMScaleX] = sx; | 304 fMat[kMScaleX] = sx; |
285 fMat[kMScaleY] = sy; | 305 fMat[kMScaleY] = sy; |
286 fMat[kMPersp2] = kMatrix22Elem; | 306 fMat[kMPersp2] = 1; |
287 | 307 |
288 fMat[kMTransX] = fMat[kMTransY] = | 308 fMat[kMTransX] = fMat[kMTransY] = |
289 fMat[kMSkewX] = fMat[kMSkewY] = | 309 fMat[kMSkewX] = fMat[kMSkewY] = |
290 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 310 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
291 | 311 |
292 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); | 312 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); |
293 } | 313 } |
294 } | 314 } |
295 | 315 |
296 bool SkMatrix::setIDiv(int divx, int divy) { | 316 bool SkMatrix::setIDiv(int divx, int divy) { |
297 if (!divx || !divy) { | 317 if (!divx || !divy) { |
298 return false; | 318 return false; |
299 } | 319 } |
300 this->setScale(SK_Scalar1 / divx, SK_Scalar1 / divy); | 320 this->setScale(SkScalarInvert(divx), SkScalarInvert(divy)); |
caryclark
2014/01/30 21:19:10
This makes me think that SkScalarInvert is special
reed1
2014/01/30 21:38:52
1. I always imaging that we could somehow be faste
| |
301 return true; | 321 return true; |
302 } | 322 } |
303 | 323 |
304 bool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 324 bool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
305 SkMatrix m; | 325 SkMatrix m; |
306 m.setScale(sx, sy, px, py); | 326 m.setScale(sx, sy, px, py); |
307 return this->preConcat(m); | 327 return this->preConcat(m); |
308 } | 328 } |
309 | 329 |
310 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) { | 330 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) { |
311 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 331 if (1 == sx && 1 == sy) { |
312 return true; | 332 return true; |
313 } | 333 } |
314 | 334 |
315 // the assumption is that these multiplies are very cheap, and that | 335 // the assumption is that these multiplies are very cheap, and that |
316 // a full concat and/or just computing the matrix type is more expensive. | 336 // a full concat and/or just computing the matrix type is more expensive. |
317 // Also, the fixed-point case checks for overflow, but the float doesn't, | 337 // Also, the fixed-point case checks for overflow, but the float doesn't, |
318 // so we can get away with these blind multiplies. | 338 // so we can get away with these blind multiplies. |
319 | 339 |
320 fMat[kMScaleX] = SkScalarMul(fMat[kMScaleX], sx); | 340 fMat[kMScaleX] *= sx; |
321 fMat[kMSkewY] = SkScalarMul(fMat[kMSkewY], sx); | 341 fMat[kMSkewY] *= sx; |
322 fMat[kMPersp0] = SkScalarMul(fMat[kMPersp0], sx); | 342 fMat[kMPersp0] *= sx; |
323 | 343 |
324 fMat[kMSkewX] = SkScalarMul(fMat[kMSkewX], sy); | 344 fMat[kMSkewX] *= sy; |
325 fMat[kMScaleY] = SkScalarMul(fMat[kMScaleY], sy); | 345 fMat[kMScaleY] *= sy; |
326 fMat[kMPersp1] = SkScalarMul(fMat[kMPersp1], sy); | 346 fMat[kMPersp1] *= sy; |
327 | 347 |
328 this->orTypeMask(kScale_Mask); | 348 this->orTypeMask(kScale_Mask); |
329 return true; | 349 return true; |
330 } | 350 } |
331 | 351 |
332 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 352 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
333 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 353 if (1 == sx && 1 == sy) { |
334 return true; | 354 return true; |
335 } | 355 } |
336 SkMatrix m; | 356 SkMatrix m; |
337 m.setScale(sx, sy, px, py); | 357 m.setScale(sx, sy, px, py); |
338 return this->postConcat(m); | 358 return this->postConcat(m); |
339 } | 359 } |
340 | 360 |
341 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) { | 361 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) { |
342 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 362 if (1 == sx && 1 == sy) { |
343 return true; | 363 return true; |
344 } | 364 } |
345 SkMatrix m; | 365 SkMatrix m; |
346 m.setScale(sx, sy); | 366 m.setScale(sx, sy); |
347 return this->postConcat(m); | 367 return this->postConcat(m); |
348 } | 368 } |
349 | 369 |
350 // this guy perhaps can go away, if we have a fract/high-precision way to | 370 // this guy perhaps can go away, if we have a fract/high-precision way to |
351 // scale matrices | 371 // scale matrices |
352 bool SkMatrix::postIDiv(int divx, int divy) { | 372 bool SkMatrix::postIDiv(int divx, int divy) { |
(...skipping 13 matching lines...) Expand all Loading... | |
366 fMat[kMTransY] *= invY; | 386 fMat[kMTransY] *= invY; |
367 | 387 |
368 this->setTypeMask(kUnknown_Mask); | 388 this->setTypeMask(kUnknown_Mask); |
369 return true; | 389 return true; |
370 } | 390 } |
371 | 391 |
372 //////////////////////////////////////////////////////////////////////////////// //// | 392 //////////////////////////////////////////////////////////////////////////////// //// |
373 | 393 |
374 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, | 394 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, |
375 SkScalar px, SkScalar py) { | 395 SkScalar px, SkScalar py) { |
376 const SkScalar oneMinusCosV = SK_Scalar1 - cosV; | 396 const SkScalar oneMinusCosV = 1 - cosV; |
377 | 397 |
378 fMat[kMScaleX] = cosV; | 398 fMat[kMScaleX] = cosV; |
379 fMat[kMSkewX] = -sinV; | 399 fMat[kMSkewX] = -sinV; |
380 fMat[kMTransX] = SkScalarMul(sinV, py) + SkScalarMul(oneMinusCosV, px); | 400 fMat[kMTransX] = sdot(sinV, py, oneMinusCosV, px); |
381 | 401 |
382 fMat[kMSkewY] = sinV; | 402 fMat[kMSkewY] = sinV; |
383 fMat[kMScaleY] = cosV; | 403 fMat[kMScaleY] = cosV; |
384 fMat[kMTransY] = SkScalarMul(-sinV, px) + SkScalarMul(oneMinusCosV, py); | 404 fMat[kMTransY] = sdot(-sinV, px, oneMinusCosV, py); |
385 | 405 |
386 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 406 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
387 fMat[kMPersp2] = kMatrix22Elem; | 407 fMat[kMPersp2] = 1; |
388 | 408 |
389 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 409 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
390 } | 410 } |
391 | 411 |
392 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) { | 412 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) { |
393 fMat[kMScaleX] = cosV; | 413 fMat[kMScaleX] = cosV; |
394 fMat[kMSkewX] = -sinV; | 414 fMat[kMSkewX] = -sinV; |
395 fMat[kMTransX] = 0; | 415 fMat[kMTransX] = 0; |
396 | 416 |
397 fMat[kMSkewY] = sinV; | 417 fMat[kMSkewY] = sinV; |
398 fMat[kMScaleY] = cosV; | 418 fMat[kMScaleY] = cosV; |
399 fMat[kMTransY] = 0; | 419 fMat[kMTransY] = 0; |
400 | 420 |
401 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 421 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
402 fMat[kMPersp2] = kMatrix22Elem; | 422 fMat[kMPersp2] = 1; |
403 | 423 |
404 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 424 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
405 } | 425 } |
406 | 426 |
407 void SkMatrix::setRotate(SkScalar degrees, SkScalar px, SkScalar py) { | 427 void SkMatrix::setRotate(SkScalar degrees, SkScalar px, SkScalar py) { |
408 SkScalar sinV, cosV; | 428 SkScalar sinV, cosV; |
409 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); | 429 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); |
410 this->setSinCos(sinV, cosV, px, py); | 430 this->setSinCos(sinV, cosV, px, py); |
411 } | 431 } |
412 | 432 |
(...skipping 23 matching lines...) Expand all Loading... | |
436 | 456 |
437 bool SkMatrix::postRotate(SkScalar degrees) { | 457 bool SkMatrix::postRotate(SkScalar degrees) { |
438 SkMatrix m; | 458 SkMatrix m; |
439 m.setRotate(degrees); | 459 m.setRotate(degrees); |
440 return this->postConcat(m); | 460 return this->postConcat(m); |
441 } | 461 } |
442 | 462 |
443 //////////////////////////////////////////////////////////////////////////////// //// | 463 //////////////////////////////////////////////////////////////////////////////// //// |
444 | 464 |
445 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 465 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
446 fMat[kMScaleX] = SK_Scalar1; | 466 fMat[kMScaleX] = 1; |
447 fMat[kMSkewX] = sx; | 467 fMat[kMSkewX] = sx; |
448 fMat[kMTransX] = SkScalarMul(-sx, py); | 468 fMat[kMTransX] = -sx * py; |
449 | 469 |
450 fMat[kMSkewY] = sy; | 470 fMat[kMSkewY] = sy; |
451 fMat[kMScaleY] = SK_Scalar1; | 471 fMat[kMScaleY] = 1; |
452 fMat[kMTransY] = SkScalarMul(-sy, px); | 472 fMat[kMTransY] = -sy * px; |
453 | 473 |
454 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 474 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
455 fMat[kMPersp2] = kMatrix22Elem; | 475 fMat[kMPersp2] = 1; |
mtklein
2014/01/30 19:14:55
Is there no value in keeping a name on this to ind
reed1
2014/01/30 20:53:48
The perspective column used to be special, when we
| |
456 | 476 |
457 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 477 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
458 } | 478 } |
459 | 479 |
460 void SkMatrix::setSkew(SkScalar sx, SkScalar sy) { | 480 void SkMatrix::setSkew(SkScalar sx, SkScalar sy) { |
461 fMat[kMScaleX] = SK_Scalar1; | 481 fMat[kMScaleX] = 1; |
462 fMat[kMSkewX] = sx; | 482 fMat[kMSkewX] = sx; |
463 fMat[kMTransX] = 0; | 483 fMat[kMTransX] = 0; |
464 | 484 |
465 fMat[kMSkewY] = sy; | 485 fMat[kMSkewY] = sy; |
466 fMat[kMScaleY] = SK_Scalar1; | 486 fMat[kMScaleY] = 1; |
467 fMat[kMTransY] = 0; | 487 fMat[kMTransY] = 0; |
468 | 488 |
469 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 489 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
470 fMat[kMPersp2] = kMatrix22Elem; | 490 fMat[kMPersp2] = 1; |
471 | 491 |
472 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 492 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
473 } | 493 } |
474 | 494 |
475 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 495 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
476 SkMatrix m; | 496 SkMatrix m; |
477 m.setSkew(sx, sy, px, py); | 497 m.setSkew(sx, sy, px, py); |
478 return this->preConcat(m); | 498 return this->preConcat(m); |
479 } | 499 } |
480 | 500 |
(...skipping 22 matching lines...) Expand all Loading... | |
503 { | 523 { |
504 if (src.isEmpty()) { | 524 if (src.isEmpty()) { |
505 this->reset(); | 525 this->reset(); |
506 return false; | 526 return false; |
507 } | 527 } |
508 | 528 |
509 if (dst.isEmpty()) { | 529 if (dst.isEmpty()) { |
510 sk_bzero(fMat, 8 * sizeof(SkScalar)); | 530 sk_bzero(fMat, 8 * sizeof(SkScalar)); |
511 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); | 531 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); |
512 } else { | 532 } else { |
513 SkScalar tx, sx = SkScalarDiv(dst.width(), src.width()); | 533 SkScalar tx, sx = dst.width() / src.width(); |
514 SkScalar ty, sy = SkScalarDiv(dst.height(), src.height()); | 534 SkScalar ty, sy = dst.height() / src.height(); |
515 bool xLarger = false; | 535 bool xLarger = false; |
516 | 536 |
517 if (align != kFill_ScaleToFit) { | 537 if (align != kFill_ScaleToFit) { |
518 if (sx > sy) { | 538 if (sx > sy) { |
519 xLarger = true; | 539 xLarger = true; |
520 sx = sy; | 540 sx = sy; |
521 } else { | 541 } else { |
522 sy = sx; | 542 sy = sx; |
523 } | 543 } |
524 } | 544 } |
525 | 545 |
526 tx = dst.fLeft - SkScalarMul(src.fLeft, sx); | 546 tx = dst.fLeft - src.fLeft * sx; |
527 ty = dst.fTop - SkScalarMul(src.fTop, sy); | 547 ty = dst.fTop - src.fTop * sy; |
528 if (align == kCenter_ScaleToFit || align == kEnd_ScaleToFit) { | 548 if (align == kCenter_ScaleToFit || align == kEnd_ScaleToFit) { |
529 SkScalar diff; | 549 SkScalar diff; |
530 | 550 |
531 if (xLarger) { | 551 if (xLarger) { |
532 diff = dst.width() - SkScalarMul(src.width(), sy); | 552 diff = dst.width() - src.width() * sy; |
533 } else { | 553 } else { |
534 diff = dst.height() - SkScalarMul(src.height(), sy); | 554 diff = dst.height() - src.height() * sy; |
535 } | 555 } |
536 | 556 |
537 if (align == kCenter_ScaleToFit) { | 557 if (align == kCenter_ScaleToFit) { |
538 diff = SkScalarHalf(diff); | 558 diff = SkScalarHalf(diff); |
539 } | 559 } |
540 | 560 |
541 if (xLarger) { | 561 if (xLarger) { |
542 tx += diff; | 562 tx += diff; |
543 } else { | 563 } else { |
544 ty += diff; | 564 ty += diff; |
545 } | 565 } |
546 } | 566 } |
547 | 567 |
548 fMat[kMScaleX] = sx; | 568 fMat[kMScaleX] = sx; |
549 fMat[kMScaleY] = sy; | 569 fMat[kMScaleY] = sy; |
550 fMat[kMTransX] = tx; | 570 fMat[kMTransX] = tx; |
551 fMat[kMTransY] = ty; | 571 fMat[kMTransY] = ty; |
552 fMat[kMSkewX] = fMat[kMSkewY] = | 572 fMat[kMSkewX] = fMat[kMSkewY] = |
553 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 573 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
554 | 574 |
555 unsigned mask = kRectStaysRect_Mask; | 575 unsigned mask = kRectStaysRect_Mask; |
556 if (sx != SK_Scalar1 || sy != SK_Scalar1) { | 576 if (sx != 1 || sy != 1) { |
557 mask |= kScale_Mask; | 577 mask |= kScale_Mask; |
558 } | 578 } |
559 if (tx || ty) { | 579 if (tx || ty) { |
560 mask |= kTranslate_Mask; | 580 mask |= kTranslate_Mask; |
561 } | 581 } |
562 this->setTypeMask(mask); | 582 this->setTypeMask(mask); |
563 } | 583 } |
564 // shared cleanup | 584 // shared cleanup |
565 fMat[kMPersp2] = kMatrix22Elem; | 585 fMat[kMPersp2] = 1; |
566 return true; | 586 return true; |
567 } | 587 } |
568 | 588 |
569 /////////////////////////////////////////////////////////////////////////////// | 589 /////////////////////////////////////////////////////////////////////////////// |
570 | 590 |
571 static inline int fixmuladdmul(float a, float b, float c, float d, | 591 static inline int fixmuladdmul(float a, float b, float c, float d, |
572 float* result) { | 592 float* result) { |
573 *result = SkDoubleToFloat((double)a * b + (double)c * d); | 593 *result = SkDoubleToFloat((double)a * b + (double)c * d); |
574 return true; | 594 return true; |
575 } | 595 } |
576 | 596 |
577 static inline bool rowcol3(const float row[], const float col[], | 597 static inline bool rowcol3(const float row[], const float col[], |
578 float* result) { | 598 float* result) { |
579 *result = row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; | 599 *result = row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; |
580 return true; | 600 return true; |
581 } | 601 } |
582 | 602 |
583 static inline int negifaddoverflows(float& result, float a, float b) { | 603 static inline int negifaddoverflows(float& result, float a, float b) { |
584 result = a + b; | 604 result = a + b; |
585 return 0; | 605 return 0; |
586 } | 606 } |
587 | 607 |
588 static void normalize_perspective(SkScalar mat[9]) { | 608 static void normalize_perspective(SkScalar mat[9]) { |
589 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > kMatrix22Elem) { | 609 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) { |
590 for (int i = 0; i < 9; i++) | 610 for (int i = 0; i < 9; i++) |
591 mat[i] = SkScalarHalf(mat[i]); | 611 mat[i] = SkScalarHalf(mat[i]); |
592 } | 612 } |
593 } | 613 } |
594 | 614 |
595 bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { | 615 bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { |
596 TypeMask aType = a.getPerspectiveTypeMaskOnly(); | 616 TypeMask aType = a.getPerspectiveTypeMaskOnly(); |
597 TypeMask bType = b.getPerspectiveTypeMaskOnly(); | 617 TypeMask bType = b.getPerspectiveTypeMaskOnly(); |
598 | 618 |
599 if (a.isTriviallyIdentity()) { | 619 if (a.isTriviallyIdentity()) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMTransX], | 685 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMTransX], |
666 a.fMat[kMScaleY], b.fMat[kMTransY], &tmp.fMat[kMTransY])) { | 686 a.fMat[kMScaleY], b.fMat[kMTransY], &tmp.fMat[kMTransY])) { |
667 return false; | 687 return false; |
668 } | 688 } |
669 if (negifaddoverflows(tmp.fMat[kMTransY], tmp.fMat[kMTransY], | 689 if (negifaddoverflows(tmp.fMat[kMTransY], tmp.fMat[kMTransY], |
670 a.fMat[kMTransY]) < 0) { | 690 a.fMat[kMTransY]) < 0) { |
671 return false; | 691 return false; |
672 } | 692 } |
673 | 693 |
674 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; | 694 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; |
675 tmp.fMat[kMPersp2] = kMatrix22Elem; | 695 tmp.fMat[kMPersp2] = 1; |
676 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); | 696 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); |
677 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); | 697 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); |
678 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 698 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
679 } | 699 } |
680 *this = tmp; | 700 *this = tmp; |
681 } | 701 } |
682 return true; | 702 return true; |
683 } | 703 } |
684 | 704 |
685 bool SkMatrix::preConcat(const SkMatrix& mat) { | 705 bool SkMatrix::preConcat(const SkMatrix& mat) { |
686 // check for identity first, so we don't do a needless copy of ourselves | 706 // check for identity first, so we don't do a needless copy of ourselves |
687 // to ourselves inside setConcat() | 707 // to ourselves inside setConcat() |
688 return mat.isIdentity() || this->setConcat(*this, mat); | 708 return mat.isIdentity() || this->setConcat(*this, mat); |
689 } | 709 } |
690 | 710 |
691 bool SkMatrix::postConcat(const SkMatrix& mat) { | 711 bool SkMatrix::postConcat(const SkMatrix& mat) { |
692 // check for identity first, so we don't do a needless copy of ourselves | 712 // check for identity first, so we don't do a needless copy of ourselves |
693 // to ourselves inside setConcat() | 713 // to ourselves inside setConcat() |
694 return mat.isIdentity() || this->setConcat(mat, *this); | 714 return mat.isIdentity() || this->setConcat(mat, *this); |
695 } | 715 } |
696 | 716 |
697 /////////////////////////////////////////////////////////////////////////////// | 717 /////////////////////////////////////////////////////////////////////////////// |
698 | 718 |
699 /* Matrix inversion is very expensive, but also the place where keeping | 719 /* Matrix inversion is very expensive, but also the place where keeping |
700 precision may be most important (here and matrix concat). Hence to avoid | 720 precision may be most important (here and matrix concat). Hence to avoid |
701 bitmap blitting artifacts when walking the inverse, we use doubles for | 721 bitmap blitting artifacts when walking the inverse, we use doubles for |
702 the intermediate math, even though we know that is more expensive. | 722 the intermediate math, even though we know that is more expensive. |
703 */ | 723 */ |
704 | 724 |
705 typedef double SkDetScalar; | 725 static inline double dcross(double a, double b, double c, double d) { |
706 #define SkPerspMul(a, b) SkScalarMul(a, b) | 726 return a * b - c * d; |
707 #define SkScalarMulShift(a, b, s) SkDoubleToFloat((a) * (b)) | 727 } |
708 static double sk_inv_determinant(const float mat[9], int isPerspective, | 728 |
709 int* /* (only used in Fixed case) */) { | 729 static double sk_inv_determinant(const float mat[9], int isPerspective) { |
710 double det; | 730 double det; |
711 | 731 |
712 if (isPerspective) { | 732 if (isPerspective) { |
713 det = mat[SkMatrix::kMScaleX] * ((double)mat[SkMatrix::kMScaleY] * mat [SkMatrix::kMPersp2] - (double)mat[SkMatrix::kMTransY] * mat[SkMatrix::kMPersp1] ) + | 733 det = mat[SkMatrix::kMScaleX] * dcross(mat[SkMatrix::kMScaleY], mat[SkMa trix::kMPersp2], mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp1]) + |
mtklein
2014/01/30 19:14:55
These lines are pretty hard to parse (they were be
reed1
2014/01/30 20:53:48
Done.
caryclark
2014/01/30 21:19:10
Or, if this was a member of SkMatrix, it would be
reed1
2014/01/30 21:38:52
My rewrite address the 100 chars, but I agree that
| |
714 mat[SkMatrix::kMSkewX] * ((double)mat[SkMatrix::kMTransY] * mat[ SkMatrix::kMPersp0] - (double)mat[SkMatrix::kMSkewY] * mat[SkMatrix::kMPersp2]) + | 734 mat[SkMatrix::kMSkewX] * dcross(mat[SkMatrix::kMTransY], mat[SkMa trix::kMPersp0], mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp2]) + |
715 mat[SkMatrix::kMTransX] * ((double)mat[SkMatrix::kMSkewY] * mat[ SkMatrix::kMPersp1] - (double)mat[SkMatrix::kMScaleY] * mat[SkMatrix::kMPersp0]) ; | 735 mat[SkMatrix::kMTransX] * dcross(mat[SkMatrix::kMSkewY], mat[SkMa trix::kMPersp1], mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp0]); |
716 } else { | 736 } else { |
717 det = (double)mat[SkMatrix::kMScaleX] * mat[SkMatrix::kMScaleY] - (dou ble)mat[SkMatrix::kMSkewX] * mat[SkMatrix::kMSkewY]; | 737 det = dcross(mat[SkMatrix::kMScaleX], mat[SkMatrix::kMScaleY], mat[SkMa trix::kMSkewX], mat[SkMatrix::kMSkewY]); |
718 } | 738 } |
719 | 739 |
720 // Since the determinant is on the order of the cube of the matrix members, | 740 // Since the determinant is on the order of the cube of the matrix members, |
721 // compare to the cube of the default nearly-zero constant (although an | 741 // compare to the cube of the default nearly-zero constant (although an |
722 // estimate of the condition number would be better if it wasn't so expensiv e). | 742 // estimate of the condition number would be better if it wasn't so expensiv e). |
723 if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero * SK_ScalarNearlyZero)) { | 743 if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero * SK_ScalarNearlyZero)) { |
724 return 0; | 744 return 0; |
725 } | 745 } |
726 return 1.0 / det; | 746 return 1.0 / det; |
727 } | 747 } |
728 // we declar a,b,c,d to all be doubles, because we want to perform | 748 // we declar a,b,c,d to all be doubles, because we want to perform |
729 // double-precision muls and subtract, even though the original values are | 749 // double-precision muls and subtract, even though the original values are |
730 // from the matrix, which are floats. | 750 // from the matrix, which are floats. |
731 static float inline mul_diff_scale(double a, double b, double c, double d, | 751 static SkScalar inline mul_diff_scale(double a, double b, double c, double d, |
mtklein
2014/01/30 19:14:55
mul_diff_scale might be better named dcross_scale?
reed1
2014/01/30 20:53:48
That guy is now unused. deleting.
| |
732 double scale) { | 752 double scale) { |
733 return SkDoubleToFloat((a * b - c * d) * scale); | 753 return SkDoubleToScalar(dcross(a, b, c, d) * scale); |
734 } | 754 } |
735 | 755 |
736 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) { | 756 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) { |
737 affine[kAScaleX] = SK_Scalar1; | 757 affine[kAScaleX] = 1; |
738 affine[kASkewY] = 0; | 758 affine[kASkewY] = 0; |
739 affine[kASkewX] = 0; | 759 affine[kASkewX] = 0; |
740 affine[kAScaleY] = SK_Scalar1; | 760 affine[kAScaleY] = 1; |
741 affine[kATransX] = 0; | 761 affine[kATransX] = 0; |
742 affine[kATransY] = 0; | 762 affine[kATransY] = 0; |
743 } | 763 } |
744 | 764 |
745 bool SkMatrix::asAffine(SkScalar affine[6]) const { | 765 bool SkMatrix::asAffine(SkScalar affine[6]) const { |
746 if (this->hasPerspective()) { | 766 if (this->hasPerspective()) { |
747 return false; | 767 return false; |
748 } | 768 } |
749 if (affine) { | 769 if (affine) { |
750 affine[kAScaleX] = this->fMat[kMScaleX]; | 770 affine[kAScaleX] = this->fMat[kMScaleX]; |
(...skipping 24 matching lines...) Expand all Loading... | |
775 invY = SkScalarInvert(invY); | 795 invY = SkScalarInvert(invY); |
776 | 796 |
777 // Must be careful when writing to inv, since it may be the | 797 // Must be careful when writing to inv, since it may be the |
778 // same memory as this. | 798 // same memory as this. |
779 | 799 |
780 inv->fMat[kMSkewX] = inv->fMat[kMSkewY] = | 800 inv->fMat[kMSkewX] = inv->fMat[kMSkewY] = |
781 inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0; | 801 inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0; |
782 | 802 |
783 inv->fMat[kMScaleX] = invX; | 803 inv->fMat[kMScaleX] = invX; |
784 inv->fMat[kMScaleY] = invY; | 804 inv->fMat[kMScaleY] = invY; |
785 inv->fMat[kMPersp2] = kMatrix22Elem; | 805 inv->fMat[kMPersp2] = 1; |
786 inv->fMat[kMTransX] = -SkScalarMul(fMat[kMTransX], invX); | 806 inv->fMat[kMTransX] = -fMat[kMTransX] * invX; |
787 inv->fMat[kMTransY] = -SkScalarMul(fMat[kMTransY], invY); | 807 inv->fMat[kMTransY] = -fMat[kMTransY] * invY; |
788 | 808 |
789 inv->setTypeMask(mask | kRectStaysRect_Mask); | 809 inv->setTypeMask(mask | kRectStaysRect_Mask); |
790 } else { | 810 } else { |
791 // translate only | 811 // translate only |
792 inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]); | 812 inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]); |
793 } | 813 } |
794 } else { // inv is NULL, just check if we're invertible | 814 } else { // inv is NULL, just check if we're invertible |
795 if (!fMat[kMScaleX] || !fMat[kMScaleY]) { | 815 if (!fMat[kMScaleX] || !fMat[kMScaleY]) { |
796 invertible = false; | 816 invertible = false; |
797 } | 817 } |
798 } | 818 } |
799 return invertible; | 819 return invertible; |
800 } | 820 } |
801 | 821 |
802 int isPersp = mask & kPerspective_Mask; | 822 int isPersp = mask & kPerspective_Mask; |
803 int shift; | 823 double scale = sk_inv_determinant(fMat, isPersp); |
804 SkDetScalar scale = sk_inv_determinant(fMat, isPersp, &shift); | |
805 | 824 |
806 if (scale == 0) { // underflow | 825 if (scale == 0) { // underflow |
807 return false; | 826 return false; |
808 } | 827 } |
809 | 828 |
810 if (inv) { | 829 if (inv) { |
811 SkMatrix tmp; | 830 SkMatrix tmp; |
812 if (inv == this) { | 831 if (inv == this) { |
813 inv = &tmp; | 832 inv = &tmp; |
814 } | 833 } |
815 | 834 |
816 if (isPersp) { | 835 if (isPersp) { |
817 shift = 61 - shift; | 836 inv->fMat[kMScaleX] = SkDoubleToScalar(scross(fMat[kMScaleY], fMat[k MPersp2], fMat[kMTransY], fMat[kMPersp1]) * scale); |
mtklein
2014/01/30 19:14:55
This part is also pretty hard to parse. could be
| |
818 inv->fMat[kMScaleX] = SkScalarMulShift(SkPerspMul(fMat[kMScaleY], fM at[kMPersp2]) - SkPerspMul(fMat[kMTransY], fMat[kMPersp1]), scale, shift); | 837 inv->fMat[kMSkewX] = SkDoubleToScalar(scross(fMat[kMTransX], fMat[k MPersp1], fMat[kMSkewX], fMat[kMPersp2]) * scale); |
819 inv->fMat[kMSkewX] = SkScalarMulShift(SkPerspMul(fMat[kMTransX], fM at[kMPersp1]) - SkPerspMul(fMat[kMSkewX], fMat[kMPersp2]), scale, shift); | 838 inv->fMat[kMTransX] = SkDoubleToScalar(scross(fMat[kMSkewX], fMat[k MTransY], fMat[kMTransX], fMat[kMScaleY]) * scale); |
820 inv->fMat[kMTransX] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM at[kMTransY]) - SkScalarMul(fMat[kMTransX], fMat[kMScaleY]), scale, shift); | |
821 | 839 |
822 inv->fMat[kMSkewY] = SkScalarMulShift(SkPerspMul(fMat[kMTransY], fM at[kMPersp0]) - SkPerspMul(fMat[kMSkewY], fMat[kMPersp2]), scale, shift); | 840 inv->fMat[kMSkewY] = SkDoubleToScalar(scross(fMat[kMTransY], fMat[k MPersp0], fMat[kMSkewY], fMat[kMPersp2]) * scale); |
823 inv->fMat[kMScaleY] = SkScalarMulShift(SkPerspMul(fMat[kMScaleX], fM at[kMPersp2]) - SkPerspMul(fMat[kMTransX], fMat[kMPersp0]), scale, shift); | 841 inv->fMat[kMScaleY] = SkDoubleToScalar(scross(fMat[kMScaleX], fMat[k MPersp2], fMat[kMTransX], fMat[kMPersp0]) * scale); |
824 inv->fMat[kMTransY] = SkScalarMulShift(SkScalarMul(fMat[kMTransX], f Mat[kMSkewY]) - SkScalarMul(fMat[kMScaleX], fMat[kMTransY]), scale, shift); | 842 inv->fMat[kMTransY] = SkDoubleToScalar(scross(fMat[kMTransX], fMat[k MSkewY], fMat[kMScaleX], fMat[kMTransY]) * scale); |
825 | 843 |
826 inv->fMat[kMPersp0] = SkScalarMulShift(SkScalarMul(fMat[kMSkewY], fM at[kMPersp1]) - SkScalarMul(fMat[kMScaleY], fMat[kMPersp0]), scale, shift); | 844 inv->fMat[kMPersp0] = SkDoubleToScalar(scross(fMat[kMSkewY], fMat[k MPersp1], fMat[kMScaleY], fMat[kMPersp0]) * scale); |
827 inv->fMat[kMPersp1] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM at[kMPersp0]) - SkScalarMul(fMat[kMScaleX], fMat[kMPersp1]), scale, shift); | 845 inv->fMat[kMPersp1] = SkDoubleToScalar(scross(fMat[kMSkewX], fMat[k MPersp0], fMat[kMScaleX], fMat[kMPersp1]) * scale); |
828 inv->fMat[kMPersp2] = SkScalarMulShift(SkScalarMul(fMat[kMScaleX], f Mat[kMScaleY]) - SkScalarMul(fMat[kMSkewX], fMat[kMSkewY]), scale, shift); | 846 inv->fMat[kMPersp2] = SkDoubleToScalar(scross(fMat[kMScaleX], fMat[k MScaleY], fMat[kMSkewX], fMat[kMSkewY]) * scale); |
829 } else { // not perspective | 847 } else { // not perspective |
830 inv->fMat[kMScaleX] = SkDoubleToFloat(fMat[kMScaleY] * scale); | 848 inv->fMat[kMScaleX] = SkDoubleToScalar(fMat[kMScaleY] * scale); |
831 inv->fMat[kMSkewX] = SkDoubleToFloat(-fMat[kMSkewX] * scale); | 849 inv->fMat[kMSkewX] = SkDoubleToScalar(-fMat[kMSkewX] * scale); |
832 inv->fMat[kMTransX] = mul_diff_scale(fMat[kMSkewX], fMat[kMTransY], | 850 inv->fMat[kMTransX] = SkDoubleToScalar(dcross(fMat[kMSkewX], fMat[kM TransY], fMat[kMScaleY], fMat[kMTransX]) * scale); |
mtklein
2014/01/30 19:14:55
Why switch away from mul_diff_scale here?
reed1
2014/01/30 20:53:48
Done.
| |
833 fMat[kMScaleY], fMat[kMTransX], scale); | |
834 | 851 |
835 inv->fMat[kMSkewY] = SkDoubleToFloat(-fMat[kMSkewY] * scale); | 852 inv->fMat[kMSkewY] = SkDoubleToScalar(-fMat[kMSkewY] * scale); |
836 inv->fMat[kMScaleY] = SkDoubleToFloat(fMat[kMScaleX] * scale); | 853 inv->fMat[kMScaleY] = SkDoubleToScalar(fMat[kMScaleX] * scale); |
837 inv->fMat[kMTransY] = mul_diff_scale(fMat[kMSkewY], fMat[kMTransX], | 854 inv->fMat[kMTransY] = SkDoubleToScalar(dcross(fMat[kMSkewY], fMat[kM TransX], fMat[kMScaleX], fMat[kMTransY]) * scale); |
mtklein
2014/01/30 19:14:55
Same?
reed1
2014/01/30 20:53:48
Done.
| |
838 fMat[kMScaleX], fMat[kMTransY], scale); | |
839 | 855 |
840 inv->fMat[kMPersp0] = 0; | 856 inv->fMat[kMPersp0] = 0; |
841 inv->fMat[kMPersp1] = 0; | 857 inv->fMat[kMPersp1] = 0; |
842 inv->fMat[kMPersp2] = kMatrix22Elem; | 858 inv->fMat[kMPersp2] = 1; |
843 | 859 |
844 } | 860 } |
845 | 861 |
846 inv->setTypeMask(fTypeMask); | 862 inv->setTypeMask(fTypeMask); |
847 | 863 |
848 if (inv == &tmp) { | 864 if (inv == &tmp) { |
849 *(SkMatrix*)this = tmp; | 865 *(SkMatrix*)this = tmp; |
850 } | 866 } |
851 } | 867 } |
852 return true; | 868 return true; |
(...skipping 26 matching lines...) Expand all Loading... | |
879 } | 895 } |
880 | 896 |
881 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], | 897 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], |
882 const SkPoint src[], int count) { | 898 const SkPoint src[], int count) { |
883 SkASSERT(m.getType() == kScale_Mask); | 899 SkASSERT(m.getType() == kScale_Mask); |
884 | 900 |
885 if (count > 0) { | 901 if (count > 0) { |
886 SkScalar mx = m.fMat[kMScaleX]; | 902 SkScalar mx = m.fMat[kMScaleX]; |
887 SkScalar my = m.fMat[kMScaleY]; | 903 SkScalar my = m.fMat[kMScaleY]; |
888 do { | 904 do { |
889 dst->fY = SkScalarMul(src->fY, my); | 905 dst->fY = src->fY * my; |
890 dst->fX = SkScalarMul(src->fX, mx); | 906 dst->fX = src->fX * mx; |
891 src += 1; | 907 src += 1; |
892 dst += 1; | 908 dst += 1; |
893 } while (--count); | 909 } while (--count); |
894 } | 910 } |
895 } | 911 } |
896 | 912 |
897 void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], | 913 void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], |
898 const SkPoint src[], int count) { | 914 const SkPoint src[], int count) { |
899 SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); | 915 SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); |
900 | 916 |
901 if (count > 0) { | 917 if (count > 0) { |
902 SkScalar mx = m.fMat[kMScaleX]; | 918 SkScalar mx = m.fMat[kMScaleX]; |
903 SkScalar my = m.fMat[kMScaleY]; | 919 SkScalar my = m.fMat[kMScaleY]; |
904 SkScalar tx = m.fMat[kMTransX]; | 920 SkScalar tx = m.fMat[kMTransX]; |
905 SkScalar ty = m.fMat[kMTransY]; | 921 SkScalar ty = m.fMat[kMTransY]; |
906 do { | 922 do { |
907 dst->fY = SkScalarMulAdd(src->fY, my, ty); | 923 dst->fY = src->fY * my + ty; |
908 dst->fX = SkScalarMulAdd(src->fX, mx, tx); | 924 dst->fX = src->fX * mx + tx; |
909 src += 1; | 925 src += 1; |
910 dst += 1; | 926 dst += 1; |
911 } while (--count); | 927 } while (--count); |
912 } | 928 } |
913 } | 929 } |
914 | 930 |
915 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[], | 931 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[], |
916 const SkPoint src[], int count) { | 932 const SkPoint src[], int count) { |
917 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0); | 933 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0); |
918 | 934 |
919 if (count > 0) { | 935 if (count > 0) { |
920 SkScalar mx = m.fMat[kMScaleX]; | 936 SkScalar mx = m.fMat[kMScaleX]; |
921 SkScalar my = m.fMat[kMScaleY]; | 937 SkScalar my = m.fMat[kMScaleY]; |
922 SkScalar kx = m.fMat[kMSkewX]; | 938 SkScalar kx = m.fMat[kMSkewX]; |
923 SkScalar ky = m.fMat[kMSkewY]; | 939 SkScalar ky = m.fMat[kMSkewY]; |
924 do { | 940 do { |
925 SkScalar sy = src->fY; | 941 SkScalar sy = src->fY; |
926 SkScalar sx = src->fX; | 942 SkScalar sx = src->fX; |
927 src += 1; | 943 src += 1; |
928 dst->fY = SkScalarMul(sx, ky) + SkScalarMul(sy, my); | 944 dst->fY = sdot(sx, ky, sy, my); |
929 dst->fX = SkScalarMul(sx, mx) + SkScalarMul(sy, kx); | 945 dst->fX = sdot(sx, mx, sy, kx); |
930 dst += 1; | 946 dst += 1; |
931 } while (--count); | 947 } while (--count); |
932 } | 948 } |
933 } | 949 } |
934 | 950 |
935 void SkMatrix::RotTrans_pts(const SkMatrix& m, SkPoint dst[], | 951 void SkMatrix::RotTrans_pts(const SkMatrix& m, SkPoint dst[], |
936 const SkPoint src[], int count) { | 952 const SkPoint src[], int count) { |
937 SkASSERT(!m.hasPerspective()); | 953 SkASSERT(!m.hasPerspective()); |
938 | 954 |
939 if (count > 0) { | 955 if (count > 0) { |
940 SkScalar mx = m.fMat[kMScaleX]; | 956 SkScalar mx = m.fMat[kMScaleX]; |
941 SkScalar my = m.fMat[kMScaleY]; | 957 SkScalar my = m.fMat[kMScaleY]; |
942 SkScalar kx = m.fMat[kMSkewX]; | 958 SkScalar kx = m.fMat[kMSkewX]; |
943 SkScalar ky = m.fMat[kMSkewY]; | 959 SkScalar ky = m.fMat[kMSkewY]; |
944 SkScalar tx = m.fMat[kMTransX]; | 960 SkScalar tx = m.fMat[kMTransX]; |
945 SkScalar ty = m.fMat[kMTransY]; | 961 SkScalar ty = m.fMat[kMTransY]; |
946 do { | 962 do { |
947 SkScalar sy = src->fY; | 963 SkScalar sy = src->fY; |
948 SkScalar sx = src->fX; | 964 SkScalar sx = src->fX; |
949 src += 1; | 965 src += 1; |
950 dst->fY = SkScalarMul(sx, ky) + SkScalarMulAdd(sy, my, ty); | 966 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
951 dst->fX = SkScalarMul(sx, mx) + SkScalarMulAdd(sy, kx, tx); | 967 dst->fY = sx * ky + (sy * my + ty); |
968 dst->fX = sx * mx + (sy * kx + tx); | |
969 #else | |
970 dst->fY = sdot(sx, ky, sy, my) + ty; | |
971 dst->fX = sdot(sx, mx, sy, kx) + tx; | |
972 #endif | |
952 dst += 1; | 973 dst += 1; |
953 } while (--count); | 974 } while (--count); |
954 } | 975 } |
955 } | 976 } |
956 | 977 |
957 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], | 978 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], |
958 const SkPoint src[], int count) { | 979 const SkPoint src[], int count) { |
959 SkASSERT(m.hasPerspective()); | 980 SkASSERT(m.hasPerspective()); |
960 | 981 |
961 if (count > 0) { | 982 if (count > 0) { |
962 do { | 983 do { |
963 SkScalar sy = src->fY; | 984 SkScalar sy = src->fY; |
964 SkScalar sx = src->fX; | 985 SkScalar sx = src->fX; |
965 src += 1; | 986 src += 1; |
966 | 987 |
967 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + | 988 SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fM at[kMTransX]; |
968 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; | 989 SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fM at[kMTransY]; |
969 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + | 990 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
970 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; | 991 SkScalar z = sx * m.fMat[kMPersp0] + (sy * m.fMat[kMPersp1] + m.fMat [kMPersp2]); |
971 SkScalar z = SkScalarMul(sx, m.fMat[kMPersp0]) + | 992 #else |
972 SkScalarMulAdd(sy, m.fMat[kMPersp1], m.fMat[kMPersp2]); | 993 SkScalar z = sdot(sx, m.fMat[kMPersp0], sy, m.fMat[kMPersp1]) + m.fM at[kMPersp2]; |
994 #endif | |
973 if (z) { | 995 if (z) { |
974 z = SkScalarFastInvert(z); | 996 z = SkScalarFastInvert(z); |
975 } | 997 } |
976 | 998 |
977 dst->fY = SkScalarMul(y, z); | 999 dst->fY = y * z; |
978 dst->fX = SkScalarMul(x, z); | 1000 dst->fX = x * z; |
979 dst += 1; | 1001 dst += 1; |
980 } while (--count); | 1002 } while (--count); |
981 } | 1003 } |
982 } | 1004 } |
983 | 1005 |
984 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { | 1006 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { |
985 SkMatrix::Identity_pts, SkMatrix::Trans_pts, | 1007 SkMatrix::Identity_pts, SkMatrix::Trans_pts, |
986 SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts, | 1008 SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts, |
987 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, | 1009 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, |
988 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, | 1010 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, |
(...skipping 23 matching lines...) Expand all Loading... | |
1012 if (this->isIdentity()) { | 1034 if (this->isIdentity()) { |
1013 memcpy(dst, src, 3*count*sizeof(SkScalar)); | 1035 memcpy(dst, src, 3*count*sizeof(SkScalar)); |
1014 return; | 1036 return; |
1015 } | 1037 } |
1016 do { | 1038 do { |
1017 SkScalar sx = src[0]; | 1039 SkScalar sx = src[0]; |
1018 SkScalar sy = src[1]; | 1040 SkScalar sy = src[1]; |
1019 SkScalar sw = src[2]; | 1041 SkScalar sw = src[2]; |
1020 src += 3; | 1042 src += 3; |
1021 | 1043 |
1022 SkScalar x = SkScalarMul(sx, fMat[kMScaleX]) + | 1044 SkScalar x = sdot3(sx, fMat[kMScaleX], sy, fMat[kMSkewX], sw, fMat[ kMTransX]); |
1023 SkScalarMul(sy, fMat[kMSkewX]) + | 1045 SkScalar y = sdot3(sx, fMat[kMSkewY], sy, fMat[kMScaleY], sw, fMat[ kMTransY]); |
1024 SkScalarMul(sw, fMat[kMTransX]); | 1046 SkScalar w = sdot3(sx, fMat[kMPersp0], sy, fMat[kMPersp1], sw, fMat[ kMPersp2]); |
1025 SkScalar y = SkScalarMul(sx, fMat[kMSkewY]) + | |
1026 SkScalarMul(sy, fMat[kMScaleY]) + | |
1027 SkScalarMul(sw, fMat[kMTransY]); | |
1028 SkScalar w = SkScalarMul(sx, fMat[kMPersp0]) + | |
1029 SkScalarMul(sy, fMat[kMPersp1]) + | |
1030 SkScalarMul(sw, fMat[kMPersp2]); | |
1031 | 1047 |
1032 dst[0] = x; | 1048 dst[0] = x; |
1033 dst[1] = y; | 1049 dst[1] = y; |
1034 dst[2] = w; | 1050 dst[2] = w; |
1035 dst += 3; | 1051 dst += 3; |
1036 } while (--count); | 1052 } while (--count); |
1037 } | 1053 } |
1038 } | 1054 } |
1039 | 1055 |
1040 /////////////////////////////////////////////////////////////////////////////// | 1056 /////////////////////////////////////////////////////////////////////////////// |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1091 // return geometric mean | 1107 // return geometric mean |
1092 return SkScalarSqrt(d0 * d1); | 1108 return SkScalarSqrt(d0 * d1); |
1093 } | 1109 } |
1094 | 1110 |
1095 /////////////////////////////////////////////////////////////////////////////// | 1111 /////////////////////////////////////////////////////////////////////////////// |
1096 | 1112 |
1097 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1113 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1098 SkPoint* pt) { | 1114 SkPoint* pt) { |
1099 SkASSERT(m.hasPerspective()); | 1115 SkASSERT(m.hasPerspective()); |
1100 | 1116 |
1101 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1117 SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTra nsX]; |
1102 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; | 1118 SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTra nsY]; |
1103 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1119 SkScalar z = sdot(sx, m.fMat[kMPersp0], sy, m.fMat[kMPersp1]) + m.fMat[kMPer sp2]; |
1104 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; | |
1105 SkScalar z = SkScalarMul(sx, m.fMat[kMPersp0]) + | |
1106 SkScalarMul(sy, m.fMat[kMPersp1]) + m.fMat[kMPersp2]; | |
1107 if (z) { | 1120 if (z) { |
1108 z = SkScalarFastInvert(z); | 1121 z = SkScalarFastInvert(z); |
1109 } | 1122 } |
1110 pt->fX = SkScalarMul(x, z); | 1123 pt->fX = x * z; |
1111 pt->fY = SkScalarMul(y, z); | 1124 pt->fY = y * z; |
1112 } | 1125 } |
1113 | 1126 |
1114 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1127 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1115 SkPoint* pt) { | 1128 SkPoint* pt) { |
1116 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask) ; | 1129 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask) ; |
1117 | 1130 |
1118 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1131 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
1119 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); | 1132 pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX]) ; |
1120 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1133 pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]); |
1121 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1134 #else |
1135 pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX] ; | |
1136 pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY] ; | |
1137 #endif | |
1122 } | 1138 } |
1123 | 1139 |
1124 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1140 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1125 SkPoint* pt) { | 1141 SkPoint* pt) { |
1126 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); | 1142 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); |
1127 SkASSERT(0 == m.fMat[kMTransX]); | 1143 SkASSERT(0 == m.fMat[kMTransX]); |
1128 SkASSERT(0 == m.fMat[kMTransY]); | 1144 SkASSERT(0 == m.fMat[kMTransY]); |
1129 | 1145 |
1130 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1146 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
1131 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); | 1147 pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX]); |
1132 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1148 pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]); |
1133 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1149 #else |
1150 pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX] ; | |
1151 pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY] ; | |
1152 #endif | |
1134 } | 1153 } |
1135 | 1154 |
1136 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1155 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1137 SkPoint* pt) { | 1156 SkPoint* pt) { |
1138 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) | 1157 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) |
1139 == kScale_Mask); | 1158 == kScale_Mask); |
1140 | 1159 |
1141 pt->fX = SkScalarMulAdd(sx, m.fMat[kMScaleX], m.fMat[kMTransX]); | 1160 pt->fX = sx * m.fMat[kMScaleX] + m.fMat[kMTransX]; |
1142 pt->fY = SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1161 pt->fY = sy * m.fMat[kMScaleY] + m.fMat[kMTransY]; |
1143 } | 1162 } |
1144 | 1163 |
1145 void SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1164 void SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1146 SkPoint* pt) { | 1165 SkPoint* pt) { |
1147 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) | 1166 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) |
1148 == kScale_Mask); | 1167 == kScale_Mask); |
1149 SkASSERT(0 == m.fMat[kMTransX]); | 1168 SkASSERT(0 == m.fMat[kMTransX]); |
1150 SkASSERT(0 == m.fMat[kMTransY]); | 1169 SkASSERT(0 == m.fMat[kMTransY]); |
1151 | 1170 |
1152 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]); | 1171 pt->fX = sx * m.fMat[kMScaleX]; |
1153 pt->fY = SkScalarMul(sy, m.fMat[kMScaleY]); | 1172 pt->fY = sy * m.fMat[kMScaleY]; |
1154 } | 1173 } |
1155 | 1174 |
1156 void SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1175 void SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1157 SkPoint* pt) { | 1176 SkPoint* pt) { |
1158 SkASSERT(m.getType() == kTranslate_Mask); | 1177 SkASSERT(m.getType() == kTranslate_Mask); |
1159 | 1178 |
1160 pt->fX = sx + m.fMat[kMTransX]; | 1179 pt->fX = sx + m.fMat[kMTransX]; |
1161 pt->fY = sy + m.fMat[kMTransY]; | 1180 pt->fY = sy + m.fMat[kMTransY]; |
1162 } | 1181 } |
1163 | 1182 |
(...skipping 19 matching lines...) Expand all Loading... | |
1183 | 1202 |
1184 /////////////////////////////////////////////////////////////////////////////// | 1203 /////////////////////////////////////////////////////////////////////////////// |
1185 | 1204 |
1186 // if its nearly zero (just made up 26, perhaps it should be bigger or smaller) | 1205 // if its nearly zero (just made up 26, perhaps it should be bigger or smaller) |
1187 #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26))) | 1206 #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26))) |
1188 | 1207 |
1189 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { | 1208 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { |
1190 if (PerspNearlyZero(fMat[kMPersp0])) { | 1209 if (PerspNearlyZero(fMat[kMPersp0])) { |
1191 if (stepX || stepY) { | 1210 if (stepX || stepY) { |
1192 if (PerspNearlyZero(fMat[kMPersp1]) && | 1211 if (PerspNearlyZero(fMat[kMPersp1]) && |
1193 PerspNearlyZero(fMat[kMPersp2] - kMatrix22Elem)) { | 1212 PerspNearlyZero(fMat[kMPersp2] - 1)) { |
1194 if (stepX) { | 1213 if (stepX) { |
1195 *stepX = SkScalarToFixed(fMat[kMScaleX]); | 1214 *stepX = SkScalarToFixed(fMat[kMScaleX]); |
1196 } | 1215 } |
1197 if (stepY) { | 1216 if (stepY) { |
1198 *stepY = SkScalarToFixed(fMat[kMSkewY]); | 1217 *stepY = SkScalarToFixed(fMat[kMSkewY]); |
1199 } | 1218 } |
1200 } else { | 1219 } else { |
1201 SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2]; | 1220 SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2]; |
1202 if (stepX) { | 1221 if (stepX) { |
1203 *stepX = SkScalarToFixed(SkScalarDiv(fMat[kMScaleX], z)); | 1222 *stepX = SkScalarToFixed(fMat[kMScaleX] / z); |
1204 } | 1223 } |
1205 if (stepY) { | 1224 if (stepY) { |
1206 *stepY = SkScalarToFixed(SkScalarDiv(fMat[kMSkewY], z)); | 1225 *stepY = SkScalarToFixed(fMat[kMSkewY] / z); |
1207 } | 1226 } |
1208 } | 1227 } |
1209 } | 1228 } |
1210 return true; | 1229 return true; |
1211 } | 1230 } |
1212 return false; | 1231 return false; |
1213 } | 1232 } |
1214 | 1233 |
1215 /////////////////////////////////////////////////////////////////////////////// | 1234 /////////////////////////////////////////////////////////////////////////////// |
1216 | 1235 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1284 case 2: | 1303 case 2: |
1285 break; | 1304 break; |
1286 case 3: | 1305 case 3: |
1287 pt2.fX = poly[0].fY - poly[2].fY; | 1306 pt2.fX = poly[0].fY - poly[2].fY; |
1288 pt2.fY = poly[2].fX - poly[0].fX; | 1307 pt2.fY = poly[2].fX - poly[0].fX; |
1289 goto CALC_X; | 1308 goto CALC_X; |
1290 default: | 1309 default: |
1291 pt2.fX = poly[0].fY - poly[3].fY; | 1310 pt2.fX = poly[0].fY - poly[3].fY; |
1292 pt2.fY = poly[3].fX - poly[0].fX; | 1311 pt2.fY = poly[3].fX - poly[0].fX; |
1293 CALC_X: | 1312 CALC_X: |
1294 x = SkScalarDiv(SkScalarMul(pt1.fX, pt2.fX) + | 1313 x = sdot(pt1.fX, pt2.fX, pt1.fY, pt2.fY) / y; |
1295 SkScalarMul(pt1.fY, pt2.fY), y); | |
1296 break; | 1314 break; |
1297 } | 1315 } |
1298 } | 1316 } |
1299 pt->set(x, y); | 1317 pt->set(x, y); |
1300 return true; | 1318 return true; |
1301 } | 1319 } |
1302 | 1320 |
1303 bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, | 1321 bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, |
1304 const SkPoint& scale) { | 1322 const SkPoint& scale) { |
1305 float invScale = 1 / scale.fY; | 1323 float invScale = 1 / scale.fY; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1347 y1 = srcPt[2].fY - srcPt[1].fY; | 1365 y1 = srcPt[2].fY - srcPt[1].fY; |
1348 x2 = srcPt[2].fX - srcPt[3].fX; | 1366 x2 = srcPt[2].fX - srcPt[3].fX; |
1349 y2 = srcPt[2].fY - srcPt[3].fY; | 1367 y2 = srcPt[2].fY - srcPt[3].fY; |
1350 | 1368 |
1351 /* check if abs(x2) > abs(y2) */ | 1369 /* check if abs(x2) > abs(y2) */ |
1352 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { | 1370 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { |
1353 float denom = SkScalarMulDiv(x1, y2, x2) - y1; | 1371 float denom = SkScalarMulDiv(x1, y2, x2) - y1; |
1354 if (checkForZero(denom)) { | 1372 if (checkForZero(denom)) { |
1355 return false; | 1373 return false; |
1356 } | 1374 } |
1357 a1 = SkScalarDiv(SkScalarMulDiv(x0 - x1, y2, x2) - y0 + y1, denom); | 1375 a1 = (SkScalarMulDiv(x0 - x1, y2, x2) - y0 + y1) / denom; |
1358 } else { | 1376 } else { |
1359 float denom = x1 - SkScalarMulDiv(y1, x2, y2); | 1377 float denom = x1 - SkScalarMulDiv(y1, x2, y2); |
1360 if (checkForZero(denom)) { | 1378 if (checkForZero(denom)) { |
1361 return false; | 1379 return false; |
1362 } | 1380 } |
1363 a1 = SkScalarDiv(x0 - x1 - SkScalarMulDiv(y0 - y1, x2, y2), denom); | 1381 a1 = (x0 - x1 - SkScalarMulDiv(y0 - y1, x2, y2)) / denom; |
1364 } | 1382 } |
1365 | 1383 |
1366 /* check if abs(x1) > abs(y1) */ | 1384 /* check if abs(x1) > abs(y1) */ |
1367 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { | 1385 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { |
1368 float denom = y2 - SkScalarMulDiv(x2, y1, x1); | 1386 float denom = y2 - SkScalarMulDiv(x2, y1, x1); |
1369 if (checkForZero(denom)) { | 1387 if (checkForZero(denom)) { |
1370 return false; | 1388 return false; |
1371 } | 1389 } |
1372 a2 = SkScalarDiv(y0 - y2 - SkScalarMulDiv(x0 - x2, y1, x1), denom); | 1390 a2 = (y0 - y2 - SkScalarMulDiv(x0 - x2, y1, x1)) / denom; |
1373 } else { | 1391 } else { |
1374 float denom = SkScalarMulDiv(y2, x1, y1) - x2; | 1392 float denom = SkScalarMulDiv(y2, x1, y1) - x2; |
1375 if (checkForZero(denom)) { | 1393 if (checkForZero(denom)) { |
1376 return false; | 1394 return false; |
1377 } | 1395 } |
1378 a2 = SkScalarDiv(SkScalarMulDiv(y0 - y2, x1, y1) - x0 + x2, denom); | 1396 a2 = (SkScalarMulDiv(y0 - y2, x1, y1) - x0 + x2) / denom; |
1379 } | 1397 } |
1380 | 1398 |
1381 float invScale = 1 / scale.fX; | 1399 float invScale = SkScalarInvert(scale.fX); |
1382 dst->fMat[kMScaleX] = SkScalarMul(SkScalarMul(a2, srcPt[3].fX) + | 1400 dst->fMat[kMScaleX] = (a2 * srcPt[3].fX + srcPt[3].fX - srcPt[0].fX) * invSc ale; |
1383 srcPt[3].fX - srcPt[0].fX, invScale); | 1401 dst->fMat[kMSkewY] = (a2 * srcPt[3].fY + srcPt[3].fY - srcPt[0].fY) * invSc ale; |
1384 dst->fMat[kMSkewY] = SkScalarMul(SkScalarMul(a2, srcPt[3].fY) + | 1402 dst->fMat[kMPersp0] = a2 * invScale; |
1385 srcPt[3].fY - srcPt[0].fY, invScale); | 1403 |
1386 dst->fMat[kMPersp0] = SkScalarMul(a2, invScale); | 1404 invScale = SkScalarInvert(scale.fY); |
1387 invScale = 1 / scale.fY; | 1405 dst->fMat[kMSkewX] = (a1 * srcPt[1].fX + srcPt[1].fX - srcPt[0].fX) * invSc ale; |
1388 dst->fMat[kMSkewX] = SkScalarMul(SkScalarMul(a1, srcPt[1].fX) + | 1406 dst->fMat[kMScaleY] = (a1 * srcPt[1].fY + srcPt[1].fY - srcPt[0].fY) * invSc ale; |
1389 srcPt[1].fX - srcPt[0].fX, invScale); | 1407 dst->fMat[kMPersp1] = a1 * invScale; |
1390 dst->fMat[kMScaleY] = SkScalarMul(SkScalarMul(a1, srcPt[1].fY) + | 1408 |
1391 srcPt[1].fY - srcPt[0].fY, invScale); | |
1392 dst->fMat[kMPersp1] = SkScalarMul(a1, invScale); | |
1393 dst->fMat[kMTransX] = srcPt[0].fX; | 1409 dst->fMat[kMTransX] = srcPt[0].fX; |
1394 dst->fMat[kMTransY] = srcPt[0].fY; | 1410 dst->fMat[kMTransY] = srcPt[0].fY; |
1395 dst->fMat[kMPersp2] = 1; | 1411 dst->fMat[kMPersp2] = 1; |
1396 dst->setTypeMask(kUnknown_Mask); | 1412 dst->setTypeMask(kUnknown_Mask); |
1397 return true; | 1413 return true; |
1398 } | 1414 } |
1399 | 1415 |
1400 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); | 1416 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); |
1401 | 1417 |
1402 /* Taken from Rob Johnson's original sample code in QuickDraw GX | 1418 /* Taken from Rob Johnson's original sample code in QuickDraw GX |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1451 /////////////////////////////////////////////////////////////////////////////// | 1467 /////////////////////////////////////////////////////////////////////////////// |
1452 | 1468 |
1453 enum MinOrMax { | 1469 enum MinOrMax { |
1454 kMin_MinOrMax, | 1470 kMin_MinOrMax, |
1455 kMax_MinOrMax | 1471 kMax_MinOrMax |
1456 }; | 1472 }; |
1457 | 1473 |
1458 template <MinOrMax MIN_OR_MAX> SkScalar get_stretch_factor(SkMatrix::TypeMask ty peMask, | 1474 template <MinOrMax MIN_OR_MAX> SkScalar get_stretch_factor(SkMatrix::TypeMask ty peMask, |
1459 const SkScalar m[9]) { | 1475 const SkScalar m[9]) { |
1460 if (typeMask & SkMatrix::kPerspective_Mask) { | 1476 if (typeMask & SkMatrix::kPerspective_Mask) { |
1461 return -SK_Scalar1; | 1477 return -1; |
1462 } | 1478 } |
1463 if (SkMatrix::kIdentity_Mask == typeMask) { | 1479 if (SkMatrix::kIdentity_Mask == typeMask) { |
1464 return SK_Scalar1; | 1480 return 1; |
1465 } | 1481 } |
1466 if (!(typeMask & SkMatrix::kAffine_Mask)) { | 1482 if (!(typeMask & SkMatrix::kAffine_Mask)) { |
1467 if (kMin_MinOrMax == MIN_OR_MAX) { | 1483 if (kMin_MinOrMax == MIN_OR_MAX) { |
1468 return SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), | 1484 return SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), |
1469 SkScalarAbs(m[SkMatrix::kMScaleY])); | 1485 SkScalarAbs(m[SkMatrix::kMScaleY])); |
1470 } else { | 1486 } else { |
1471 return SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), | 1487 return SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), |
1472 SkScalarAbs(m[SkMatrix::kMScaleY])); | 1488 SkScalarAbs(m[SkMatrix::kMScaleY])); |
1473 } | 1489 } |
1474 } | 1490 } |
1475 // ignore the translation part of the matrix, just look at 2x2 portion. | 1491 // ignore the translation part of the matrix, just look at 2x2 portion. |
1476 // compute singular values, take largest or smallest abs value. | 1492 // compute singular values, take largest or smallest abs value. |
1477 // [a b; b c] = A^T*A | 1493 // [a b; b c] = A^T*A |
1478 SkScalar a = SkScalarMul(m[SkMatrix::kMScaleX], m[SkMatrix::kMScaleX]) + | 1494 SkScalar a = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMScaleX], m[SkMatrix:: kMSkewY], m[SkMatrix::kMSkewY]); |
mtklein
2014/01/30 19:14:55
Clearer back on two lines each?
reed1
2014/01/30 20:53:48
Done.
| |
1479 SkScalarMul(m[SkMatrix::kMSkewY], m[SkMatrix::kMSkewY]); | 1495 SkScalar b = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewX], m[SkMatrix:: kMScaleY], m[SkMatrix::kMSkewY]); |
1480 SkScalar b = SkScalarMul(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewX]) + | 1496 SkScalar c = sdot(m[SkMatrix::kMSkewX], m[SkMatrix::kMSkewX], m[SkMatrix:: kMScaleY], m[SkMatrix::kMScaleY]); |
1481 SkScalarMul(m[SkMatrix::kMScaleY], m[SkMatrix::kMSkewY]); | |
1482 SkScalar c = SkScalarMul(m[SkMatrix::kMSkewX], m[SkMatrix::kMSkewX]) + | |
1483 SkScalarMul(m[SkMatrix::kMScaleY], m[SkMatrix::kMScaleY]); | |
1484 // eigenvalues of A^T*A are the squared singular values of A. | 1497 // eigenvalues of A^T*A are the squared singular values of A. |
1485 // characteristic equation is det((A^T*A) - l*I) = 0 | 1498 // characteristic equation is det((A^T*A) - l*I) = 0 |
1486 // l^2 - (a + c)l + (ac-b^2) | 1499 // l^2 - (a + c)l + (ac-b^2) |
1487 // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff | 1500 // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff |
1488 // and roots are guaranteed to be pos and real). | 1501 // and roots are guaranteed to be pos and real). |
1489 SkScalar chosenRoot; | 1502 SkScalar chosenRoot; |
1490 SkScalar bSqd = SkScalarMul(b,b); | 1503 SkScalar bSqd = b * b; |
1491 // if upper left 2x2 is orthogonal save some math | 1504 // if upper left 2x2 is orthogonal save some math |
1492 if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) { | 1505 if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) { |
1493 if (kMin_MinOrMax == MIN_OR_MAX) { | 1506 if (kMin_MinOrMax == MIN_OR_MAX) { |
1494 chosenRoot = SkMinScalar(a, c); | 1507 chosenRoot = SkMinScalar(a, c); |
1495 } else { | 1508 } else { |
1496 chosenRoot = SkMaxScalar(a, c); | 1509 chosenRoot = SkMaxScalar(a, c); |
1497 } | 1510 } |
1498 } else { | 1511 } else { |
1499 SkScalar aminusc = a - c; | 1512 SkScalar aminusc = a - c; |
1500 SkScalar apluscdiv2 = SkScalarHalf(a + c); | 1513 SkScalar apluscdiv2 = SkScalarHalf(a + c); |
1501 SkScalar x = SkScalarHalf(SkScalarSqrt(SkScalarMul(aminusc, aminusc) + 4 * bSqd)); | 1514 SkScalar x = SkScalarHalf(SkScalarSqrt(aminusc * aminusc + 4 * bSqd)); |
1502 if (kMin_MinOrMax == MIN_OR_MAX) { | 1515 if (kMin_MinOrMax == MIN_OR_MAX) { |
1503 chosenRoot = apluscdiv2 - x; | 1516 chosenRoot = apluscdiv2 - x; |
1504 } else { | 1517 } else { |
1505 chosenRoot = apluscdiv2 + x; | 1518 chosenRoot = apluscdiv2 + x; |
1506 } | 1519 } |
1507 } | 1520 } |
1508 SkASSERT(chosenRoot >= 0); | 1521 SkASSERT(chosenRoot >= 0); |
1509 return SkScalarSqrt(chosenRoot); | 1522 return SkScalarSqrt(chosenRoot); |
1510 } | 1523 } |
1511 | 1524 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1654 | 1667 |
1655 double w1, w2; | 1668 double w1, w2; |
1656 SkScalar cos1, sin1; | 1669 SkScalar cos1, sin1; |
1657 SkScalar cos2, sin2; | 1670 SkScalar cos2, sin2; |
1658 | 1671 |
1659 // do polar decomposition (M = Q*S) | 1672 // do polar decomposition (M = Q*S) |
1660 SkScalar cosQ, sinQ; | 1673 SkScalar cosQ, sinQ; |
1661 double Sa, Sb, Sd; | 1674 double Sa, Sb, Sd; |
1662 // if M is already symmetric (i.e., M = I*S) | 1675 // if M is already symmetric (i.e., M = I*S) |
1663 if (SkScalarNearlyEqual(B, C)) { | 1676 if (SkScalarNearlyEqual(B, C)) { |
1664 cosQ = SK_Scalar1; | 1677 cosQ = 1; |
1665 sinQ = 0; | 1678 sinQ = 0; |
1666 | 1679 |
1667 Sa = A; | 1680 Sa = A; |
1668 Sb = B; | 1681 Sb = B; |
1669 Sd = D; | 1682 Sd = D; |
1670 } else { | 1683 } else { |
1671 cosQ = A + D; | 1684 cosQ = A + D; |
1672 sinQ = C - B; | 1685 sinQ = C - B; |
1673 SkScalar reciplen = SK_Scalar1/SkScalarSqrt(cosQ*cosQ + sinQ*sinQ); | 1686 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cosQ*cosQ + sinQ*sinQ)); |
1674 cosQ *= reciplen; | 1687 cosQ *= reciplen; |
1675 sinQ *= reciplen; | 1688 sinQ *= reciplen; |
1676 | 1689 |
1677 // S = Q^-1*M | 1690 // S = Q^-1*M |
1678 // we don't calc Sc since it's symmetric | 1691 // we don't calc Sc since it's symmetric |
1679 Sa = A*cosQ + C*sinQ; | 1692 Sa = A*cosQ + C*sinQ; |
1680 Sb = B*cosQ + D*sinQ; | 1693 Sb = B*cosQ + D*sinQ; |
1681 Sd = -B*sinQ + D*cosQ; | 1694 Sd = -B*sinQ + D*cosQ; |
1682 } | 1695 } |
1683 | 1696 |
1684 // Now we need to compute eigenvalues of S (our scale factors) | 1697 // Now we need to compute eigenvalues of S (our scale factors) |
1685 // and eigenvectors (bases for our rotation) | 1698 // and eigenvectors (bases for our rotation) |
1686 // From this, should be able to reconstruct S as U*W*U^T | 1699 // From this, should be able to reconstruct S as U*W*U^T |
1687 if (SkScalarNearlyZero(SkDoubleToScalar(Sb))) { | 1700 if (SkScalarNearlyZero(SkDoubleToScalar(Sb))) { |
1688 // already diagonalized | 1701 // already diagonalized |
1689 cos1 = SK_Scalar1; | 1702 cos1 = 1; |
1690 sin1 = 0; | 1703 sin1 = 0; |
1691 w1 = Sa; | 1704 w1 = Sa; |
1692 w2 = Sd; | 1705 w2 = Sd; |
1693 cos2 = cosQ; | 1706 cos2 = cosQ; |
1694 sin2 = sinQ; | 1707 sin2 = sinQ; |
1695 } else { | 1708 } else { |
1696 double diff = Sa - Sd; | 1709 double diff = Sa - Sd; |
1697 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb); | 1710 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb); |
1698 double trace = Sa + Sd; | 1711 double trace = Sa + Sd; |
1699 if (diff > 0) { | 1712 if (diff > 0) { |
1700 w1 = 0.5*(trace + discriminant); | 1713 w1 = 0.5*(trace + discriminant); |
1701 w2 = 0.5*(trace - discriminant); | 1714 w2 = 0.5*(trace - discriminant); |
1702 } else { | 1715 } else { |
1703 w1 = 0.5*(trace - discriminant); | 1716 w1 = 0.5*(trace - discriminant); |
1704 w2 = 0.5*(trace + discriminant); | 1717 w2 = 0.5*(trace + discriminant); |
1705 } | 1718 } |
1706 | 1719 |
1707 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa); | 1720 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa); |
1708 SkScalar reciplen = SK_Scalar1/SkScalarSqrt(cos1*cos1 + sin1*sin1); | 1721 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cos1*cos1 + sin1*sin1)); |
1709 cos1 *= reciplen; | 1722 cos1 *= reciplen; |
1710 sin1 *= reciplen; | 1723 sin1 *= reciplen; |
1711 | 1724 |
1712 // rotation 2 is composition of Q and U | 1725 // rotation 2 is composition of Q and U |
1713 cos2 = cos1*cosQ - sin1*sinQ; | 1726 cos2 = cos1*cosQ - sin1*sinQ; |
1714 sin2 = sin1*cosQ + cos1*sinQ; | 1727 sin2 = sin1*cosQ + cos1*sinQ; |
1715 | 1728 |
1716 // rotation 1 is U^T | 1729 // rotation 1 is U^T |
1717 sin1 = -sin1; | 1730 sin1 = -sin1; |
1718 } | 1731 } |
1719 | 1732 |
1720 if (NULL != scale) { | 1733 if (NULL != scale) { |
1721 scale->fX = SkDoubleToScalar(w1); | 1734 scale->fX = SkDoubleToScalar(w1); |
1722 scale->fY = SkDoubleToScalar(w2); | 1735 scale->fY = SkDoubleToScalar(w2); |
1723 } | 1736 } |
1724 if (NULL != rotation1) { | 1737 if (NULL != rotation1) { |
1725 rotation1->fX = cos1; | 1738 rotation1->fX = cos1; |
1726 rotation1->fY = sin1; | 1739 rotation1->fY = sin1; |
1727 } | 1740 } |
1728 if (NULL != rotation2) { | 1741 if (NULL != rotation2) { |
1729 rotation2->fX = cos2; | 1742 rotation2->fX = cos2; |
1730 rotation2->fY = sin2; | 1743 rotation2->fY = sin2; |
1731 } | 1744 } |
1732 | 1745 |
1733 return true; | 1746 return true; |
1734 } | 1747 } |
OLD | NEW |