Chromium Code Reviews| 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" |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1; | 240 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1; |
| 241 fMat[kMSkewX] = fMat[kMSkewY] = | 241 fMat[kMSkewX] = fMat[kMSkewY] = |
| 242 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 242 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
| 243 | 243 |
| 244 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); | 244 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); |
| 245 } else { | 245 } else { |
| 246 this->reset(); | 246 this->reset(); |
| 247 } | 247 } |
| 248 } | 248 } |
| 249 | 249 |
| 250 bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { | 250 void SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { |
| 251 if (!dx && !dy) { | |
| 252 return; | |
| 253 } | |
| 254 | |
| 251 if (this->hasPerspective()) { | 255 if (this->hasPerspective()) { |
| 252 SkMatrix m; | 256 SkMatrix m; |
| 253 m.setTranslate(dx, dy); | 257 m.setTranslate(dx, dy); |
| 254 return this->preConcat(m); | 258 this->preConcat(m); |
| 259 } else { | |
| 260 fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy); | |
| 261 fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy); | |
| 262 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | |
| 263 } | |
| 264 } | |
| 265 | |
| 266 void SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { | |
| 267 if (!dx && !dy) { | |
| 268 return; | |
| 255 } | 269 } |
| 256 | 270 |
| 257 if (dx || dy) { | |
| 258 fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy); | |
| 259 fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy); | |
| 260 | |
| 261 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | |
| 262 } | |
| 263 return true; | |
| 264 } | |
| 265 | |
| 266 bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { | |
| 267 if (this->hasPerspective()) { | 271 if (this->hasPerspective()) { |
| 268 SkMatrix m; | 272 SkMatrix m; |
| 269 m.setTranslate(dx, dy); | 273 m.setTranslate(dx, dy); |
| 270 return this->postConcat(m); | 274 this->postConcat(m); |
| 271 } | 275 } else { |
| 272 | |
| 273 if (dx || dy) { | |
| 274 fMat[kMTransX] += dx; | 276 fMat[kMTransX] += dx; |
| 275 fMat[kMTransY] += dy; | 277 fMat[kMTransY] += dy; |
| 276 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 278 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 277 } | 279 } |
| 278 return true; | |
| 279 } | 280 } |
| 280 | 281 |
| 281 /////////////////////////////////////////////////////////////////////////////// | 282 /////////////////////////////////////////////////////////////////////////////// |
| 282 | 283 |
| 283 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 284 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 284 if (1 == sx && 1 == sy) { | 285 if (1 == sx && 1 == sy) { |
| 285 this->reset(); | 286 this->reset(); |
| 286 } else { | 287 } else { |
| 287 fMat[kMScaleX] = sx; | 288 fMat[kMScaleX] = sx; |
| 288 fMat[kMScaleY] = sy; | 289 fMat[kMScaleY] = sy; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 314 } | 315 } |
| 315 | 316 |
| 316 bool SkMatrix::setIDiv(int divx, int divy) { | 317 bool SkMatrix::setIDiv(int divx, int divy) { |
| 317 if (!divx || !divy) { | 318 if (!divx || !divy) { |
| 318 return false; | 319 return false; |
| 319 } | 320 } |
| 320 this->setScale(SkScalarInvert(divx), SkScalarInvert(divy)); | 321 this->setScale(SkScalarInvert(divx), SkScalarInvert(divy)); |
| 321 return true; | 322 return true; |
| 322 } | 323 } |
| 323 | 324 |
| 324 bool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 325 void SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
|
robertphillips
2014/03/14 17:35:18
Why no sx & sy checks here? All the other kids get
fmalita_google_do_not_use
2014/03/14 17:39:14
I had to leave for Chipotle ;)
(will do)
| |
| 325 SkMatrix m; | 326 SkMatrix m; |
| 326 m.setScale(sx, sy, px, py); | 327 m.setScale(sx, sy, px, py); |
| 327 return this->preConcat(m); | 328 this->preConcat(m); |
| 328 } | 329 } |
| 329 | 330 |
| 330 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) { | 331 void SkMatrix::preScale(SkScalar sx, SkScalar sy) { |
| 331 if (1 == sx && 1 == sy) { | 332 if (1 == sx && 1 == sy) { |
| 332 return true; | 333 return; |
| 333 } | 334 } |
| 334 | 335 |
| 335 // the assumption is that these multiplies are very cheap, and that | 336 // the assumption is that these multiplies are very cheap, and that |
| 336 // a full concat and/or just computing the matrix type is more expensive. | 337 // a full concat and/or just computing the matrix type is more expensive. |
| 337 // Also, the fixed-point case checks for overflow, but the float doesn't, | 338 // Also, the fixed-point case checks for overflow, but the float doesn't, |
| 338 // so we can get away with these blind multiplies. | 339 // so we can get away with these blind multiplies. |
| 339 | 340 |
| 340 fMat[kMScaleX] *= sx; | 341 fMat[kMScaleX] *= sx; |
| 341 fMat[kMSkewY] *= sx; | 342 fMat[kMSkewY] *= sx; |
| 342 fMat[kMPersp0] *= sx; | 343 fMat[kMPersp0] *= sx; |
| 343 | 344 |
| 344 fMat[kMSkewX] *= sy; | 345 fMat[kMSkewX] *= sy; |
| 345 fMat[kMScaleY] *= sy; | 346 fMat[kMScaleY] *= sy; |
| 346 fMat[kMPersp1] *= sy; | 347 fMat[kMPersp1] *= sy; |
| 347 | 348 |
| 348 this->orTypeMask(kScale_Mask); | 349 this->orTypeMask(kScale_Mask); |
| 349 return true; | |
| 350 } | 350 } |
| 351 | 351 |
| 352 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 352 void SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 353 if (1 == sx && 1 == sy) { | 353 if (1 == sx && 1 == sy) { |
| 354 return true; | 354 return; |
| 355 } | 355 } |
| 356 SkMatrix m; | 356 SkMatrix m; |
| 357 m.setScale(sx, sy, px, py); | 357 m.setScale(sx, sy, px, py); |
| 358 return this->postConcat(m); | 358 this->postConcat(m); |
| 359 } | 359 } |
| 360 | 360 |
| 361 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) { | 361 void SkMatrix::postScale(SkScalar sx, SkScalar sy) { |
| 362 if (1 == sx && 1 == sy) { | 362 if (1 == sx && 1 == sy) { |
| 363 return true; | 363 return; |
| 364 } | 364 } |
| 365 SkMatrix m; | 365 SkMatrix m; |
| 366 m.setScale(sx, sy); | 366 m.setScale(sx, sy); |
| 367 return this->postConcat(m); | 367 this->postConcat(m); |
| 368 } | 368 } |
| 369 | 369 |
| 370 // 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 |
| 371 // scale matrices | 371 // scale matrices |
| 372 bool SkMatrix::postIDiv(int divx, int divy) { | 372 bool SkMatrix::postIDiv(int divx, int divy) { |
| 373 if (divx == 0 || divy == 0) { | 373 if (divx == 0 || divy == 0) { |
| 374 return false; | 374 return false; |
| 375 } | 375 } |
| 376 | 376 |
| 377 const float invX = 1.f / divx; | 377 const float invX = 1.f / divx; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); | 429 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); |
| 430 this->setSinCos(sinV, cosV, px, py); | 430 this->setSinCos(sinV, cosV, px, py); |
| 431 } | 431 } |
| 432 | 432 |
| 433 void SkMatrix::setRotate(SkScalar degrees) { | 433 void SkMatrix::setRotate(SkScalar degrees) { |
| 434 SkScalar sinV, cosV; | 434 SkScalar sinV, cosV; |
| 435 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); | 435 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); |
| 436 this->setSinCos(sinV, cosV); | 436 this->setSinCos(sinV, cosV); |
| 437 } | 437 } |
| 438 | 438 |
| 439 bool SkMatrix::preRotate(SkScalar degrees, SkScalar px, SkScalar py) { | 439 void SkMatrix::preRotate(SkScalar degrees, SkScalar px, SkScalar py) { |
| 440 SkMatrix m; | 440 SkMatrix m; |
| 441 m.setRotate(degrees, px, py); | 441 m.setRotate(degrees, px, py); |
| 442 return this->preConcat(m); | 442 this->preConcat(m); |
| 443 } | 443 } |
| 444 | 444 |
| 445 bool SkMatrix::preRotate(SkScalar degrees) { | 445 void SkMatrix::preRotate(SkScalar degrees) { |
| 446 SkMatrix m; | 446 SkMatrix m; |
| 447 m.setRotate(degrees); | 447 m.setRotate(degrees); |
| 448 return this->preConcat(m); | 448 this->preConcat(m); |
| 449 } | 449 } |
| 450 | 450 |
| 451 bool SkMatrix::postRotate(SkScalar degrees, SkScalar px, SkScalar py) { | 451 void SkMatrix::postRotate(SkScalar degrees, SkScalar px, SkScalar py) { |
| 452 SkMatrix m; | 452 SkMatrix m; |
| 453 m.setRotate(degrees, px, py); | 453 m.setRotate(degrees, px, py); |
| 454 return this->postConcat(m); | 454 this->postConcat(m); |
| 455 } | 455 } |
| 456 | 456 |
| 457 bool SkMatrix::postRotate(SkScalar degrees) { | 457 void SkMatrix::postRotate(SkScalar degrees) { |
| 458 SkMatrix m; | 458 SkMatrix m; |
| 459 m.setRotate(degrees); | 459 m.setRotate(degrees); |
| 460 return this->postConcat(m); | 460 this->postConcat(m); |
| 461 } | 461 } |
| 462 | 462 |
| 463 //////////////////////////////////////////////////////////////////////////////// //// | 463 //////////////////////////////////////////////////////////////////////////////// //// |
| 464 | 464 |
| 465 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 465 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 466 fMat[kMScaleX] = 1; | 466 fMat[kMScaleX] = 1; |
| 467 fMat[kMSkewX] = sx; | 467 fMat[kMSkewX] = sx; |
| 468 fMat[kMTransX] = -sx * py; | 468 fMat[kMTransX] = -sx * py; |
| 469 | 469 |
| 470 fMat[kMSkewY] = sy; | 470 fMat[kMSkewY] = sy; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 485 fMat[kMSkewY] = sy; | 485 fMat[kMSkewY] = sy; |
| 486 fMat[kMScaleY] = 1; | 486 fMat[kMScaleY] = 1; |
| 487 fMat[kMTransY] = 0; | 487 fMat[kMTransY] = 0; |
| 488 | 488 |
| 489 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 489 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
| 490 fMat[kMPersp2] = 1; | 490 fMat[kMPersp2] = 1; |
| 491 | 491 |
| 492 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 492 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 493 } | 493 } |
| 494 | 494 |
| 495 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 495 void SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 496 SkMatrix m; | 496 SkMatrix m; |
| 497 m.setSkew(sx, sy, px, py); | 497 m.setSkew(sx, sy, px, py); |
| 498 return this->preConcat(m); | 498 this->preConcat(m); |
| 499 } | 499 } |
| 500 | 500 |
| 501 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy) { | 501 void SkMatrix::preSkew(SkScalar sx, SkScalar sy) { |
| 502 SkMatrix m; | 502 SkMatrix m; |
| 503 m.setSkew(sx, sy); | 503 m.setSkew(sx, sy); |
| 504 return this->preConcat(m); | 504 this->preConcat(m); |
| 505 } | 505 } |
| 506 | 506 |
| 507 bool SkMatrix::postSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 507 void SkMatrix::postSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 508 SkMatrix m; | 508 SkMatrix m; |
| 509 m.setSkew(sx, sy, px, py); | 509 m.setSkew(sx, sy, px, py); |
| 510 return this->postConcat(m); | 510 this->postConcat(m); |
| 511 } | 511 } |
| 512 | 512 |
| 513 bool SkMatrix::postSkew(SkScalar sx, SkScalar sy) { | 513 void SkMatrix::postSkew(SkScalar sx, SkScalar sy) { |
| 514 SkMatrix m; | 514 SkMatrix m; |
| 515 m.setSkew(sx, sy); | 515 m.setSkew(sx, sy); |
| 516 return this->postConcat(m); | 516 this->postConcat(m); |
| 517 } | 517 } |
| 518 | 518 |
| 519 /////////////////////////////////////////////////////////////////////////////// | 519 /////////////////////////////////////////////////////////////////////////////// |
| 520 | 520 |
| 521 bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, | 521 bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, |
| 522 ScaleToFit align) | 522 ScaleToFit align) |
| 523 { | 523 { |
| 524 if (src.isEmpty()) { | 524 if (src.isEmpty()) { |
| 525 this->reset(); | 525 this->reset(); |
| 526 return false; | 526 return false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 581 } | 581 } |
| 582 this->setTypeMask(mask); | 582 this->setTypeMask(mask); |
| 583 } | 583 } |
| 584 // shared cleanup | 584 // shared cleanup |
| 585 fMat[kMPersp2] = 1; | 585 fMat[kMPersp2] = 1; |
| 586 return true; | 586 return true; |
| 587 } | 587 } |
| 588 | 588 |
| 589 /////////////////////////////////////////////////////////////////////////////// | 589 /////////////////////////////////////////////////////////////////////////////// |
| 590 | 590 |
| 591 static inline int fixmuladdmul(float a, float b, float c, float d, | 591 static inline float muladdmul(float a, float b, float c, float d) { |
| 592 float* result) { | 592 return SkDoubleToFloat((double)a * b + (double)c * d); |
| 593 *result = SkDoubleToFloat((double)a * b + (double)c * d); | |
| 594 return true; | |
| 595 } | 593 } |
| 596 | 594 |
| 597 static inline bool rowcol3(const float row[], const float col[], | 595 static inline float rowcol3(const float row[], const float col[]) { |
| 598 float* result) { | 596 return 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]; | |
| 600 return true; | |
| 601 } | |
| 602 | |
| 603 static inline int negifaddoverflows(float& result, float a, float b) { | |
| 604 result = a + b; | |
| 605 return 0; | |
| 606 } | 597 } |
| 607 | 598 |
| 608 static void normalize_perspective(SkScalar mat[9]) { | 599 static void normalize_perspective(SkScalar mat[9]) { |
| 609 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) { | 600 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) { |
| 610 for (int i = 0; i < 9; i++) | 601 for (int i = 0; i < 9; i++) |
| 611 mat[i] = SkScalarHalf(mat[i]); | 602 mat[i] = SkScalarHalf(mat[i]); |
| 612 } | 603 } |
| 613 } | 604 } |
| 614 | 605 |
| 615 bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { | 606 void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { |
| 616 TypeMask aType = a.getPerspectiveTypeMaskOnly(); | 607 TypeMask aType = a.getPerspectiveTypeMaskOnly(); |
| 617 TypeMask bType = b.getPerspectiveTypeMaskOnly(); | 608 TypeMask bType = b.getPerspectiveTypeMaskOnly(); |
| 618 | 609 |
| 619 if (a.isTriviallyIdentity()) { | 610 if (a.isTriviallyIdentity()) { |
| 620 *this = b; | 611 *this = b; |
| 621 } else if (b.isTriviallyIdentity()) { | 612 } else if (b.isTriviallyIdentity()) { |
| 622 *this = a; | 613 *this = a; |
| 623 } else { | 614 } else { |
| 624 SkMatrix tmp; | 615 SkMatrix tmp; |
| 625 | 616 |
| 626 if ((aType | bType) & kPerspective_Mask) { | 617 if ((aType | bType) & kPerspective_Mask) { |
| 627 if (!rowcol3(&a.fMat[0], &b.fMat[0], &tmp.fMat[kMScaleX])) { | 618 tmp.fMat[kMScaleX] = rowcol3(&a.fMat[0], &b.fMat[0]); |
| 628 return false; | 619 tmp.fMat[kMSkewX] = rowcol3(&a.fMat[0], &b.fMat[1]); |
| 629 } | 620 tmp.fMat[kMTransX] = rowcol3(&a.fMat[0], &b.fMat[2]); |
| 630 if (!rowcol3(&a.fMat[0], &b.fMat[1], &tmp.fMat[kMSkewX])) { | 621 tmp.fMat[kMSkewY] = rowcol3(&a.fMat[3], &b.fMat[0]); |
| 631 return false; | 622 tmp.fMat[kMScaleY] = rowcol3(&a.fMat[3], &b.fMat[1]); |
| 632 } | 623 tmp.fMat[kMTransY] = rowcol3(&a.fMat[3], &b.fMat[2]); |
| 633 if (!rowcol3(&a.fMat[0], &b.fMat[2], &tmp.fMat[kMTransX])) { | 624 tmp.fMat[kMPersp0] = rowcol3(&a.fMat[6], &b.fMat[0]); |
| 634 return false; | 625 tmp.fMat[kMPersp1] = rowcol3(&a.fMat[6], &b.fMat[1]); |
| 635 } | 626 tmp.fMat[kMPersp2] = rowcol3(&a.fMat[6], &b.fMat[2]); |
| 636 | |
| 637 if (!rowcol3(&a.fMat[3], &b.fMat[0], &tmp.fMat[kMSkewY])) { | |
| 638 return false; | |
| 639 } | |
| 640 if (!rowcol3(&a.fMat[3], &b.fMat[1], &tmp.fMat[kMScaleY])) { | |
| 641 return false; | |
| 642 } | |
| 643 if (!rowcol3(&a.fMat[3], &b.fMat[2], &tmp.fMat[kMTransY])) { | |
| 644 return false; | |
| 645 } | |
| 646 | |
| 647 if (!rowcol3(&a.fMat[6], &b.fMat[0], &tmp.fMat[kMPersp0])) { | |
| 648 return false; | |
| 649 } | |
| 650 if (!rowcol3(&a.fMat[6], &b.fMat[1], &tmp.fMat[kMPersp1])) { | |
| 651 return false; | |
| 652 } | |
| 653 if (!rowcol3(&a.fMat[6], &b.fMat[2], &tmp.fMat[kMPersp2])) { | |
| 654 return false; | |
| 655 } | |
| 656 | 627 |
| 657 normalize_perspective(tmp.fMat); | 628 normalize_perspective(tmp.fMat); |
| 658 tmp.setTypeMask(kUnknown_Mask); | 629 tmp.setTypeMask(kUnknown_Mask); |
| 659 } else { // not perspective | 630 } else { // not perspective |
| 660 if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMScaleX], | 631 tmp.fMat[kMScaleX] = muladdmul(a.fMat[kMScaleX], |
| 661 a.fMat[kMSkewX], b.fMat[kMSkewY], &tmp.fMat[kMScaleX])) { | 632 b.fMat[kMScaleX], |
| 662 return false; | 633 a.fMat[kMSkewX], |
| 663 } | 634 b.fMat[kMSkewY]); |
| 664 if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMSkewX], | |
| 665 a.fMat[kMSkewX], b.fMat[kMScaleY], &tmp.fMat[kMSkewX])) { | |
| 666 return false; | |
| 667 } | |
| 668 if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMTransX], | |
| 669 a.fMat[kMSkewX], b.fMat[kMTransY], &tmp.fMat[kMTransX])) { | |
| 670 return false; | |
| 671 } | |
| 672 if (negifaddoverflows(tmp.fMat[kMTransX], tmp.fMat[kMTransX], | |
| 673 a.fMat[kMTransX]) < 0) { | |
| 674 return false; | |
| 675 } | |
| 676 | 635 |
| 677 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMScaleX], | 636 tmp.fMat[kMSkewX] = muladdmul(a.fMat[kMScaleX], |
| 678 a.fMat[kMScaleY], b.fMat[kMSkewY], &tmp.fMat[kMSkewY])) { | 637 b.fMat[kMSkewX], |
| 679 return false; | 638 a.fMat[kMSkewX], |
| 680 } | 639 b.fMat[kMScaleY]); |
| 681 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMSkewX], | |
| 682 a.fMat[kMScaleY], b.fMat[kMScaleY], &tmp.fMat[kMScaleY])) { | |
| 683 return false; | |
| 684 } | |
| 685 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMTransX], | |
| 686 a.fMat[kMScaleY], b.fMat[kMTransY], &tmp.fMat[kMTransY])) { | |
| 687 return false; | |
| 688 } | |
| 689 if (negifaddoverflows(tmp.fMat[kMTransY], tmp.fMat[kMTransY], | |
| 690 a.fMat[kMTransY]) < 0) { | |
| 691 return false; | |
| 692 } | |
| 693 | 640 |
| 641 tmp.fMat[kMTransX] = muladdmul(a.fMat[kMScaleX], | |
| 642 b.fMat[kMTransX], | |
| 643 a.fMat[kMSkewX], | |
| 644 b.fMat[kMTransY]); | |
| 645 | |
| 646 tmp.fMat[kMTransX] += a.fMat[kMTransX]; | |
| 647 | |
| 648 tmp.fMat[kMSkewY] = muladdmul(a.fMat[kMSkewY], | |
| 649 b.fMat[kMScaleX], | |
| 650 a.fMat[kMScaleY], | |
| 651 b.fMat[kMSkewY]); | |
| 652 | |
| 653 tmp.fMat[kMScaleY] = muladdmul(a.fMat[kMSkewY], | |
| 654 b.fMat[kMSkewX], | |
| 655 a.fMat[kMScaleY], | |
| 656 b.fMat[kMScaleY]); | |
| 657 | |
| 658 tmp.fMat[kMTransY] = muladdmul(a.fMat[kMSkewY], | |
| 659 b.fMat[kMTransX], | |
| 660 a.fMat[kMScaleY], | |
| 661 b.fMat[kMTransY]); | |
| 662 | |
| 663 tmp.fMat[kMTransY] += a.fMat[kMTransY]; | |
| 694 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; | 664 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; |
| 695 tmp.fMat[kMPersp2] = 1; | 665 tmp.fMat[kMPersp2] = 1; |
| 696 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); | 666 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); |
| 697 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); | 667 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); |
| 698 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 668 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 699 } | 669 } |
| 700 *this = tmp; | 670 *this = tmp; |
| 701 } | 671 } |
| 702 return true; | |
| 703 } | 672 } |
| 704 | 673 |
| 705 bool SkMatrix::preConcat(const SkMatrix& mat) { | 674 void SkMatrix::preConcat(const SkMatrix& mat) { |
| 706 // check for identity first, so we don't do a needless copy of ourselves | 675 // check for identity first, so we don't do a needless copy of ourselves |
| 707 // to ourselves inside setConcat() | 676 // to ourselves inside setConcat() |
| 708 return mat.isIdentity() || this->setConcat(*this, mat); | 677 if(!mat.isIdentity()) { |
| 678 this->setConcat(*this, mat); | |
| 679 } | |
| 709 } | 680 } |
| 710 | 681 |
| 711 bool SkMatrix::postConcat(const SkMatrix& mat) { | 682 void SkMatrix::postConcat(const SkMatrix& mat) { |
| 712 // check for identity first, so we don't do a needless copy of ourselves | 683 // check for identity first, so we don't do a needless copy of ourselves |
| 713 // to ourselves inside setConcat() | 684 // to ourselves inside setConcat() |
| 714 return mat.isIdentity() || this->setConcat(mat, *this); | 685 if (!mat.isIdentity()) { |
| 686 this->setConcat(mat, *this); | |
| 687 } | |
| 715 } | 688 } |
| 716 | 689 |
| 717 /////////////////////////////////////////////////////////////////////////////// | 690 /////////////////////////////////////////////////////////////////////////////// |
| 718 | 691 |
| 719 /* Matrix inversion is very expensive, but also the place where keeping | 692 /* Matrix inversion is very expensive, but also the place where keeping |
| 720 precision may be most important (here and matrix concat). Hence to avoid | 693 precision may be most important (here and matrix concat). Hence to avoid |
| 721 bitmap blitting artifacts when walking the inverse, we use doubles for | 694 bitmap blitting artifacts when walking the inverse, we use doubles for |
| 722 the intermediate math, even though we know that is more expensive. | 695 the intermediate math, even though we know that is more expensive. |
| 723 */ | 696 */ |
| 724 | 697 |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1461 | 1434 |
| 1462 if (!proc(src, &tempMap, scale)) { | 1435 if (!proc(src, &tempMap, scale)) { |
| 1463 return false; | 1436 return false; |
| 1464 } | 1437 } |
| 1465 if (!tempMap.invert(&result)) { | 1438 if (!tempMap.invert(&result)) { |
| 1466 return false; | 1439 return false; |
| 1467 } | 1440 } |
| 1468 if (!proc(dst, &tempMap, scale)) { | 1441 if (!proc(dst, &tempMap, scale)) { |
| 1469 return false; | 1442 return false; |
| 1470 } | 1443 } |
| 1471 if (!result.setConcat(tempMap, result)) { | 1444 this->setConcat(tempMap, result); |
| 1472 return false; | |
| 1473 } | |
| 1474 *this = result; | |
| 1475 return true; | 1445 return true; |
| 1476 } | 1446 } |
| 1477 | 1447 |
| 1478 /////////////////////////////////////////////////////////////////////////////// | 1448 /////////////////////////////////////////////////////////////////////////////// |
| 1479 | 1449 |
| 1480 enum MinOrMax { | 1450 enum MinOrMax { |
| 1481 kMin_MinOrMax, | 1451 kMin_MinOrMax, |
| 1482 kMax_MinOrMax | 1452 kMax_MinOrMax |
| 1483 }; | 1453 }; |
| 1484 | 1454 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1754 rotation1->fX = cos1; | 1724 rotation1->fX = cos1; |
| 1755 rotation1->fY = sin1; | 1725 rotation1->fY = sin1; |
| 1756 } | 1726 } |
| 1757 if (NULL != rotation2) { | 1727 if (NULL != rotation2) { |
| 1758 rotation2->fX = cos2; | 1728 rotation2->fX = cos2; |
| 1759 rotation2->fY = sin2; | 1729 rotation2->fY = sin2; |
| 1760 } | 1730 } |
| 1761 | 1731 |
| 1762 return true; | 1732 return true; |
| 1763 } | 1733 } |
| OLD | NEW |