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 |