| 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 "SkString.h" | 10 #include "SkString.h" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 273 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 274 } | 274 } |
| 275 } | 275 } |
| 276 | 276 |
| 277 /////////////////////////////////////////////////////////////////////////////// | 277 /////////////////////////////////////////////////////////////////////////////// |
| 278 | 278 |
| 279 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 279 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 280 if (1 == sx && 1 == sy) { | 280 if (1 == sx && 1 == sy) { |
| 281 this->reset(); | 281 this->reset(); |
| 282 } else { | 282 } else { |
| 283 this->setScaleTranslate(sx, sy, px - sx * px, py - sy * py); | 283 fMat[kMScaleX] = sx; |
| 284 fMat[kMScaleY] = sy; |
| 285 fMat[kMTransX] = px - sx * px; |
| 286 fMat[kMTransY] = py - sy * py; |
| 287 fMat[kMPersp2] = 1; |
| 288 |
| 289 fMat[kMSkewX] = fMat[kMSkewY] = |
| 290 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
| 291 |
| 292 this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask); |
| 284 } | 293 } |
| 285 } | 294 } |
| 286 | 295 |
| 287 void SkMatrix::setScale(SkScalar sx, SkScalar sy) { | 296 void SkMatrix::setScale(SkScalar sx, SkScalar sy) { |
| 288 if (1 == sx && 1 == sy) { | 297 if (1 == sx && 1 == sy) { |
| 289 this->reset(); | 298 this->reset(); |
| 290 } else { | 299 } else { |
| 291 fMat[kMScaleX] = sx; | 300 fMat[kMScaleX] = sx; |
| 292 fMat[kMScaleY] = sy; | 301 fMat[kMScaleY] = sy; |
| 293 fMat[kMPersp2] = 1; | 302 fMat[kMPersp2] = 1; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 fMat[kMScaleY] *= invY; | 383 fMat[kMScaleY] *= invY; |
| 375 fMat[kMSkewY] *= invY; | 384 fMat[kMSkewY] *= invY; |
| 376 fMat[kMTransY] *= invY; | 385 fMat[kMTransY] *= invY; |
| 377 | 386 |
| 378 this->setTypeMask(kUnknown_Mask); | 387 this->setTypeMask(kUnknown_Mask); |
| 379 return true; | 388 return true; |
| 380 } | 389 } |
| 381 | 390 |
| 382 ////////////////////////////////////////////////////////////////////////////////
//// | 391 ////////////////////////////////////////////////////////////////////////////////
//// |
| 383 | 392 |
| 384 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, SkScalar px, SkScalar py)
{ | 393 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, |
| 394 SkScalar px, SkScalar py) { |
| 385 const SkScalar oneMinusCosV = 1 - cosV; | 395 const SkScalar oneMinusCosV = 1 - cosV; |
| 386 | 396 |
| 387 fMat[kMScaleX] = cosV; | 397 fMat[kMScaleX] = cosV; |
| 388 fMat[kMSkewX] = -sinV; | 398 fMat[kMSkewX] = -sinV; |
| 389 fMat[kMTransX] = sdot(sinV, py, oneMinusCosV, px); | 399 fMat[kMTransX] = sdot(sinV, py, oneMinusCosV, px); |
| 390 | 400 |
| 391 fMat[kMSkewY] = sinV; | 401 fMat[kMSkewY] = sinV; |
| 392 fMat[kMScaleY] = cosV; | 402 fMat[kMScaleY] = cosV; |
| 393 fMat[kMTransY] = sdot(-sinV, px, oneMinusCosV, py); | 403 fMat[kMTransY] = sdot(-sinV, px, oneMinusCosV, py); |
| 394 | 404 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 } | 510 } |
| 501 | 511 |
| 502 void SkMatrix::postSkew(SkScalar sx, SkScalar sy) { | 512 void SkMatrix::postSkew(SkScalar sx, SkScalar sy) { |
| 503 SkMatrix m; | 513 SkMatrix m; |
| 504 m.setSkew(sx, sy); | 514 m.setSkew(sx, sy); |
| 505 this->postConcat(m); | 515 this->postConcat(m); |
| 506 } | 516 } |
| 507 | 517 |
| 508 /////////////////////////////////////////////////////////////////////////////// | 518 /////////////////////////////////////////////////////////////////////////////// |
| 509 | 519 |
| 510 bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit al
ign) { | 520 bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, |
| 521 ScaleToFit align) |
| 522 { |
| 511 if (src.isEmpty()) { | 523 if (src.isEmpty()) { |
| 512 this->reset(); | 524 this->reset(); |
| 513 return false; | 525 return false; |
| 514 } | 526 } |
| 515 | 527 |
| 516 if (dst.isEmpty()) { | 528 if (dst.isEmpty()) { |
| 517 sk_bzero(fMat, 8 * sizeof(SkScalar)); | 529 sk_bzero(fMat, 8 * sizeof(SkScalar)); |
| 518 fMat[kMPersp2] = 1; | |
| 519 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); | 530 this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); |
| 520 } else { | 531 } else { |
| 521 SkScalar tx, sx = dst.width() / src.width(); | 532 SkScalar tx, sx = dst.width() / src.width(); |
| 522 SkScalar ty, sy = dst.height() / src.height(); | 533 SkScalar ty, sy = dst.height() / src.height(); |
| 523 bool xLarger = false; | 534 bool xLarger = false; |
| 524 | 535 |
| 525 if (align != kFill_ScaleToFit) { | 536 if (align != kFill_ScaleToFit) { |
| 526 if (sx > sy) { | 537 if (sx > sy) { |
| 527 xLarger = true; | 538 xLarger = true; |
| 528 sx = sy; | 539 sx = sy; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 546 diff = SkScalarHalf(diff); | 557 diff = SkScalarHalf(diff); |
| 547 } | 558 } |
| 548 | 559 |
| 549 if (xLarger) { | 560 if (xLarger) { |
| 550 tx += diff; | 561 tx += diff; |
| 551 } else { | 562 } else { |
| 552 ty += diff; | 563 ty += diff; |
| 553 } | 564 } |
| 554 } | 565 } |
| 555 | 566 |
| 556 this->setScaleTranslate(sx, sy, tx, ty); | 567 fMat[kMScaleX] = sx; |
| 568 fMat[kMScaleY] = sy; |
| 569 fMat[kMTransX] = tx; |
| 570 fMat[kMTransY] = ty; |
| 571 fMat[kMSkewX] = fMat[kMSkewY] = |
| 572 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
| 573 |
| 574 unsigned mask = kRectStaysRect_Mask; |
| 575 if (sx != 1 || sy != 1) { |
| 576 mask |= kScale_Mask; |
| 577 } |
| 578 if (tx || ty) { |
| 579 mask |= kTranslate_Mask; |
| 580 } |
| 581 this->setTypeMask(mask); |
| 557 } | 582 } |
| 583 // shared cleanup |
| 584 fMat[kMPersp2] = 1; |
| 558 return true; | 585 return true; |
| 559 } | 586 } |
| 560 | 587 |
| 561 /////////////////////////////////////////////////////////////////////////////// | 588 /////////////////////////////////////////////////////////////////////////////// |
| 562 | 589 |
| 563 static inline float muladdmul(float a, float b, float c, float d) { | 590 static inline float muladdmul(float a, float b, float c, float d) { |
| 564 return SkDoubleToFloat((double)a * b + (double)c * d); | 591 return SkDoubleToFloat((double)a * b + (double)c * d); |
| 565 } | 592 } |
| 566 | 593 |
| 567 static inline float rowcol3(const float row[], const float col[]) { | 594 static inline float rowcol3(const float row[], const float col[]) { |
| 568 return row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; | 595 return row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; |
| 569 } | 596 } |
| 570 | 597 |
| 571 static void normalize_perspective(SkScalar mat[9]) { | 598 static void normalize_perspective(SkScalar mat[9]) { |
| 572 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) { | 599 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) { |
| 573 for (int i = 0; i < 9; i++) | 600 for (int i = 0; i < 9; i++) |
| 574 mat[i] = SkScalarHalf(mat[i]); | 601 mat[i] = SkScalarHalf(mat[i]); |
| 575 } | 602 } |
| 576 } | 603 } |
| 577 | 604 |
| 578 static bool only_scale_and_translate(unsigned mask) { | |
| 579 return 0 == (mask & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)); | |
| 580 } | |
| 581 | |
| 582 void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { | 605 void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { |
| 583 TypeMask aType = a.getType(); | 606 TypeMask aType = a.getPerspectiveTypeMaskOnly(); |
| 584 TypeMask bType = b.getType(); | 607 TypeMask bType = b.getPerspectiveTypeMaskOnly(); |
| 585 | 608 |
| 586 if (a.isTriviallyIdentity()) { | 609 if (a.isTriviallyIdentity()) { |
| 587 *this = b; | 610 *this = b; |
| 588 } else if (b.isTriviallyIdentity()) { | 611 } else if (b.isTriviallyIdentity()) { |
| 589 *this = a; | 612 *this = a; |
| 590 } else if (only_scale_and_translate(aType | bType)) { | |
| 591 this->setScaleTranslate(a.fMat[kMScaleX] * b.fMat[kMScaleX], | |
| 592 a.fMat[kMScaleY] * b.fMat[kMScaleY], | |
| 593 a.fMat[kMScaleX] * b.fMat[kMTransX] + a.fMat[kMT
ransX], | |
| 594 a.fMat[kMScaleY] * b.fMat[kMTransY] + a.fMat[kMT
ransY]); | |
| 595 } else { | 613 } else { |
| 596 SkMatrix tmp; | 614 SkMatrix tmp; |
| 597 | 615 |
| 598 if ((aType | bType) & kPerspective_Mask) { | 616 if ((aType | bType) & kPerspective_Mask) { |
| 599 tmp.fMat[kMScaleX] = rowcol3(&a.fMat[0], &b.fMat[0]); | 617 tmp.fMat[kMScaleX] = rowcol3(&a.fMat[0], &b.fMat[0]); |
| 600 tmp.fMat[kMSkewX] = rowcol3(&a.fMat[0], &b.fMat[1]); | 618 tmp.fMat[kMSkewX] = rowcol3(&a.fMat[0], &b.fMat[1]); |
| 601 tmp.fMat[kMTransX] = rowcol3(&a.fMat[0], &b.fMat[2]); | 619 tmp.fMat[kMTransX] = rowcol3(&a.fMat[0], &b.fMat[2]); |
| 602 tmp.fMat[kMSkewY] = rowcol3(&a.fMat[3], &b.fMat[0]); | 620 tmp.fMat[kMSkewY] = rowcol3(&a.fMat[3], &b.fMat[0]); |
| 603 tmp.fMat[kMScaleY] = rowcol3(&a.fMat[3], &b.fMat[1]); | 621 tmp.fMat[kMScaleY] = rowcol3(&a.fMat[3], &b.fMat[1]); |
| 604 tmp.fMat[kMTransY] = rowcol3(&a.fMat[3], &b.fMat[2]); | 622 tmp.fMat[kMTransY] = rowcol3(&a.fMat[3], &b.fMat[2]); |
| 605 tmp.fMat[kMPersp0] = rowcol3(&a.fMat[6], &b.fMat[0]); | 623 tmp.fMat[kMPersp0] = rowcol3(&a.fMat[6], &b.fMat[0]); |
| 606 tmp.fMat[kMPersp1] = rowcol3(&a.fMat[6], &b.fMat[1]); | 624 tmp.fMat[kMPersp1] = rowcol3(&a.fMat[6], &b.fMat[1]); |
| 607 tmp.fMat[kMPersp2] = rowcol3(&a.fMat[6], &b.fMat[2]); | 625 tmp.fMat[kMPersp2] = rowcol3(&a.fMat[6], &b.fMat[2]); |
| 608 | 626 |
| 609 normalize_perspective(tmp.fMat); | 627 normalize_perspective(tmp.fMat); |
| 610 tmp.setTypeMask(kUnknown_Mask); | 628 tmp.setTypeMask(kUnknown_Mask); |
| 611 } else { | 629 } else { // not perspective |
| 612 tmp.fMat[kMScaleX] = muladdmul(a.fMat[kMScaleX], | 630 tmp.fMat[kMScaleX] = muladdmul(a.fMat[kMScaleX], |
| 613 b.fMat[kMScaleX], | 631 b.fMat[kMScaleX], |
| 614 a.fMat[kMSkewX], | 632 a.fMat[kMSkewX], |
| 615 b.fMat[kMSkewY]); | 633 b.fMat[kMSkewY]); |
| 616 | 634 |
| 617 tmp.fMat[kMSkewX] = muladdmul(a.fMat[kMScaleX], | 635 tmp.fMat[kMSkewX] = muladdmul(a.fMat[kMScaleX], |
| 618 b.fMat[kMSkewX], | 636 b.fMat[kMSkewX], |
| 619 a.fMat[kMSkewX], | 637 a.fMat[kMSkewX], |
| 620 b.fMat[kMScaleY]); | 638 b.fMat[kMScaleY]); |
| 621 | 639 |
| 622 tmp.fMat[kMTransX] = muladdmul(a.fMat[kMScaleX], | 640 tmp.fMat[kMTransX] = muladdmul(a.fMat[kMScaleX], |
| 623 b.fMat[kMTransX], | 641 b.fMat[kMTransX], |
| 624 a.fMat[kMSkewX], | 642 a.fMat[kMSkewX], |
| 625 b.fMat[kMTransY]) + a.fMat[kMTransX]; | 643 b.fMat[kMTransY]); |
| 644 |
| 645 tmp.fMat[kMTransX] += a.fMat[kMTransX]; |
| 626 | 646 |
| 627 tmp.fMat[kMSkewY] = muladdmul(a.fMat[kMSkewY], | 647 tmp.fMat[kMSkewY] = muladdmul(a.fMat[kMSkewY], |
| 628 b.fMat[kMScaleX], | 648 b.fMat[kMScaleX], |
| 629 a.fMat[kMScaleY], | 649 a.fMat[kMScaleY], |
| 630 b.fMat[kMSkewY]); | 650 b.fMat[kMSkewY]); |
| 631 | 651 |
| 632 tmp.fMat[kMScaleY] = muladdmul(a.fMat[kMSkewY], | 652 tmp.fMat[kMScaleY] = muladdmul(a.fMat[kMSkewY], |
| 633 b.fMat[kMSkewX], | 653 b.fMat[kMSkewX], |
| 634 a.fMat[kMScaleY], | 654 a.fMat[kMScaleY], |
| 635 b.fMat[kMScaleY]); | 655 b.fMat[kMScaleY]); |
| 636 | 656 |
| 637 tmp.fMat[kMTransY] = muladdmul(a.fMat[kMSkewY], | 657 tmp.fMat[kMTransY] = muladdmul(a.fMat[kMSkewY], |
| 638 b.fMat[kMTransX], | 658 b.fMat[kMTransX], |
| 639 a.fMat[kMScaleY], | 659 a.fMat[kMScaleY], |
| 640 b.fMat[kMTransY]) + a.fMat[kMTransY]; | 660 b.fMat[kMTransY]); |
| 641 | 661 |
| 642 tmp.fMat[kMPersp0] = 0; | 662 tmp.fMat[kMTransY] += a.fMat[kMTransY]; |
| 643 tmp.fMat[kMPersp1] = 0; | 663 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; |
| 644 tmp.fMat[kMPersp2] = 1; | 664 tmp.fMat[kMPersp2] = 1; |
| 645 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); | 665 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); |
| 646 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); | 666 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); |
| 647 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 667 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 648 } | 668 } |
| 649 *this = tmp; | 669 *this = tmp; |
| 650 } | 670 } |
| 651 } | 671 } |
| 652 | 672 |
| 653 void SkMatrix::preConcat(const SkMatrix& mat) { | 673 void SkMatrix::preConcat(const SkMatrix& mat) { |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1754 rotation1->fX = cos1; | 1774 rotation1->fX = cos1; |
| 1755 rotation1->fY = sin1; | 1775 rotation1->fY = sin1; |
| 1756 } | 1776 } |
| 1757 if (rotation2) { | 1777 if (rotation2) { |
| 1758 rotation2->fX = cos2; | 1778 rotation2->fX = cos2; |
| 1759 rotation2->fY = sin2; | 1779 rotation2->fY = sin2; |
| 1760 } | 1780 } |
| 1761 | 1781 |
| 1762 return true; | 1782 return true; |
| 1763 } | 1783 } |
| OLD | NEW |