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 |