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