Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: src/core/SkMatrix.cpp

Issue 150493002: remove unnecessary SkScalar macros (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: review comments from #8 Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698