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 sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d, |
| 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)); |
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; |
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 SkScalar scross_dscale(SkScalar a, SkScalar b, |
706 #define SkPerspMul(a, b) SkScalarMul(a, b) | 726 SkScalar c, SkScalar d, double scale) { |
707 #define SkScalarMulShift(a, b, s) SkDoubleToFloat((a) * (b)) | 727 return SkDoubleToScalar(scross(a, b, c, d) * scale); |
708 static double sk_inv_determinant(const float mat[9], int isPerspective, | 728 } |
709 int* /* (only used in Fixed case) */) { | 729 |
| 730 static inline double dcross(double a, double b, double c, double d) { |
| 731 return a * b - c * d; |
| 732 } |
| 733 |
| 734 static inline SkScalar dcross_dscale(double a, double b, |
| 735 double c, double d, double scale) { |
| 736 return SkDoubleToScalar(dcross(a, b, c, d) * scale); |
| 737 } |
| 738 |
| 739 static double sk_inv_determinant(const float mat[9], int isPerspective) { |
710 double det; | 740 double det; |
711 | 741 |
712 if (isPerspective) { | 742 if (isPerspective) { |
713 det = mat[SkMatrix::kMScaleX] * ((double)mat[SkMatrix::kMScaleY] * mat
[SkMatrix::kMPersp2] - (double)mat[SkMatrix::kMTransY] * mat[SkMatrix::kMPersp1]
) + | 743 det = mat[SkMatrix::kMScaleX] * |
714 mat[SkMatrix::kMSkewX] * ((double)mat[SkMatrix::kMTransY] * mat[
SkMatrix::kMPersp0] - (double)mat[SkMatrix::kMSkewY] * mat[SkMatrix::kMPersp2])
+ | 744 dcross(mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp2], |
715 mat[SkMatrix::kMTransX] * ((double)mat[SkMatrix::kMSkewY] * mat[
SkMatrix::kMPersp1] - (double)mat[SkMatrix::kMScaleY] * mat[SkMatrix::kMPersp0])
; | 745 mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp1]) |
| 746 + |
| 747 mat[SkMatrix::kMSkewX] * |
| 748 dcross(mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp0], |
| 749 mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp2]) |
| 750 + |
| 751 mat[SkMatrix::kMTransX] * |
| 752 dcross(mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp1], |
| 753 mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp0]); |
716 } else { | 754 } else { |
717 det = (double)mat[SkMatrix::kMScaleX] * mat[SkMatrix::kMScaleY] - (dou
ble)mat[SkMatrix::kMSkewX] * mat[SkMatrix::kMSkewY]; | 755 det = dcross(mat[SkMatrix::kMScaleX], mat[SkMatrix::kMScaleY], |
| 756 mat[SkMatrix::kMSkewX], mat[SkMatrix::kMSkewY]); |
718 } | 757 } |
719 | 758 |
720 // Since the determinant is on the order of the cube of the matrix members, | 759 // 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 | 760 // 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). | 761 // 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)) { | 762 if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero
* SK_ScalarNearlyZero)) { |
724 return 0; | 763 return 0; |
725 } | 764 } |
726 return 1.0 / det; | 765 return 1.0 / det; |
727 } | 766 } |
728 // 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 | |
730 // from the matrix, which are floats. | |
731 static float inline mul_diff_scale(double a, double b, double c, double d, | |
732 double scale) { | |
733 return SkDoubleToFloat((a * b - c * d) * scale); | |
734 } | |
735 | 767 |
736 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) { | 768 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) { |
737 affine[kAScaleX] = SK_Scalar1; | 769 affine[kAScaleX] = 1; |
738 affine[kASkewY] = 0; | 770 affine[kASkewY] = 0; |
739 affine[kASkewX] = 0; | 771 affine[kASkewX] = 0; |
740 affine[kAScaleY] = SK_Scalar1; | 772 affine[kAScaleY] = 1; |
741 affine[kATransX] = 0; | 773 affine[kATransX] = 0; |
742 affine[kATransY] = 0; | 774 affine[kATransY] = 0; |
743 } | 775 } |
744 | 776 |
745 bool SkMatrix::asAffine(SkScalar affine[6]) const { | 777 bool SkMatrix::asAffine(SkScalar affine[6]) const { |
746 if (this->hasPerspective()) { | 778 if (this->hasPerspective()) { |
747 return false; | 779 return false; |
748 } | 780 } |
749 if (affine) { | 781 if (affine) { |
750 affine[kAScaleX] = this->fMat[kMScaleX]; | 782 affine[kAScaleX] = this->fMat[kMScaleX]; |
(...skipping 24 matching lines...) Expand all Loading... |
775 invY = SkScalarInvert(invY); | 807 invY = SkScalarInvert(invY); |
776 | 808 |
777 // Must be careful when writing to inv, since it may be the | 809 // Must be careful when writing to inv, since it may be the |
778 // same memory as this. | 810 // same memory as this. |
779 | 811 |
780 inv->fMat[kMSkewX] = inv->fMat[kMSkewY] = | 812 inv->fMat[kMSkewX] = inv->fMat[kMSkewY] = |
781 inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0; | 813 inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0; |
782 | 814 |
783 inv->fMat[kMScaleX] = invX; | 815 inv->fMat[kMScaleX] = invX; |
784 inv->fMat[kMScaleY] = invY; | 816 inv->fMat[kMScaleY] = invY; |
785 inv->fMat[kMPersp2] = kMatrix22Elem; | 817 inv->fMat[kMPersp2] = 1; |
786 inv->fMat[kMTransX] = -SkScalarMul(fMat[kMTransX], invX); | 818 inv->fMat[kMTransX] = -fMat[kMTransX] * invX; |
787 inv->fMat[kMTransY] = -SkScalarMul(fMat[kMTransY], invY); | 819 inv->fMat[kMTransY] = -fMat[kMTransY] * invY; |
788 | 820 |
789 inv->setTypeMask(mask | kRectStaysRect_Mask); | 821 inv->setTypeMask(mask | kRectStaysRect_Mask); |
790 } else { | 822 } else { |
791 // translate only | 823 // translate only |
792 inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]); | 824 inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]); |
793 } | 825 } |
794 } else { // inv is NULL, just check if we're invertible | 826 } else { // inv is NULL, just check if we're invertible |
795 if (!fMat[kMScaleX] || !fMat[kMScaleY]) { | 827 if (!fMat[kMScaleX] || !fMat[kMScaleY]) { |
796 invertible = false; | 828 invertible = false; |
797 } | 829 } |
798 } | 830 } |
799 return invertible; | 831 return invertible; |
800 } | 832 } |
801 | 833 |
802 int isPersp = mask & kPerspective_Mask; | 834 int isPersp = mask & kPerspective_Mask; |
803 int shift; | 835 double scale = sk_inv_determinant(fMat, isPersp); |
804 SkDetScalar scale = sk_inv_determinant(fMat, isPersp, &shift); | |
805 | 836 |
806 if (scale == 0) { // underflow | 837 if (scale == 0) { // underflow |
807 return false; | 838 return false; |
808 } | 839 } |
809 | 840 |
810 if (inv) { | 841 if (inv) { |
811 SkMatrix tmp; | 842 SkMatrix tmp; |
812 if (inv == this) { | 843 if (inv == this) { |
813 inv = &tmp; | 844 inv = &tmp; |
814 } | 845 } |
815 | 846 |
816 if (isPersp) { | 847 if (isPersp) { |
817 shift = 61 - shift; | 848 inv->fMat[kMScaleX] = scross_dscale(fMat[kMScaleY], fMat[kMPersp2],
fMat[kMTransY], fMat[kMPersp1], scale); |
818 inv->fMat[kMScaleX] = SkScalarMulShift(SkPerspMul(fMat[kMScaleY], fM
at[kMPersp2]) - SkPerspMul(fMat[kMTransY], fMat[kMPersp1]), scale, shift); | 849 inv->fMat[kMSkewX] = scross_dscale(fMat[kMTransX], fMat[kMPersp1],
fMat[kMSkewX], fMat[kMPersp2], scale); |
819 inv->fMat[kMSkewX] = SkScalarMulShift(SkPerspMul(fMat[kMTransX], fM
at[kMPersp1]) - SkPerspMul(fMat[kMSkewX], fMat[kMPersp2]), scale, shift); | 850 inv->fMat[kMTransX] = scross_dscale(fMat[kMSkewX], fMat[kMTransY],
fMat[kMTransX], fMat[kMScaleY], scale); |
820 inv->fMat[kMTransX] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM
at[kMTransY]) - SkScalarMul(fMat[kMTransX], fMat[kMScaleY]), scale, shift); | |
821 | 851 |
822 inv->fMat[kMSkewY] = SkScalarMulShift(SkPerspMul(fMat[kMTransY], fM
at[kMPersp0]) - SkPerspMul(fMat[kMSkewY], fMat[kMPersp2]), scale, shift); | 852 inv->fMat[kMSkewY] = scross_dscale(fMat[kMTransY], fMat[kMPersp0],
fMat[kMSkewY], fMat[kMPersp2], scale); |
823 inv->fMat[kMScaleY] = SkScalarMulShift(SkPerspMul(fMat[kMScaleX], fM
at[kMPersp2]) - SkPerspMul(fMat[kMTransX], fMat[kMPersp0]), scale, shift); | 853 inv->fMat[kMScaleY] = scross_dscale(fMat[kMScaleX], fMat[kMPersp2],
fMat[kMTransX], fMat[kMPersp0], scale); |
824 inv->fMat[kMTransY] = SkScalarMulShift(SkScalarMul(fMat[kMTransX], f
Mat[kMSkewY]) - SkScalarMul(fMat[kMScaleX], fMat[kMTransY]), scale, shift); | 854 inv->fMat[kMTransY] = scross_dscale(fMat[kMTransX], fMat[kMSkewY],
fMat[kMScaleX], fMat[kMTransY], scale); |
825 | 855 |
826 inv->fMat[kMPersp0] = SkScalarMulShift(SkScalarMul(fMat[kMSkewY], fM
at[kMPersp1]) - SkScalarMul(fMat[kMScaleY], fMat[kMPersp0]), scale, shift); | 856 inv->fMat[kMPersp0] = scross_dscale(fMat[kMSkewY], fMat[kMPersp1],
fMat[kMScaleY], fMat[kMPersp0], scale); |
827 inv->fMat[kMPersp1] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM
at[kMPersp0]) - SkScalarMul(fMat[kMScaleX], fMat[kMPersp1]), scale, shift); | 857 inv->fMat[kMPersp1] = scross_dscale(fMat[kMSkewX], fMat[kMPersp0],
fMat[kMScaleX], fMat[kMPersp1], scale); |
828 inv->fMat[kMPersp2] = SkScalarMulShift(SkScalarMul(fMat[kMScaleX], f
Mat[kMScaleY]) - SkScalarMul(fMat[kMSkewX], fMat[kMSkewY]), scale, shift); | 858 inv->fMat[kMPersp2] = scross_dscale(fMat[kMScaleX], fMat[kMScaleY],
fMat[kMSkewX], fMat[kMSkewY], scale); |
829 } else { // not perspective | 859 } else { // not perspective |
830 inv->fMat[kMScaleX] = SkDoubleToFloat(fMat[kMScaleY] * scale); | 860 inv->fMat[kMScaleX] = SkDoubleToScalar(fMat[kMScaleY] * scale); |
831 inv->fMat[kMSkewX] = SkDoubleToFloat(-fMat[kMSkewX] * scale); | 861 inv->fMat[kMSkewX] = SkDoubleToScalar(-fMat[kMSkewX] * scale); |
832 inv->fMat[kMTransX] = mul_diff_scale(fMat[kMSkewX], fMat[kMTransY], | 862 inv->fMat[kMTransX] = dcross_dscale(fMat[kMSkewX], fMat[kMTransY], f
Mat[kMScaleY], fMat[kMTransX], scale); |
833 fMat[kMScaleY], fMat[kMTransX], scale); | |
834 | 863 |
835 inv->fMat[kMSkewY] = SkDoubleToFloat(-fMat[kMSkewY] * scale); | 864 inv->fMat[kMSkewY] = SkDoubleToScalar(-fMat[kMSkewY] * scale); |
836 inv->fMat[kMScaleY] = SkDoubleToFloat(fMat[kMScaleX] * scale); | 865 inv->fMat[kMScaleY] = SkDoubleToScalar(fMat[kMScaleX] * scale); |
837 inv->fMat[kMTransY] = mul_diff_scale(fMat[kMSkewY], fMat[kMTransX], | 866 inv->fMat[kMTransY] = dcross_dscale(fMat[kMSkewY], fMat[kMTransX], f
Mat[kMScaleX], fMat[kMTransY], scale); |
838 fMat[kMScaleX], fMat[kMTransY], scale); | |
839 | 867 |
840 inv->fMat[kMPersp0] = 0; | 868 inv->fMat[kMPersp0] = 0; |
841 inv->fMat[kMPersp1] = 0; | 869 inv->fMat[kMPersp1] = 0; |
842 inv->fMat[kMPersp2] = kMatrix22Elem; | 870 inv->fMat[kMPersp2] = 1; |
843 | |
844 } | 871 } |
845 | 872 |
846 inv->setTypeMask(fTypeMask); | 873 inv->setTypeMask(fTypeMask); |
847 | 874 |
848 if (inv == &tmp) { | 875 if (inv == &tmp) { |
849 *(SkMatrix*)this = tmp; | 876 *(SkMatrix*)this = tmp; |
850 } | 877 } |
851 } | 878 } |
852 return true; | 879 return true; |
853 } | 880 } |
(...skipping 25 matching lines...) Expand all Loading... |
879 } | 906 } |
880 | 907 |
881 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], | 908 void SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], |
882 const SkPoint src[], int count) { | 909 const SkPoint src[], int count) { |
883 SkASSERT(m.getType() == kScale_Mask); | 910 SkASSERT(m.getType() == kScale_Mask); |
884 | 911 |
885 if (count > 0) { | 912 if (count > 0) { |
886 SkScalar mx = m.fMat[kMScaleX]; | 913 SkScalar mx = m.fMat[kMScaleX]; |
887 SkScalar my = m.fMat[kMScaleY]; | 914 SkScalar my = m.fMat[kMScaleY]; |
888 do { | 915 do { |
889 dst->fY = SkScalarMul(src->fY, my); | 916 dst->fY = src->fY * my; |
890 dst->fX = SkScalarMul(src->fX, mx); | 917 dst->fX = src->fX * mx; |
891 src += 1; | 918 src += 1; |
892 dst += 1; | 919 dst += 1; |
893 } while (--count); | 920 } while (--count); |
894 } | 921 } |
895 } | 922 } |
896 | 923 |
897 void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], | 924 void SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], |
898 const SkPoint src[], int count) { | 925 const SkPoint src[], int count) { |
899 SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); | 926 SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); |
900 | 927 |
901 if (count > 0) { | 928 if (count > 0) { |
902 SkScalar mx = m.fMat[kMScaleX]; | 929 SkScalar mx = m.fMat[kMScaleX]; |
903 SkScalar my = m.fMat[kMScaleY]; | 930 SkScalar my = m.fMat[kMScaleY]; |
904 SkScalar tx = m.fMat[kMTransX]; | 931 SkScalar tx = m.fMat[kMTransX]; |
905 SkScalar ty = m.fMat[kMTransY]; | 932 SkScalar ty = m.fMat[kMTransY]; |
906 do { | 933 do { |
907 dst->fY = SkScalarMulAdd(src->fY, my, ty); | 934 dst->fY = src->fY * my + ty; |
908 dst->fX = SkScalarMulAdd(src->fX, mx, tx); | 935 dst->fX = src->fX * mx + tx; |
909 src += 1; | 936 src += 1; |
910 dst += 1; | 937 dst += 1; |
911 } while (--count); | 938 } while (--count); |
912 } | 939 } |
913 } | 940 } |
914 | 941 |
915 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[], | 942 void SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[], |
916 const SkPoint src[], int count) { | 943 const SkPoint src[], int count) { |
917 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0); | 944 SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0); |
918 | 945 |
919 if (count > 0) { | 946 if (count > 0) { |
920 SkScalar mx = m.fMat[kMScaleX]; | 947 SkScalar mx = m.fMat[kMScaleX]; |
921 SkScalar my = m.fMat[kMScaleY]; | 948 SkScalar my = m.fMat[kMScaleY]; |
922 SkScalar kx = m.fMat[kMSkewX]; | 949 SkScalar kx = m.fMat[kMSkewX]; |
923 SkScalar ky = m.fMat[kMSkewY]; | 950 SkScalar ky = m.fMat[kMSkewY]; |
924 do { | 951 do { |
925 SkScalar sy = src->fY; | 952 SkScalar sy = src->fY; |
926 SkScalar sx = src->fX; | 953 SkScalar sx = src->fX; |
927 src += 1; | 954 src += 1; |
928 dst->fY = SkScalarMul(sx, ky) + SkScalarMul(sy, my); | 955 dst->fY = sdot(sx, ky, sy, my); |
929 dst->fX = SkScalarMul(sx, mx) + SkScalarMul(sy, kx); | 956 dst->fX = sdot(sx, mx, sy, kx); |
930 dst += 1; | 957 dst += 1; |
931 } while (--count); | 958 } while (--count); |
932 } | 959 } |
933 } | 960 } |
934 | 961 |
935 void SkMatrix::RotTrans_pts(const SkMatrix& m, SkPoint dst[], | 962 void SkMatrix::RotTrans_pts(const SkMatrix& m, SkPoint dst[], |
936 const SkPoint src[], int count) { | 963 const SkPoint src[], int count) { |
937 SkASSERT(!m.hasPerspective()); | 964 SkASSERT(!m.hasPerspective()); |
938 | 965 |
939 if (count > 0) { | 966 if (count > 0) { |
940 SkScalar mx = m.fMat[kMScaleX]; | 967 SkScalar mx = m.fMat[kMScaleX]; |
941 SkScalar my = m.fMat[kMScaleY]; | 968 SkScalar my = m.fMat[kMScaleY]; |
942 SkScalar kx = m.fMat[kMSkewX]; | 969 SkScalar kx = m.fMat[kMSkewX]; |
943 SkScalar ky = m.fMat[kMSkewY]; | 970 SkScalar ky = m.fMat[kMSkewY]; |
944 SkScalar tx = m.fMat[kMTransX]; | 971 SkScalar tx = m.fMat[kMTransX]; |
945 SkScalar ty = m.fMat[kMTransY]; | 972 SkScalar ty = m.fMat[kMTransY]; |
946 do { | 973 do { |
947 SkScalar sy = src->fY; | 974 SkScalar sy = src->fY; |
948 SkScalar sx = src->fX; | 975 SkScalar sx = src->fX; |
949 src += 1; | 976 src += 1; |
950 dst->fY = SkScalarMul(sx, ky) + SkScalarMulAdd(sy, my, ty); | 977 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
951 dst->fX = SkScalarMul(sx, mx) + SkScalarMulAdd(sy, kx, tx); | 978 dst->fY = sx * ky + (sy * my + ty); |
| 979 dst->fX = sx * mx + (sy * kx + tx); |
| 980 #else |
| 981 dst->fY = sdot(sx, ky, sy, my) + ty; |
| 982 dst->fX = sdot(sx, mx, sy, kx) + tx; |
| 983 #endif |
952 dst += 1; | 984 dst += 1; |
953 } while (--count); | 985 } while (--count); |
954 } | 986 } |
955 } | 987 } |
956 | 988 |
957 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], | 989 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], |
958 const SkPoint src[], int count) { | 990 const SkPoint src[], int count) { |
959 SkASSERT(m.hasPerspective()); | 991 SkASSERT(m.hasPerspective()); |
960 | 992 |
961 if (count > 0) { | 993 if (count > 0) { |
962 do { | 994 do { |
963 SkScalar sy = src->fY; | 995 SkScalar sy = src->fY; |
964 SkScalar sx = src->fX; | 996 SkScalar sx = src->fX; |
965 src += 1; | 997 src += 1; |
966 | 998 |
967 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + | 999 SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fM
at[kMTransX]; |
968 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; | 1000 SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fM
at[kMTransY]; |
969 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1001 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
970 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; | 1002 SkScalar z = sx * m.fMat[kMPersp0] + (sy * m.fMat[kMPersp1] + m.fMat
[kMPersp2]); |
971 SkScalar z = SkScalarMul(sx, m.fMat[kMPersp0]) + | 1003 #else |
972 SkScalarMulAdd(sy, m.fMat[kMPersp1], m.fMat[kMPersp2]); | 1004 SkScalar z = sdot(sx, m.fMat[kMPersp0], sy, m.fMat[kMPersp1]) + m.fM
at[kMPersp2]; |
| 1005 #endif |
973 if (z) { | 1006 if (z) { |
974 z = SkScalarFastInvert(z); | 1007 z = SkScalarFastInvert(z); |
975 } | 1008 } |
976 | 1009 |
977 dst->fY = SkScalarMul(y, z); | 1010 dst->fY = y * z; |
978 dst->fX = SkScalarMul(x, z); | 1011 dst->fX = x * z; |
979 dst += 1; | 1012 dst += 1; |
980 } while (--count); | 1013 } while (--count); |
981 } | 1014 } |
982 } | 1015 } |
983 | 1016 |
984 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { | 1017 const SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { |
985 SkMatrix::Identity_pts, SkMatrix::Trans_pts, | 1018 SkMatrix::Identity_pts, SkMatrix::Trans_pts, |
986 SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts, | 1019 SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts, |
987 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, | 1020 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, |
988 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, | 1021 SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, |
(...skipping 23 matching lines...) Expand all Loading... |
1012 if (this->isIdentity()) { | 1045 if (this->isIdentity()) { |
1013 memcpy(dst, src, 3*count*sizeof(SkScalar)); | 1046 memcpy(dst, src, 3*count*sizeof(SkScalar)); |
1014 return; | 1047 return; |
1015 } | 1048 } |
1016 do { | 1049 do { |
1017 SkScalar sx = src[0]; | 1050 SkScalar sx = src[0]; |
1018 SkScalar sy = src[1]; | 1051 SkScalar sy = src[1]; |
1019 SkScalar sw = src[2]; | 1052 SkScalar sw = src[2]; |
1020 src += 3; | 1053 src += 3; |
1021 | 1054 |
1022 SkScalar x = SkScalarMul(sx, fMat[kMScaleX]) + | 1055 SkScalar x = sdot(sx, fMat[kMScaleX], sy, fMat[kMSkewX], sw, fMat[k
MTransX]); |
1023 SkScalarMul(sy, fMat[kMSkewX]) + | 1056 SkScalar y = sdot(sx, fMat[kMSkewY], sy, fMat[kMScaleY], sw, fMat[k
MTransY]); |
1024 SkScalarMul(sw, fMat[kMTransX]); | 1057 SkScalar w = sdot(sx, fMat[kMPersp0], sy, fMat[kMPersp1], sw, fMat[k
MPersp2]); |
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 | 1058 |
1032 dst[0] = x; | 1059 dst[0] = x; |
1033 dst[1] = y; | 1060 dst[1] = y; |
1034 dst[2] = w; | 1061 dst[2] = w; |
1035 dst += 3; | 1062 dst += 3; |
1036 } while (--count); | 1063 } while (--count); |
1037 } | 1064 } |
1038 } | 1065 } |
1039 | 1066 |
1040 /////////////////////////////////////////////////////////////////////////////// | 1067 /////////////////////////////////////////////////////////////////////////////// |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 // return geometric mean | 1118 // return geometric mean |
1092 return SkScalarSqrt(d0 * d1); | 1119 return SkScalarSqrt(d0 * d1); |
1093 } | 1120 } |
1094 | 1121 |
1095 /////////////////////////////////////////////////////////////////////////////// | 1122 /////////////////////////////////////////////////////////////////////////////// |
1096 | 1123 |
1097 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1124 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1098 SkPoint* pt) { | 1125 SkPoint* pt) { |
1099 SkASSERT(m.hasPerspective()); | 1126 SkASSERT(m.hasPerspective()); |
1100 | 1127 |
1101 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1128 SkScalar x = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTra
nsX]; |
1102 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; | 1129 SkScalar y = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTra
nsY]; |
1103 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1130 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) { | 1131 if (z) { |
1108 z = SkScalarFastInvert(z); | 1132 z = SkScalarFastInvert(z); |
1109 } | 1133 } |
1110 pt->fX = SkScalarMul(x, z); | 1134 pt->fX = x * z; |
1111 pt->fY = SkScalarMul(y, z); | 1135 pt->fY = y * z; |
1112 } | 1136 } |
1113 | 1137 |
1114 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1138 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1115 SkPoint* pt) { | 1139 SkPoint* pt) { |
1116 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask)
; | 1140 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask)
; |
1117 | 1141 |
1118 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1142 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
1119 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); | 1143 pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX])
; |
1120 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1144 pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]); |
1121 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1145 #else |
| 1146 pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]
; |
| 1147 pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]
; |
| 1148 #endif |
1122 } | 1149 } |
1123 | 1150 |
1124 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1151 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1125 SkPoint* pt) { | 1152 SkPoint* pt) { |
1126 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); | 1153 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); |
1127 SkASSERT(0 == m.fMat[kMTransX]); | 1154 SkASSERT(0 == m.fMat[kMTransX]); |
1128 SkASSERT(0 == m.fMat[kMTransY]); | 1155 SkASSERT(0 == m.fMat[kMTransY]); |
1129 | 1156 |
1130 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1157 #ifdef SK_LEGACY_MATRIX_MATH_ORDER |
1131 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); | 1158 pt->fX = sx * m.fMat[kMScaleX] + (sy * m.fMat[kMSkewX] + m.fMat[kMTransX]); |
1132 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1159 pt->fY = sx * m.fMat[kMSkewY] + (sy * m.fMat[kMScaleY] + m.fMat[kMTransY]); |
1133 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1160 #else |
| 1161 pt->fX = sdot(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]
; |
| 1162 pt->fY = sdot(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]
; |
| 1163 #endif |
1134 } | 1164 } |
1135 | 1165 |
1136 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1166 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1137 SkPoint* pt) { | 1167 SkPoint* pt) { |
1138 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) | 1168 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) |
1139 == kScale_Mask); | 1169 == kScale_Mask); |
1140 | 1170 |
1141 pt->fX = SkScalarMulAdd(sx, m.fMat[kMScaleX], m.fMat[kMTransX]); | 1171 pt->fX = sx * m.fMat[kMScaleX] + m.fMat[kMTransX]; |
1142 pt->fY = SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1172 pt->fY = sy * m.fMat[kMScaleY] + m.fMat[kMTransY]; |
1143 } | 1173 } |
1144 | 1174 |
1145 void SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1175 void SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1146 SkPoint* pt) { | 1176 SkPoint* pt) { |
1147 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) | 1177 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) |
1148 == kScale_Mask); | 1178 == kScale_Mask); |
1149 SkASSERT(0 == m.fMat[kMTransX]); | 1179 SkASSERT(0 == m.fMat[kMTransX]); |
1150 SkASSERT(0 == m.fMat[kMTransY]); | 1180 SkASSERT(0 == m.fMat[kMTransY]); |
1151 | 1181 |
1152 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]); | 1182 pt->fX = sx * m.fMat[kMScaleX]; |
1153 pt->fY = SkScalarMul(sy, m.fMat[kMScaleY]); | 1183 pt->fY = sy * m.fMat[kMScaleY]; |
1154 } | 1184 } |
1155 | 1185 |
1156 void SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1186 void SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
1157 SkPoint* pt) { | 1187 SkPoint* pt) { |
1158 SkASSERT(m.getType() == kTranslate_Mask); | 1188 SkASSERT(m.getType() == kTranslate_Mask); |
1159 | 1189 |
1160 pt->fX = sx + m.fMat[kMTransX]; | 1190 pt->fX = sx + m.fMat[kMTransX]; |
1161 pt->fY = sy + m.fMat[kMTransY]; | 1191 pt->fY = sy + m.fMat[kMTransY]; |
1162 } | 1192 } |
1163 | 1193 |
(...skipping 19 matching lines...) Expand all Loading... |
1183 | 1213 |
1184 /////////////////////////////////////////////////////////////////////////////// | 1214 /////////////////////////////////////////////////////////////////////////////// |
1185 | 1215 |
1186 // if its nearly zero (just made up 26, perhaps it should be bigger or smaller) | 1216 // 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))) | 1217 #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26))) |
1188 | 1218 |
1189 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { | 1219 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { |
1190 if (PerspNearlyZero(fMat[kMPersp0])) { | 1220 if (PerspNearlyZero(fMat[kMPersp0])) { |
1191 if (stepX || stepY) { | 1221 if (stepX || stepY) { |
1192 if (PerspNearlyZero(fMat[kMPersp1]) && | 1222 if (PerspNearlyZero(fMat[kMPersp1]) && |
1193 PerspNearlyZero(fMat[kMPersp2] - kMatrix22Elem)) { | 1223 PerspNearlyZero(fMat[kMPersp2] - 1)) { |
1194 if (stepX) { | 1224 if (stepX) { |
1195 *stepX = SkScalarToFixed(fMat[kMScaleX]); | 1225 *stepX = SkScalarToFixed(fMat[kMScaleX]); |
1196 } | 1226 } |
1197 if (stepY) { | 1227 if (stepY) { |
1198 *stepY = SkScalarToFixed(fMat[kMSkewY]); | 1228 *stepY = SkScalarToFixed(fMat[kMSkewY]); |
1199 } | 1229 } |
1200 } else { | 1230 } else { |
1201 SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2]; | 1231 SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2]; |
1202 if (stepX) { | 1232 if (stepX) { |
1203 *stepX = SkScalarToFixed(SkScalarDiv(fMat[kMScaleX], z)); | 1233 *stepX = SkScalarToFixed(fMat[kMScaleX] / z); |
1204 } | 1234 } |
1205 if (stepY) { | 1235 if (stepY) { |
1206 *stepY = SkScalarToFixed(SkScalarDiv(fMat[kMSkewY], z)); | 1236 *stepY = SkScalarToFixed(fMat[kMSkewY] / z); |
1207 } | 1237 } |
1208 } | 1238 } |
1209 } | 1239 } |
1210 return true; | 1240 return true; |
1211 } | 1241 } |
1212 return false; | 1242 return false; |
1213 } | 1243 } |
1214 | 1244 |
1215 /////////////////////////////////////////////////////////////////////////////// | 1245 /////////////////////////////////////////////////////////////////////////////// |
1216 | 1246 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 case 2: | 1314 case 2: |
1285 break; | 1315 break; |
1286 case 3: | 1316 case 3: |
1287 pt2.fX = poly[0].fY - poly[2].fY; | 1317 pt2.fX = poly[0].fY - poly[2].fY; |
1288 pt2.fY = poly[2].fX - poly[0].fX; | 1318 pt2.fY = poly[2].fX - poly[0].fX; |
1289 goto CALC_X; | 1319 goto CALC_X; |
1290 default: | 1320 default: |
1291 pt2.fX = poly[0].fY - poly[3].fY; | 1321 pt2.fX = poly[0].fY - poly[3].fY; |
1292 pt2.fY = poly[3].fX - poly[0].fX; | 1322 pt2.fY = poly[3].fX - poly[0].fX; |
1293 CALC_X: | 1323 CALC_X: |
1294 x = SkScalarDiv(SkScalarMul(pt1.fX, pt2.fX) + | 1324 x = sdot(pt1.fX, pt2.fX, pt1.fY, pt2.fY) / y; |
1295 SkScalarMul(pt1.fY, pt2.fY), y); | |
1296 break; | 1325 break; |
1297 } | 1326 } |
1298 } | 1327 } |
1299 pt->set(x, y); | 1328 pt->set(x, y); |
1300 return true; | 1329 return true; |
1301 } | 1330 } |
1302 | 1331 |
1303 bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, | 1332 bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, |
1304 const SkPoint& scale) { | 1333 const SkPoint& scale) { |
1305 float invScale = 1 / scale.fY; | 1334 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; | 1376 y1 = srcPt[2].fY - srcPt[1].fY; |
1348 x2 = srcPt[2].fX - srcPt[3].fX; | 1377 x2 = srcPt[2].fX - srcPt[3].fX; |
1349 y2 = srcPt[2].fY - srcPt[3].fY; | 1378 y2 = srcPt[2].fY - srcPt[3].fY; |
1350 | 1379 |
1351 /* check if abs(x2) > abs(y2) */ | 1380 /* check if abs(x2) > abs(y2) */ |
1352 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { | 1381 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { |
1353 float denom = SkScalarMulDiv(x1, y2, x2) - y1; | 1382 float denom = SkScalarMulDiv(x1, y2, x2) - y1; |
1354 if (checkForZero(denom)) { | 1383 if (checkForZero(denom)) { |
1355 return false; | 1384 return false; |
1356 } | 1385 } |
1357 a1 = SkScalarDiv(SkScalarMulDiv(x0 - x1, y2, x2) - y0 + y1, denom); | 1386 a1 = (SkScalarMulDiv(x0 - x1, y2, x2) - y0 + y1) / denom; |
1358 } else { | 1387 } else { |
1359 float denom = x1 - SkScalarMulDiv(y1, x2, y2); | 1388 float denom = x1 - SkScalarMulDiv(y1, x2, y2); |
1360 if (checkForZero(denom)) { | 1389 if (checkForZero(denom)) { |
1361 return false; | 1390 return false; |
1362 } | 1391 } |
1363 a1 = SkScalarDiv(x0 - x1 - SkScalarMulDiv(y0 - y1, x2, y2), denom); | 1392 a1 = (x0 - x1 - SkScalarMulDiv(y0 - y1, x2, y2)) / denom; |
1364 } | 1393 } |
1365 | 1394 |
1366 /* check if abs(x1) > abs(y1) */ | 1395 /* check if abs(x1) > abs(y1) */ |
1367 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { | 1396 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { |
1368 float denom = y2 - SkScalarMulDiv(x2, y1, x1); | 1397 float denom = y2 - SkScalarMulDiv(x2, y1, x1); |
1369 if (checkForZero(denom)) { | 1398 if (checkForZero(denom)) { |
1370 return false; | 1399 return false; |
1371 } | 1400 } |
1372 a2 = SkScalarDiv(y0 - y2 - SkScalarMulDiv(x0 - x2, y1, x1), denom); | 1401 a2 = (y0 - y2 - SkScalarMulDiv(x0 - x2, y1, x1)) / denom; |
1373 } else { | 1402 } else { |
1374 float denom = SkScalarMulDiv(y2, x1, y1) - x2; | 1403 float denom = SkScalarMulDiv(y2, x1, y1) - x2; |
1375 if (checkForZero(denom)) { | 1404 if (checkForZero(denom)) { |
1376 return false; | 1405 return false; |
1377 } | 1406 } |
1378 a2 = SkScalarDiv(SkScalarMulDiv(y0 - y2, x1, y1) - x0 + x2, denom); | 1407 a2 = (SkScalarMulDiv(y0 - y2, x1, y1) - x0 + x2) / denom; |
1379 } | 1408 } |
1380 | 1409 |
1381 float invScale = 1 / scale.fX; | 1410 float invScale = SkScalarInvert(scale.fX); |
1382 dst->fMat[kMScaleX] = SkScalarMul(SkScalarMul(a2, srcPt[3].fX) + | 1411 dst->fMat[kMScaleX] = (a2 * srcPt[3].fX + srcPt[3].fX - srcPt[0].fX) * invSc
ale; |
1383 srcPt[3].fX - srcPt[0].fX, invScale); | 1412 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) + | 1413 dst->fMat[kMPersp0] = a2 * invScale; |
1385 srcPt[3].fY - srcPt[0].fY, invScale); | 1414 |
1386 dst->fMat[kMPersp0] = SkScalarMul(a2, invScale); | 1415 invScale = SkScalarInvert(scale.fY); |
1387 invScale = 1 / scale.fY; | 1416 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) + | 1417 dst->fMat[kMScaleY] = (a1 * srcPt[1].fY + srcPt[1].fY - srcPt[0].fY) * invSc
ale; |
1389 srcPt[1].fX - srcPt[0].fX, invScale); | 1418 dst->fMat[kMPersp1] = a1 * invScale; |
1390 dst->fMat[kMScaleY] = SkScalarMul(SkScalarMul(a1, srcPt[1].fY) + | 1419 |
1391 srcPt[1].fY - srcPt[0].fY, invScale); | |
1392 dst->fMat[kMPersp1] = SkScalarMul(a1, invScale); | |
1393 dst->fMat[kMTransX] = srcPt[0].fX; | 1420 dst->fMat[kMTransX] = srcPt[0].fX; |
1394 dst->fMat[kMTransY] = srcPt[0].fY; | 1421 dst->fMat[kMTransY] = srcPt[0].fY; |
1395 dst->fMat[kMPersp2] = 1; | 1422 dst->fMat[kMPersp2] = 1; |
1396 dst->setTypeMask(kUnknown_Mask); | 1423 dst->setTypeMask(kUnknown_Mask); |
1397 return true; | 1424 return true; |
1398 } | 1425 } |
1399 | 1426 |
1400 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); | 1427 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); |
1401 | 1428 |
1402 /* Taken from Rob Johnson's original sample code in QuickDraw GX | 1429 /* 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 /////////////////////////////////////////////////////////////////////////////// | 1478 /////////////////////////////////////////////////////////////////////////////// |
1452 | 1479 |
1453 enum MinOrMax { | 1480 enum MinOrMax { |
1454 kMin_MinOrMax, | 1481 kMin_MinOrMax, |
1455 kMax_MinOrMax | 1482 kMax_MinOrMax |
1456 }; | 1483 }; |
1457 | 1484 |
1458 template <MinOrMax MIN_OR_MAX> SkScalar get_stretch_factor(SkMatrix::TypeMask ty
peMask, | 1485 template <MinOrMax MIN_OR_MAX> SkScalar get_stretch_factor(SkMatrix::TypeMask ty
peMask, |
1459 const SkScalar m[9])
{ | 1486 const SkScalar m[9])
{ |
1460 if (typeMask & SkMatrix::kPerspective_Mask) { | 1487 if (typeMask & SkMatrix::kPerspective_Mask) { |
1461 return -SK_Scalar1; | 1488 return -1; |
1462 } | 1489 } |
1463 if (SkMatrix::kIdentity_Mask == typeMask) { | 1490 if (SkMatrix::kIdentity_Mask == typeMask) { |
1464 return SK_Scalar1; | 1491 return 1; |
1465 } | 1492 } |
1466 if (!(typeMask & SkMatrix::kAffine_Mask)) { | 1493 if (!(typeMask & SkMatrix::kAffine_Mask)) { |
1467 if (kMin_MinOrMax == MIN_OR_MAX) { | 1494 if (kMin_MinOrMax == MIN_OR_MAX) { |
1468 return SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), | 1495 return SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), |
1469 SkScalarAbs(m[SkMatrix::kMScaleY])); | 1496 SkScalarAbs(m[SkMatrix::kMScaleY])); |
1470 } else { | 1497 } else { |
1471 return SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), | 1498 return SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]), |
1472 SkScalarAbs(m[SkMatrix::kMScaleY])); | 1499 SkScalarAbs(m[SkMatrix::kMScaleY])); |
1473 } | 1500 } |
1474 } | 1501 } |
1475 // ignore the translation part of the matrix, just look at 2x2 portion. | 1502 // ignore the translation part of the matrix, just look at 2x2 portion. |
1476 // compute singular values, take largest or smallest abs value. | 1503 // compute singular values, take largest or smallest abs value. |
1477 // [a b; b c] = A^T*A | 1504 // [a b; b c] = A^T*A |
1478 SkScalar a = SkScalarMul(m[SkMatrix::kMScaleX], m[SkMatrix::kMScaleX]) + | 1505 SkScalar a = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMScaleX], |
1479 SkScalarMul(m[SkMatrix::kMSkewY], m[SkMatrix::kMSkewY]); | 1506 m[SkMatrix::kMSkewY], m[SkMatrix::kMSkewY]); |
1480 SkScalar b = SkScalarMul(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewX]) + | 1507 SkScalar b = sdot(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewX], |
1481 SkScalarMul(m[SkMatrix::kMScaleY], m[SkMatrix::kMSkewY]); | 1508 m[SkMatrix::kMScaleY], m[SkMatrix::kMSkewY]); |
1482 SkScalar c = SkScalarMul(m[SkMatrix::kMSkewX], m[SkMatrix::kMSkewX]) + | 1509 SkScalar c = sdot(m[SkMatrix::kMSkewX], m[SkMatrix::kMSkewX], |
1483 SkScalarMul(m[SkMatrix::kMScaleY], m[SkMatrix::kMScaleY]); | 1510 m[SkMatrix::kMScaleY], m[SkMatrix::kMScaleY]); |
1484 // eigenvalues of A^T*A are the squared singular values of A. | 1511 // eigenvalues of A^T*A are the squared singular values of A. |
1485 // characteristic equation is det((A^T*A) - l*I) = 0 | 1512 // characteristic equation is det((A^T*A) - l*I) = 0 |
1486 // l^2 - (a + c)l + (ac-b^2) | 1513 // l^2 - (a + c)l + (ac-b^2) |
1487 // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff | 1514 // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff |
1488 // and roots are guaranteed to be pos and real). | 1515 // and roots are guaranteed to be pos and real). |
1489 SkScalar chosenRoot; | 1516 SkScalar chosenRoot; |
1490 SkScalar bSqd = SkScalarMul(b,b); | 1517 SkScalar bSqd = b * b; |
1491 // if upper left 2x2 is orthogonal save some math | 1518 // if upper left 2x2 is orthogonal save some math |
1492 if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) { | 1519 if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) { |
1493 if (kMin_MinOrMax == MIN_OR_MAX) { | 1520 if (kMin_MinOrMax == MIN_OR_MAX) { |
1494 chosenRoot = SkMinScalar(a, c); | 1521 chosenRoot = SkMinScalar(a, c); |
1495 } else { | 1522 } else { |
1496 chosenRoot = SkMaxScalar(a, c); | 1523 chosenRoot = SkMaxScalar(a, c); |
1497 } | 1524 } |
1498 } else { | 1525 } else { |
1499 SkScalar aminusc = a - c; | 1526 SkScalar aminusc = a - c; |
1500 SkScalar apluscdiv2 = SkScalarHalf(a + c); | 1527 SkScalar apluscdiv2 = SkScalarHalf(a + c); |
1501 SkScalar x = SkScalarHalf(SkScalarSqrt(SkScalarMul(aminusc, aminusc) + 4
* bSqd)); | 1528 SkScalar x = SkScalarHalf(SkScalarSqrt(aminusc * aminusc + 4 * bSqd)); |
1502 if (kMin_MinOrMax == MIN_OR_MAX) { | 1529 if (kMin_MinOrMax == MIN_OR_MAX) { |
1503 chosenRoot = apluscdiv2 - x; | 1530 chosenRoot = apluscdiv2 - x; |
1504 } else { | 1531 } else { |
1505 chosenRoot = apluscdiv2 + x; | 1532 chosenRoot = apluscdiv2 + x; |
1506 } | 1533 } |
1507 } | 1534 } |
1508 SkASSERT(chosenRoot >= 0); | 1535 SkASSERT(chosenRoot >= 0); |
1509 return SkScalarSqrt(chosenRoot); | 1536 return SkScalarSqrt(chosenRoot); |
1510 } | 1537 } |
1511 | 1538 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1654 | 1681 |
1655 double w1, w2; | 1682 double w1, w2; |
1656 SkScalar cos1, sin1; | 1683 SkScalar cos1, sin1; |
1657 SkScalar cos2, sin2; | 1684 SkScalar cos2, sin2; |
1658 | 1685 |
1659 // do polar decomposition (M = Q*S) | 1686 // do polar decomposition (M = Q*S) |
1660 SkScalar cosQ, sinQ; | 1687 SkScalar cosQ, sinQ; |
1661 double Sa, Sb, Sd; | 1688 double Sa, Sb, Sd; |
1662 // if M is already symmetric (i.e., M = I*S) | 1689 // if M is already symmetric (i.e., M = I*S) |
1663 if (SkScalarNearlyEqual(B, C)) { | 1690 if (SkScalarNearlyEqual(B, C)) { |
1664 cosQ = SK_Scalar1; | 1691 cosQ = 1; |
1665 sinQ = 0; | 1692 sinQ = 0; |
1666 | 1693 |
1667 Sa = A; | 1694 Sa = A; |
1668 Sb = B; | 1695 Sb = B; |
1669 Sd = D; | 1696 Sd = D; |
1670 } else { | 1697 } else { |
1671 cosQ = A + D; | 1698 cosQ = A + D; |
1672 sinQ = C - B; | 1699 sinQ = C - B; |
1673 SkScalar reciplen = SK_Scalar1/SkScalarSqrt(cosQ*cosQ + sinQ*sinQ); | 1700 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cosQ*cosQ + sinQ*sinQ)); |
1674 cosQ *= reciplen; | 1701 cosQ *= reciplen; |
1675 sinQ *= reciplen; | 1702 sinQ *= reciplen; |
1676 | 1703 |
1677 // S = Q^-1*M | 1704 // S = Q^-1*M |
1678 // we don't calc Sc since it's symmetric | 1705 // we don't calc Sc since it's symmetric |
1679 Sa = A*cosQ + C*sinQ; | 1706 Sa = A*cosQ + C*sinQ; |
1680 Sb = B*cosQ + D*sinQ; | 1707 Sb = B*cosQ + D*sinQ; |
1681 Sd = -B*sinQ + D*cosQ; | 1708 Sd = -B*sinQ + D*cosQ; |
1682 } | 1709 } |
1683 | 1710 |
1684 // Now we need to compute eigenvalues of S (our scale factors) | 1711 // Now we need to compute eigenvalues of S (our scale factors) |
1685 // and eigenvectors (bases for our rotation) | 1712 // and eigenvectors (bases for our rotation) |
1686 // From this, should be able to reconstruct S as U*W*U^T | 1713 // From this, should be able to reconstruct S as U*W*U^T |
1687 if (SkScalarNearlyZero(SkDoubleToScalar(Sb))) { | 1714 if (SkScalarNearlyZero(SkDoubleToScalar(Sb))) { |
1688 // already diagonalized | 1715 // already diagonalized |
1689 cos1 = SK_Scalar1; | 1716 cos1 = 1; |
1690 sin1 = 0; | 1717 sin1 = 0; |
1691 w1 = Sa; | 1718 w1 = Sa; |
1692 w2 = Sd; | 1719 w2 = Sd; |
1693 cos2 = cosQ; | 1720 cos2 = cosQ; |
1694 sin2 = sinQ; | 1721 sin2 = sinQ; |
1695 } else { | 1722 } else { |
1696 double diff = Sa - Sd; | 1723 double diff = Sa - Sd; |
1697 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb); | 1724 double discriminant = sqrt(diff*diff + 4.0*Sb*Sb); |
1698 double trace = Sa + Sd; | 1725 double trace = Sa + Sd; |
1699 if (diff > 0) { | 1726 if (diff > 0) { |
1700 w1 = 0.5*(trace + discriminant); | 1727 w1 = 0.5*(trace + discriminant); |
1701 w2 = 0.5*(trace - discriminant); | 1728 w2 = 0.5*(trace - discriminant); |
1702 } else { | 1729 } else { |
1703 w1 = 0.5*(trace - discriminant); | 1730 w1 = 0.5*(trace - discriminant); |
1704 w2 = 0.5*(trace + discriminant); | 1731 w2 = 0.5*(trace + discriminant); |
1705 } | 1732 } |
1706 | 1733 |
1707 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa); | 1734 cos1 = SkDoubleToScalar(Sb); sin1 = SkDoubleToScalar(w1 - Sa); |
1708 SkScalar reciplen = SK_Scalar1/SkScalarSqrt(cos1*cos1 + sin1*sin1); | 1735 SkScalar reciplen = SkScalarInvert(SkScalarSqrt(cos1*cos1 + sin1*sin1)); |
1709 cos1 *= reciplen; | 1736 cos1 *= reciplen; |
1710 sin1 *= reciplen; | 1737 sin1 *= reciplen; |
1711 | 1738 |
1712 // rotation 2 is composition of Q and U | 1739 // rotation 2 is composition of Q and U |
1713 cos2 = cos1*cosQ - sin1*sinQ; | 1740 cos2 = cos1*cosQ - sin1*sinQ; |
1714 sin2 = sin1*cosQ + cos1*sinQ; | 1741 sin2 = sin1*cosQ + cos1*sinQ; |
1715 | 1742 |
1716 // rotation 1 is U^T | 1743 // rotation 1 is U^T |
1717 sin1 = -sin1; | 1744 sin1 = -sin1; |
1718 } | 1745 } |
1719 | 1746 |
1720 if (NULL != scale) { | 1747 if (NULL != scale) { |
1721 scale->fX = SkDoubleToScalar(w1); | 1748 scale->fX = SkDoubleToScalar(w1); |
1722 scale->fY = SkDoubleToScalar(w2); | 1749 scale->fY = SkDoubleToScalar(w2); |
1723 } | 1750 } |
1724 if (NULL != rotation1) { | 1751 if (NULL != rotation1) { |
1725 rotation1->fX = cos1; | 1752 rotation1->fX = cos1; |
1726 rotation1->fY = sin1; | 1753 rotation1->fY = sin1; |
1727 } | 1754 } |
1728 if (NULL != rotation2) { | 1755 if (NULL != rotation2) { |
1729 rotation2->fX = cos2; | 1756 rotation2->fX = cos2; |
1730 rotation2->fY = sin2; | 1757 rotation2->fY = sin2; |
1731 } | 1758 } |
1732 | 1759 |
1733 return true; | 1760 return true; |
1734 } | 1761 } |
OLD | NEW |