Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: src/core/SkMatrix.cpp

Issue 626583002: specialize setConcat for scale+translate (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkMatrix.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « include/core/SkMatrix.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698