1#Topic Matrix 2#Alias Matrices ## 3#Alias Matrix_Reference ## 4 5#Class SkMatrix 6 7#Code 8#Populate 9## 10 11Matrix holds a 3 by 3 matrix for transforming coordinates. This allows mapping 12Points and Vectors with translation, scaling, skewing, rotation, and 13perspective. 14 15Matrix elements are in row major order. Matrix does not have a constructor, 16so it must be explicitly initialized. setIdentity initializes Matrix 17so it has no effect. setTranslate, setScale, setSkew, setRotate, set9 and setAll 18initializes all Matrix elements with the corresponding mapping. 19 20Matrix includes a hidden variable that classifies the type of matrix to 21improve performance. Matrix is not thread safe unless getType is called first. 22 23# ------------------------------------------------------------------------------ 24 25#Method static SkMatrix MakeScale(SkScalar sx, SkScalar sy) 26#In Constructors 27#Line # constructs from scale on x-axis and y-axis ## 28#Populate 29 30#Example 31#Image 4 32canvas->concat(SkMatrix::MakeScale(4, 3)); 33canvas->drawBitmap(source, 0, 0); 34## 35 36#SeeAlso setScale postScale preScale 37 38## 39 40# ------------------------------------------------------------------------------ 41 42#Method static SkMatrix MakeScale(SkScalar scale) 43#Populate 44 45#Example 46#Image 4 47canvas->concat(SkMatrix::MakeScale(4)); 48canvas->drawBitmap(source, 0, 0); 49## 50 51#SeeAlso setScale postScale preScale 52 53## 54 55# ------------------------------------------------------------------------------ 56 57#Method static SkMatrix MakeTrans(SkScalar dx, SkScalar dy) 58#In Constructors 59#Line # constructs from translate on x-axis and y-axis ## 60#Populate 61 62#Example 63#Image 4 64SkMatrix matrix = SkMatrix::MakeTrans(64, 48); 65for (int i = 0; i < 4; ++i) { 66 canvas->drawBitmap(source, 0, 0); 67 canvas->concat(matrix); 68} 69## 70 71#SeeAlso setTranslate postTranslate preTranslate 72 73## 74 75# ------------------------------------------------------------------------------ 76 77#Method static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, 78 SkScalar skewY, SkScalar scaleY, SkScalar transY, 79 SkScalar pers0, SkScalar pers1, SkScalar pers2) 80#In Constructors 81#Line # constructs all nine values ## 82#Populate 83 84#Example 85 SkPaint p; 86 SkFont font(nullptr, 64); 87 for (SkScalar sx : { -1, 1 } ) { 88 for (SkScalar sy : { -1, 1 } ) { 89 SkAutoCanvasRestore autoRestore(canvas, true); 90 SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1); 91 canvas->concat(m); 92 canvas->drawString("K", 0, 0, font, p); 93 } 94 } 95## 96 97#SeeAlso setAll set9 postConcat preConcat 98 99## 100 101 102# ------------------------------------------------------------------------------ 103 104#Enum TypeMask 105#Line # bit field for Matrix complexity ## 106#Code 107#Populate 108## 109 110Enumeration of bit fields for mask returned by getType. 111Used to identify the complexity of Matrix, to optimize performance. 112 113#Const kIdentity_Mask 0 114#Line # identity Matrix; all bits clear ## 115all bits clear if Matrix is identity 116## 117#Const kTranslate_Mask 1 118#Line # translation Matrix ## 119set if Matrix has translation 120## 121#Const kScale_Mask 2 122#Line # scale Matrix ## 123set if Matrix scales x-axis or y-axis 124## 125#Const kAffine_Mask 4 126#Line # skew or rotate Matrix ## 127set if Matrix skews or rotates 128## 129#Const kPerspective_Mask 8 130#Line # perspective Matrix ## 131set if Matrix has perspective 132## 133 134#Example 135 auto debugster = [](const char* prefix, const SkMatrix& matrix) -> void { 136 SkString typeMask; 137 typeMask += SkMatrix::kIdentity_Mask == matrix.getType() ? "kIdentity_Mask " : ""; 138 typeMask += SkMatrix::kTranslate_Mask & matrix.getType() ? "kTranslate_Mask " : ""; 139 typeMask += SkMatrix::kScale_Mask & matrix.getType() ? "kScale_Mask " : ""; 140 typeMask += SkMatrix::kAffine_Mask & matrix.getType() ? "kAffine_Mask " : ""; 141 typeMask += SkMatrix::kPerspective_Mask & matrix.getType() ? "kPerspective_Mask" : ""; 142 SkDebugf("after %s: %s\n", prefix, typeMask.c_str()); 143 }; 144SkMatrix matrix; 145matrix.reset(); 146debugster("reset", matrix); 147matrix.postTranslate(1, 0); 148debugster("postTranslate", matrix); 149matrix.postScale(2, 1); 150debugster("postScale", matrix); 151matrix.postRotate(45); 152debugster("postScale", matrix); 153SkPoint polys[][4] = {{{0, 0}, {0, 1}, {1, 1}, {1, 0}}, {{0, 0}, {0, 1}, {2, 1}, {1, 0}}}; 154matrix.setPolyToPoly(polys[0], polys[1], 4); 155debugster("setPolyToPoly", matrix); 156#StdOut 157after reset: kIdentity_Mask 158after postTranslate: kTranslate_Mask 159after postScale: kTranslate_Mask kScale_Mask 160after postScale: kTranslate_Mask kScale_Mask kAffine_Mask 161after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask 162## 163## 164 165#SeeAlso getType 166 167## 168 169# ------------------------------------------------------------------------------ 170#Subtopic Property 171#Line # values and attributes ## 172## 173 174#Method TypeMask getType() const 175#In Property 176#Line # returns transform complexity ## 177#Populate 178 179#Example 180SkMatrix matrix; 181matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 182SkDebugf("identity flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType()); 183matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, .5f); 184SkDebugf("set all flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType()); 185#StdOut 186identity flags hex: 0 decimal: 0 187set all flags hex: f decimal: 15 188## 189## 190 191#SeeAlso TypeMask 192 193## 194 195# ------------------------------------------------------------------------------ 196 197#Method bool isIdentity() const 198#In Property 199#Line # returns if matrix equals the identity Matrix ## 200#Populate 201 202#Example 203SkMatrix matrix; 204matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 205SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false"); 206matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 2); 207SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false"); 208#StdOut 209is identity: true 210is identity: false 211## 212## 213 214#SeeAlso reset() setIdentity getType 215 216## 217 218# ------------------------------------------------------------------------------ 219 220#Method bool isScaleTranslate() const 221#In Property 222#Line # returns if transform is limited to scale and translate ## 223#Populate 224 225#Example 226SkMatrix matrix; 227for (SkScalar scaleX : { 1, 2 } ) { 228 for (SkScalar translateX : { 0, 20 } ) { 229 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1); 230 SkDebugf("is scale-translate: %s\n", matrix.isScaleTranslate() ? "true" : "false"); 231 } 232} 233#StdOut 234is scale-translate: true 235is scale-translate: true 236is scale-translate: true 237is scale-translate: true 238## 239## 240 241#SeeAlso setScale isTranslate setTranslate getType 242 243## 244 245# ------------------------------------------------------------------------------ 246 247#Method bool isTranslate() const 248#In Property 249#Line # returns if transform is limited to translate ## 250#Populate 251 252#Example 253SkMatrix matrix; 254for (SkScalar scaleX : { 1, 2 } ) { 255 for (SkScalar translateX : { 0, 20 } ) { 256 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1); 257 SkDebugf("is translate: %s\n", matrix.isTranslate() ? "true" : "false"); 258 } 259} 260#StdOut 261is translate: true 262is translate: true 263is translate: false 264is translate: false 265## 266## 267 268#SeeAlso setTranslate getType 269 270## 271 272# ------------------------------------------------------------------------------ 273 274#Method bool rectStaysRect() const 275#In Property 276#Line # returns if mapped Rect can be represented by another Rect ## 277#Populate 278 279#Example 280SkMatrix matrix; 281for (SkScalar angle: { 0, 90, 180, 270 } ) { 282 matrix.setRotate(angle); 283 SkDebugf("rectStaysRect: %s\n", matrix.rectStaysRect() ? "true" : "false"); 284} 285#StdOut 286rectStaysRect: true 287rectStaysRect: true 288rectStaysRect: true 289rectStaysRect: true 290## 291## 292 293#SeeAlso preservesAxisAlignment preservesRightAngles 294 295## 296 297# ------------------------------------------------------------------------------ 298 299#Method bool preservesAxisAlignment() const 300#In Property 301#Line # returns if mapping restricts to 90 degree multiples and mirroring ## 302#Populate 303 304#Example 305SkMatrix matrix; 306for (SkScalar angle: { 0, 90, 180, 270 } ) { 307 matrix.setRotate(angle); 308 SkDebugf("preservesAxisAlignment: %s\n", matrix.preservesAxisAlignment() ? "true" : "false"); 309} 310#StdOut 311preservesAxisAlignment: true 312preservesAxisAlignment: true 313preservesAxisAlignment: true 314preservesAxisAlignment: true 315## 316## 317 318#SeeAlso rectStaysRect preservesRightAngles 319 320## 321 322# ------------------------------------------------------------------------------ 323 324#Method bool hasPerspective() const 325#In Property 326#Line # returns if transform includes perspective ## 327#Populate 328 329#Example 330#Image 4 331SkMatrix matrix; 332SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 333SkRect::Make(source.bounds()).toQuad(bitmapBounds); 334matrix.setPolyToPoly(bitmapBounds, perspect, 4); 335canvas->concat(matrix); 336SkString string; 337string.printf("hasPerspective %s", matrix.hasPerspective() ? "true" : "false"); 338canvas->drawBitmap(source, 0, 0); 339SkPaint paint; 340SkFont font(nullptr, 48); 341canvas->drawString(string, 0, source.bounds().height() + 48, font, paint); 342## 343 344#SeeAlso setAll set9 MakeAll 345 346## 347 348# ------------------------------------------------------------------------------ 349 350#Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const 351#In Property 352#Line # returns if transform is limited to square scale and rotation ## 353#Populate 354 355#Example 356#Description 357String is drawn four times through but only two are visible. Drawing the pair 358with isSimilarity false reveals the pair not visible through the matrix. 359## 360 SkPaint p; 361 p.setAntiAlias(true); 362 SkMatrix m; 363 int below = 175; 364 for (SkScalar sx : { -1, 1 } ) { 365 for (SkScalar sy : { -1, 1 } ) { 366 m.setAll(sx, 1, 128, 1, sy, 32, 0, 0, 1); 367 bool isSimilarity = m.isSimilarity(); 368 SkString str; 369 str.printf("sx: %g sy: %g sim: %s", sx, sy, isSimilarity ? "true" : "false"); 370 { 371 SkAutoCanvasRestore autoRestore(canvas, true); 372 canvas->concat(m); 373 canvas->drawString(str, 0, 0, p); 374 } 375 if (!isSimilarity) { 376 canvas->drawString(str, 40, below, p); 377 below += 20; 378 } 379 } 380 } 381## 382 383#SeeAlso isScaleTranslate preservesRightAngles rectStaysRect isFixedStepInX 384 385## 386 387# ------------------------------------------------------------------------------ 388 389#Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const 390#In Property 391#Line # returns if mapped 90 angle remains 90 degrees ## 392#Populate 393 394#Example 395#Height 128 396#Description 397Equal scale is both similar and preserves right angles. 398Unequal scale is not similar but preserves right angles. 399Skews are not similar and do not preserve right angles. 400## 401SkPaint p; 402p.setAntiAlias(true); 403SkMatrix m; 404int pos = 0; 405for (SkScalar sx : { 1, 2 } ) { 406 for (SkScalar kx : { 0, 1 } ) { 407 m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1); 408 bool isSimilarity = m.isSimilarity(); 409 bool preservesRightAngles = m.preservesRightAngles(); 410 SkString str; 411 str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "", 412 preservesRightAngles ? "right" : ""); 413 SkAutoCanvasRestore autoRestore(canvas, true); 414 canvas->concat(m); 415 canvas->drawString(str, 0, pos, p); 416 pos += 20; 417 } 418} 419## 420 421#SeeAlso isScaleTranslate isSimilarity rectStaysRect isFixedStepInX 422 423## 424 425# ------------------------------------------------------------------------------ 426 427#Subtopic MemberIndex 428#In Constant 429#Line # member indices ## 430#Filter kM 431#Code 432#Populate 433## 434 435Matrix organizes its values in row order. These members correspond to 436each value in Matrix. 437 438#Const kMScaleX 0 439#Line # horizontal scale factor ## 440## 441#Const kMSkewX 1 442#Line # horizontal skew factor ## 443## 444#Const kMTransX 2 445#Line # horizontal translation ## 446## 447#Const kMSkewY 3 448#Line # vertical skew factor ## 449## 450#Const kMScaleY 4 451#Line # vertical scale factor ## 452## 453#Const kMTransY 5 454#Line # vertical translation ## 455## 456#Const kMPersp0 6 457#Line # input x perspective factor ## 458## 459#Const kMPersp1 7 460#Line # input y perspective factor ## 461## 462#Const kMPersp2 8 463#Line # perspective bias ## 464## 465 466#Example 467SkPaint black; 468SkFont font(nullptr, 48); 469SkPaint gray = black; 470gray.setColor(0xFF9f9f9f); 471SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 }; 472for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX, 473 SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY, 474 SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) { 475 SkMatrix m; 476 m.setIdentity(); 477 m.set(i, offset[i]); 478 SkAutoCanvasRestore autoRestore(canvas, true); 479 canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88); 480 canvas->drawString("&", 0, 0, font, gray); 481 canvas->concat(m); 482 canvas->drawString("&", 0, 0, font, black); 483} 484## 485 486#SeeAlso get() set() 487 488## 489 490# ------------------------------------------------------------------------------ 491 492#Subtopic AffineIndex 493#In Constant 494#Line # affine member indices ## 495#Filter KA 496 497#Code 498#Populate 499## 500 501Affine arrays are in column major order to match the matrix used by 502PDF and XPS. 503 504#Const kAScaleX 0 505#Line # horizontal scale factor ## 506## 507#Const kASkewY 1 508#Line # vertical skew factor ## 509## 510#Const kASkewX 2 511#Line # horizontal skew factor ## 512## 513#Const kAScaleY 3 514#Line # vertical scale factor ## 515## 516#Const kATransX 4 517#Line # horizontal translation ## 518## 519#Const kATransY 5 520#Line # vertical translation ## 521## 522 523#NoExample 524## 525 526#SeeAlso SetAffineIdentity asAffine setAffine 527 528## 529 530# ------------------------------------------------------------------------------ 531 532#Method SkScalar operator[](int index) const 533 534#Line # returns Matrix value ## 535#Populate 536 537#Example 538SkMatrix matrix; 539matrix.setScale(42, 24); 540SkDebugf("matrix[SkMatrix::kMScaleX] %c= 42\n", matrix[SkMatrix::kMScaleX] == 42 ? '=' : '!'); 541SkDebugf("matrix[SkMatrix::kMScaleY] %c= 24\n", matrix[SkMatrix::kMScaleY] == 24 ? '=' : '!'); 542#StdOut 543matrix[SkMatrix::kMScaleX] == 42 544matrix[SkMatrix::kMScaleY] == 24 545## 546## 547 548#SeeAlso get set 549 550## 551 552# ------------------------------------------------------------------------------ 553 554#Method SkScalar get(int index) const 555#In Property 556#Line # returns one of nine Matrix values ## 557#Populate 558 559#Example 560SkMatrix matrix; 561matrix.setSkew(42, 24); 562SkDebugf("matrix.get(SkMatrix::kMSkewX) %c= 42\n", 563 matrix.get(SkMatrix::kMSkewX) == 42 ? '=' : '!'); 564SkDebugf("matrix.get(SkMatrix::kMSkewY) %c= 24\n", 565 matrix.get(SkMatrix::kMSkewY) == 24 ? '=' : '!'); 566#StdOut 567matrix.get(SkMatrix::kMSkewX) == 42 568matrix.get(SkMatrix::kMSkewY) == 24 569## 570## 571 572#SeeAlso operator[](int index) set 573 574## 575 576# ------------------------------------------------------------------------------ 577 578#Method SkScalar getScaleX() const 579#In Property 580#Line # returns horizontal scale factor ## 581#Populate 582 583#Example 584SkMatrix matrix; 585matrix.setScale(42, 24); 586SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!'); 587#StdOut 588matrix.getScaleX() == 42 589## 590## 591 592#SeeAlso get getScaleY setScaleX setScale 593 594## 595 596# ------------------------------------------------------------------------------ 597 598#Method SkScalar getScaleY() const 599#In Property 600#Line # returns vertical scale factor ## 601#Populate 602 603#Example 604SkMatrix matrix; 605matrix.setScale(42, 24); 606SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!'); 607#StdOut 608matrix.getScaleY() == 24 609## 610## 611 612#SeeAlso get getScaleX setScaleY setScale 613 614## 615 616# ------------------------------------------------------------------------------ 617 618#Method SkScalar getSkewY() const 619#In Property 620#Line # returns vertical skew factor ## 621#Populate 622 623#Example 624SkMatrix matrix; 625matrix.setSkew(42, 24); 626SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!'); 627#StdOut 628matrix.getSkewY() == 24 629## 630## 631 632#SeeAlso get getSkewX setSkewY setSkew 633 634## 635 636# ------------------------------------------------------------------------------ 637 638#Method SkScalar getSkewX() const 639#In Property 640#Line # returns horizontal skew factor ## 641#Populate 642 643#Example 644SkMatrix matrix; 645matrix.setSkew(42, 24); 646SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!'); 647#StdOut 648matrix.getSkewX() == 42 649## 650## 651 652#SeeAlso get getSkewY setSkewX setSkew 653 654## 655 656# ------------------------------------------------------------------------------ 657 658#Method SkScalar getTranslateX() const 659#In Property 660#Line # returns horizontal translation ## 661#Populate 662 663#Example 664SkMatrix matrix; 665matrix.setTranslate(42, 24); 666SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!'); 667#StdOut 668matrix.getTranslateX() == 42 669## 670## 671 672#SeeAlso get getTranslateY setTranslateX setTranslate 673 674## 675 676# ------------------------------------------------------------------------------ 677 678#Method SkScalar getTranslateY() const 679#In Property 680#Line # returns vertical translation ## 681#Populate 682 683#Example 684SkMatrix matrix; 685matrix.setTranslate(42, 24); 686SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!'); 687#StdOut 688matrix.getTranslateY() == 24 689## 690## 691 692#SeeAlso get getTranslateX setTranslateY setTranslate 693 694## 695 696# ------------------------------------------------------------------------------ 697 698#Method SkScalar getPerspX() const 699#In Property 700#Line # returns input x perspective factor ## 701#Populate 702 703#Example 704 SkMatrix m; 705 m.setIdentity(); 706 m.set(SkMatrix::kMPersp0, -0.004f); 707 SkAutoCanvasRestore autoRestore(canvas, true); 708 canvas->translate(22, 144); 709 SkPaint black; 710 SkFont font(nullptr, 24); 711 SkPaint gray = black; 712 gray.setColor(0xFF9f9f9f); 713 SkString string; 714 string.appendScalar(m.getPerspX()); 715 canvas->drawString(string, 0, -72, font, gray); 716 canvas->concat(m); 717 canvas->drawString(string, 0, 0, font, black); 718## 719 720#SeeAlso kMPersp0 getPerspY 721 722## 723 724# ------------------------------------------------------------------------------ 725 726#Method SkScalar getPerspY() const 727#In Property 728#Line # returns input y perspective factor ## 729#Populate 730 731#Example 732 SkMatrix m; 733 m.setIdentity(); 734 m.set(SkMatrix::kMPersp1, -0.004f); 735 SkAutoCanvasRestore autoRestore(canvas, true); 736 canvas->translate(22, 144); 737 SkPaint black; 738 SkFont font(nullptr, 24); 739 SkPaint gray; 740 gray.setColor(0xFF9f9f9f); 741 SkString string; 742 string.appendScalar(m.getPerspY()); 743 canvas->drawString(string, 0, -72, font, gray); 744 canvas->concat(m); 745 canvas->drawString(string, 0, 0, font, black); 746## 747 748#SeeAlso kMPersp1 getPerspX 749 750## 751 752# ------------------------------------------------------------------------------ 753 754#Method SkScalar& operator[](int index) 755 756#Line # returns writable reference to Matrix value ## 757#Populate 758 759#Example 760SkMatrix matrix; 761matrix.setIdentity(); 762SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX); 763SkScalar& skewRef = matrix[SkMatrix::kMSkewX]; 764skewRef = 0; 765SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 766skewRef = 1; 767SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 768matrix.dirtyMatrixTypeCache(); 769SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX); 770#StdOut 771with identity matrix: x = 24 772after skew x mod: x = 24 773after 2nd skew x mod: x = 24 774after dirty cache: x = 66 775## 776## 777 778#SeeAlso get dirtyMatrixTypeCache set 779 780## 781 782# ------------------------------------------------------------------------------ 783#Subtopic Set 784#Line # sets one or more matrix values ## 785## 786 787#Method void set(int index, SkScalar value) 788#In Set 789#Line # sets one value ## 790#Populate 791 792#Example 793SkMatrix matrix; 794matrix.setIdentity(); 795SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX); 796matrix.set(SkMatrix::kMSkewX, 0); 797SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 798matrix.set(SkMatrix::kMSkewX, 1); 799SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 800#StdOut 801with identity matrix: x = 24 802after skew x mod: x = 24 803after 2nd skew x mod: x = 66 804## 805## 806 807#SeeAlso operator[] get 808 809#Method ## 810 811# ------------------------------------------------------------------------------ 812 813#Method void setScaleX(SkScalar v) 814#In Set 815#Line # sets horizontal scale factor ## 816#Populate 817 818#Example 819#Height 64 820SkPaint paint; 821SkFont font(nullptr, 24); 822canvas->drawString("normal", 12, 24, font, paint); 823SkMatrix matrix; 824matrix.setIdentity(); 825matrix.setScaleX(3); 826canvas->concat(matrix); 827canvas->drawString("x scale", 0, 48, font, paint); 828## 829 830#SeeAlso set setScale setScaleY 831 832#Method ## 833 834# ------------------------------------------------------------------------------ 835 836#Method void setScaleY(SkScalar v) 837#In Set 838#Line # sets vertical scale factor ## 839#Populate 840 841#Example 842#Height 192 843SkPaint paint; 844SkFont font(nullptr, 24); 845canvas->drawString("normal", 12, 24, font, paint); 846SkMatrix matrix; 847matrix.setIdentity(); 848matrix.setScaleY(3); 849canvas->concat(matrix); 850canvas->drawString("y scale", 12, 48, font, paint); 851## 852 853#SeeAlso set setScale setScaleX 854 855#Method ## 856 857# ------------------------------------------------------------------------------ 858 859#Method void setSkewY(SkScalar v) 860#In Set 861#Line # sets vertical skew factor ## 862#Populate 863 864#Example 865#Height 96 866SkPaint paint; 867SkFont font(nullptr, 24); 868canvas->drawString("normal", 12, 24, font, paint); 869SkMatrix matrix; 870matrix.setIdentity(); 871matrix.setSkewY(.3f); 872canvas->concat(matrix); 873canvas->drawString("y skew", 12, 48, font, paint); 874## 875 876#SeeAlso set setSkew setSkewX 877 878#Method ## 879 880# ------------------------------------------------------------------------------ 881 882#Method void setSkewX(SkScalar v) 883#In Set 884#Line # sets horizontal skew factor ## 885#Populate 886 887#Example 888#Height 64 889SkPaint paint; 890SkFont font(nullptr, 24); 891canvas->drawString("normal", 12, 24, font, paint); 892SkMatrix matrix; 893matrix.setIdentity(); 894matrix.setSkewX(-.7f); 895canvas->concat(matrix); 896canvas->drawString("x skew", 36, 48, font, paint); 897## 898 899#SeeAlso set setSkew setSkewX 900 901#Method ## 902 903# ------------------------------------------------------------------------------ 904 905#Method void setTranslateX(SkScalar v) 906#In Set 907#Line # sets horizontal translation ## 908#Populate 909 910#Example 911#Height 48 912SkPaint paint; 913SkFont font(nullptr, 24); 914canvas->drawString("normal", 8, 24, font, paint); 915SkMatrix matrix; 916matrix.setIdentity(); 917matrix.setTranslateX(96); 918canvas->concat(matrix); 919canvas->drawString("x translate", 8, 24, font, paint); 920## 921 922#SeeAlso set setTranslate setTranslateY 923 924#Method ## 925 926# ------------------------------------------------------------------------------ 927 928#Method void setTranslateY(SkScalar v) 929#In Set 930#Line # sets vertical translation ## 931#Populate 932 933#Example 934#Height 64 935SkPaint paint; 936SkFont font(nullptr, 24); 937canvas->drawString("normal", 8, 24, font, paint); 938SkMatrix matrix; 939matrix.setIdentity(); 940matrix.setTranslateY(24); 941canvas->concat(matrix); 942canvas->drawString("y translate", 8, 24, font, paint); 943## 944 945#SeeAlso set setTranslate setTranslateX 946 947#Method ## 948 949# ------------------------------------------------------------------------------ 950 951#Method void setPerspX(SkScalar v) 952#In Set 953#Line # sets input x perspective factor ## 954#Populate 955 956#Example 957#Image 4 958for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) { 959 SkMatrix matrix; 960 matrix.setIdentity(); 961 matrix.setPerspX(perspX); 962 canvas->save(); 963 canvas->concat(matrix); 964 canvas->drawBitmap(source, 0, 0); 965 canvas->restore(); 966 canvas->translate(64, 64); 967} 968## 969 970#SeeAlso getPerspX set setAll set9 MakeAll 971 972#Method ## 973 974# ------------------------------------------------------------------------------ 975 976#Method void setPerspY(SkScalar v) 977#In Set 978#Line # sets input y perspective factor ## 979#Populate 980 981#Example 982#Image 4 983for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) { 984 SkMatrix matrix; 985 matrix.setIdentity(); 986 matrix.setPerspY(perspX); 987 canvas->save(); 988 canvas->concat(matrix); 989 canvas->drawBitmap(source, 0, 0); 990 canvas->restore(); 991 canvas->translate(64, 64); 992} 993## 994 995#SeeAlso getPerspY set setAll set9 MakeAll 996 997#Method ## 998 999# ------------------------------------------------------------------------------ 1000 1001#Method void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, 1002 SkScalar skewY, SkScalar scaleY, SkScalar transY, 1003 SkScalar persp0, SkScalar persp1, SkScalar persp2) 1004#In Set 1005#Line # sets all values from parameters ## 1006#Populate 1007 1008#Example 1009#Height 128 1010 SkPaint p; 1011 SkFont font(nullptr, 64); 1012 SkMatrix m; 1013 for (SkScalar sx : { -1, 1 } ) { 1014 for (SkScalar sy : { -1, 1 } ) { 1015 SkAutoCanvasRestore autoRestore(canvas, true); 1016 m.setAll(sx, 1, 128, 0, sy, 64, 0, 0, 1); 1017 canvas->concat(m); 1018 canvas->drawString("K", 0, 0, font, p); 1019 } 1020 } 1021## 1022 1023#SeeAlso set9 MakeAll 1024 1025#Method ## 1026 1027# ------------------------------------------------------------------------------ 1028 1029#Method void get9(SkScalar buffer[9]) const 1030#In Property 1031#Line # returns all nine Matrix values ## 1032#Populate 1033 1034#Example 1035SkMatrix matrix = SkMatrix::MakeRectToRect({0, 0, 1, 1}, {3, 4, 7, 9}, 1036 SkMatrix::kFill_ScaleToFit); 1037SkScalar b[9]; 1038matrix.get9(b); 1039SkDebugf("{%g, %g, %g},\n{%g, %g, %g},\n{%g, %g, %g}\n", b[0], b[1], b[2], 1040 b[3], b[4], b[5], b[6], b[7], b[8]); 1041#StdOut 1042{4, 0, 3}, 1043{0, 5, 4}, 1044{0, 0, 1} 1045## 1046## 1047 1048#SeeAlso set9 1049 1050#Method ## 1051 1052# ------------------------------------------------------------------------------ 1053 1054#Method void set9(const SkScalar buffer[9]) 1055#In Set 1056#In Constructors 1057#Line # sets all values from Scalar array ## 1058#Populate 1059 1060#Example 1061#Image 4 1062SkMatrix m; 1063SkScalar buffer[9] = {4, 0, 3, 0, 5, 4, 0, 0, 1}; 1064m.set9(buffer); 1065canvas->concat(m); 1066canvas->drawBitmap(source, 0, 0); 1067## 1068 1069#SeeAlso setAll get9 MakeAll 1070 1071#Method ## 1072 1073# ------------------------------------------------------------------------------ 1074 1075#Method void reset() 1076#In Constructors 1077#In Set 1078#Line # sets Matrix to identity ## 1079#Populate 1080 1081#Example 1082SkMatrix m; 1083m.reset(); 1084SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false"); 1085#StdOut 1086m.isIdentity(): true 1087## 1088## 1089 1090#SeeAlso isIdentity setIdentity 1091 1092#Method ## 1093 1094# ------------------------------------------------------------------------------ 1095 1096#Method void setIdentity() 1097#In Constructors 1098#In Set 1099#Line # sets Matrix to identity ## 1100#Populate 1101 1102#Example 1103SkMatrix m; 1104m.setIdentity(); 1105SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false"); 1106#StdOut 1107m.isIdentity(): true 1108## 1109## 1110 1111#SeeAlso isIdentity reset 1112 1113#Method ## 1114 1115# ------------------------------------------------------------------------------ 1116 1117#Method void setTranslate(SkScalar dx, SkScalar dy) 1118#In Constructors 1119#In Set 1120#Line # sets to translate on x-axis and y-axis ## 1121#Populate 1122 1123#Example 1124#Height 64 1125SkPaint paint; 1126SkFont font(nullptr, 24); 1127canvas->drawString("normal", 8, 24, font, paint); 1128SkMatrix matrix; 1129matrix.setTranslate(96, 24); 1130canvas->concat(matrix); 1131canvas->drawString("translate", 8, 24, font, paint); 1132## 1133 1134#SeeAlso setTranslateX setTranslateY 1135 1136#Method ## 1137 1138# ------------------------------------------------------------------------------ 1139 1140#Method void setTranslate(const SkVector& v) 1141#Populate 1142 1143#Example 1144#Height 64 1145SkPaint paint; 1146SkFont font(nullptr, 24); 1147canvas->drawString("normal", 8, 24, font, paint); 1148SkMatrix matrix; 1149matrix.setTranslate({96, 24}); 1150canvas->concat(matrix); 1151canvas->drawString("translate", 8, 24, font, paint); 1152## 1153 1154#SeeAlso setTranslateX setTranslateY MakeTrans 1155 1156#Method ## 1157 1158# ------------------------------------------------------------------------------ 1159 1160#Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) 1161#In Constructors 1162#In Set 1163#Line # sets to scale about a point ## 1164#Populate 1165 1166#Example 1167#Height 128 1168 SkPaint p; 1169 SkFont font(nullptr, 64); 1170 SkMatrix m; 1171 for (SkScalar sx : { -1, 1 } ) { 1172 for (SkScalar sy : { -1, 1 } ) { 1173 SkAutoCanvasRestore autoRestore(canvas, true); 1174 m.setScale(sx, sy, 128, 64); 1175 canvas->concat(m); 1176 canvas->drawString("%", 128, 64, font, p); 1177 } 1178 } 1179## 1180 1181#SeeAlso setScaleX setScaleY MakeScale preScale postScale 1182 1183#Method ## 1184 1185# ------------------------------------------------------------------------------ 1186 1187#Method void setScale(SkScalar sx, SkScalar sy) 1188#Populate 1189 1190#Example 1191#Height 128 1192 SkPaint p; 1193 SkFont font(nullptr, 64); 1194 SkMatrix m; 1195 for (SkScalar sx : { -1, 1 } ) { 1196 for (SkScalar sy : { -1, 1 } ) { 1197 SkAutoCanvasRestore autoRestore(canvas, true); 1198 m.setScale(sx, sy); 1199 m.postTranslate(128, 64); 1200 canvas->concat(m); 1201 canvas->drawString("@", 0, 0, font, p); 1202 } 1203 } 1204## 1205 1206#SeeAlso setScaleX setScaleY MakeScale preScale postScale 1207 1208#Method ## 1209 1210# ------------------------------------------------------------------------------ 1211 1212#Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py) 1213#In Constructors 1214#In Set 1215#Line # sets to rotate about a point ## 1216#Populate 1217 1218#Example 1219#Height 128 1220 SkPaint paint; 1221 paint.setColor(SK_ColorGRAY); 1222 paint.setAntiAlias(true); 1223 SkRect rect = {20, 20, 100, 100}; 1224 canvas->drawRect(rect, paint); 1225 paint.setColor(SK_ColorRED); 1226 SkMatrix matrix; 1227 matrix.setRotate(25, rect.centerX(), rect.centerY()); 1228 canvas->concat(matrix); 1229 canvas->drawRect(rect, paint); 1230## 1231 1232#SeeAlso setSinCos preRotate postRotate 1233 1234#Method ## 1235 1236# ------------------------------------------------------------------------------ 1237 1238#Method void setRotate(SkScalar degrees) 1239#Populate 1240 1241#Example 1242#Height 128 1243 SkPaint paint; 1244 paint.setColor(SK_ColorGRAY); 1245 paint.setAntiAlias(true); 1246 SkRect rect = {20, 20, 100, 100}; 1247 canvas->drawRect(rect, paint); 1248 paint.setColor(SK_ColorRED); 1249 SkMatrix matrix; 1250 matrix.setRotate(25); 1251 canvas->translate(rect.centerX(), rect.centerY()); 1252 canvas->concat(matrix); 1253 canvas->translate(-rect.centerX(), -rect.centerY()); 1254 canvas->drawRect(rect, paint); 1255## 1256 1257#SeeAlso setSinCos preRotate postRotate 1258 1259#Method ## 1260 1261# ------------------------------------------------------------------------------ 1262 1263#Method void setSinCos(SkScalar sinValue, SkScalar cosValue, 1264 SkScalar px, SkScalar py) 1265#In Constructors 1266#In Set 1267#Line # sets to rotate and scale about a point ## 1268#Populate 1269 1270#Example 1271#Height 128 1272 SkPaint paint; 1273 paint.setColor(SK_ColorGRAY); 1274 paint.setAntiAlias(true); 1275 SkRect rect = {20, 20, 100, 100}; 1276 canvas->drawRect(rect, paint); 1277 paint.setColor(SK_ColorRED); 1278 SkMatrix matrix; 1279 matrix.setSinCos(.25f, .85f, rect.centerX(), rect.centerY()); 1280 canvas->concat(matrix); 1281 canvas->drawRect(rect, paint); 1282## 1283 1284#SeeAlso setRotate setScale setRSXform 1285 1286#Method ## 1287 1288# ------------------------------------------------------------------------------ 1289 1290#Method void setSinCos(SkScalar sinValue, SkScalar cosValue) 1291#Populate 1292 1293#Example 1294#Description 1295Canvas needs offset after applying Matrix to pivot about Rect center. 1296## 1297#Height 128 1298 SkPaint paint; 1299 paint.setColor(SK_ColorGRAY); 1300 paint.setAntiAlias(true); 1301 SkRect rect = {20, 20, 100, 100}; 1302 canvas->drawRect(rect, paint); 1303 paint.setColor(SK_ColorRED); 1304 SkMatrix matrix; 1305 matrix.setSinCos(.25f, .85f); 1306 matrix.postTranslate(rect.centerX(), rect.centerY()); 1307 canvas->concat(matrix); 1308 canvas->translate(-rect.centerX(), -rect.centerY()); 1309 canvas->drawRect(rect, paint); 1310## 1311 1312#SeeAlso setRotate setScale setRSXform 1313 1314#Method ## 1315 1316# ------------------------------------------------------------------------------ 1317 1318#Method SkMatrix& setRSXform(const SkRSXform& rsxForm) 1319#In Constructors 1320#In Set 1321#Line # sets to rotate, scale, and translate ## 1322#Populate 1323 1324#Example 1325#Description 1326Canvas needs offset after applying Matrix to pivot about Rect center. 1327## 1328#Height 128 1329 SkPaint paint; 1330 paint.setColor(SK_ColorGRAY); 1331 paint.setAntiAlias(true); 1332 SkRect rect = {20, 20, 100, 100}; 1333 canvas->drawRect(rect, paint); 1334 paint.setColor(SK_ColorRED); 1335 SkMatrix matrix; 1336 matrix.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY())); 1337 canvas->concat(matrix); 1338 canvas->translate(-rect.centerX(), -rect.centerY()); 1339 canvas->drawRect(rect, paint); 1340## 1341 1342#SeeAlso setSinCos setScale setTranslate 1343 1344#Method ## 1345 1346# ------------------------------------------------------------------------------ 1347 1348#Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) 1349#In Constructors 1350#In Set 1351#Line # sets to skew about a point ## 1352#Populate 1353 1354#Example 1355 SkPaint p; 1356 SkFont font(nullptr, 48); 1357 SkMatrix m; 1358 for (SkScalar sx : { -1, 0, 1 } ) { 1359 for (SkScalar sy : { -1, 0, 1 } ) { 1360 SkAutoCanvasRestore autoRestore(canvas, true); 1361 m.setSkew(sx, sy, 96 + 64 * sx, 128 + 48 * sy); 1362 canvas->concat(m); 1363 canvas->drawString("K", 96 + 64 * sx, 128 + 48 * sy, font, p); 1364 } 1365 } 1366## 1367 1368#SeeAlso setSkewX setSkewY preSkew postSkew 1369 1370#Method ## 1371 1372# ------------------------------------------------------------------------------ 1373 1374#Method void setSkew(SkScalar kx, SkScalar ky) 1375#Populate 1376 1377#Example 1378 SkPaint p; 1379 SkFont font(nullptr, 48); 1380 SkMatrix m; 1381 for (SkScalar sx : { -1, 0, 1 } ) { 1382 for (SkScalar sy : { -1, 0, 1 } ) { 1383 SkAutoCanvasRestore autoRestore(canvas, true); 1384 m.setSkew(sx, sy); 1385 m.postTranslate(96 + 64 * sx, 128 + 48 * sy); 1386 canvas->concat(m); 1387 canvas->drawString("K", 0, 0, font, p); 1388 } 1389 } 1390## 1391 1392#SeeAlso setSkewX setSkewY preSkew postSkew 1393 1394#Method ## 1395 1396# ------------------------------------------------------------------------------ 1397 1398#Method void setConcat(const SkMatrix& a, const SkMatrix& b) 1399#In Constructors 1400#In Set 1401#Line # sets to Matrix parameter multiplied by Matrix parameter ## 1402#Populate 1403 1404#Example 1405#Image 3 1406#Description 1407setPolyToPoly creates perspective matrices, one the inverse of the other. 1408Multiplying the matrix by its inverse turns into an identity matrix. 1409## 1410SkMatrix matrix, matrix2; 1411SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1412SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1413matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1414matrix2.setPolyToPoly(perspect, bitmapBounds, 4); 1415matrix.setConcat(matrix, matrix2); 1416canvas->concat(matrix); 1417canvas->drawBitmap(source, 0, 0); 1418## 1419 1420#SeeAlso Concat preConcat postConcat SkCanvas::concat 1421 1422#Method ## 1423 1424# ------------------------------------------------------------------------------ 1425 1426#Method void preTranslate(SkScalar dx, SkScalar dy) 1427#In Set 1428#In Operators 1429#Line # pre-multiplies Matrix by translation ## 1430#Populate 1431 1432#Example 1433#Height 160 1434 SkPaint paint; 1435 paint.setAntiAlias(true); 1436 SkRect rect = {20, 20, 100, 100}; 1437 for (int i = 0; i < 2; ++i ) { 1438 SkMatrix matrix; 1439 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320); 1440 { 1441 SkAutoCanvasRestore acr(canvas, true); 1442 canvas->concat(matrix); 1443 paint.setColor(SK_ColorGRAY); 1444 canvas->drawRect(rect, paint); 1445 } 1446 paint.setColor(SK_ColorRED); 1447 for (int j = 0; j < 2; ++j ) { 1448 SkAutoCanvasRestore acr(canvas, true); 1449 matrix.preTranslate(40, 40); 1450 canvas->concat(matrix); 1451 canvas->drawCircle(0, 0, 3, paint); 1452 } 1453 } 1454## 1455 1456#SeeAlso postTranslate setTranslate MakeTrans 1457 1458#Method ## 1459 1460# ------------------------------------------------------------------------------ 1461 1462#Method void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) 1463#In Set 1464#In Operators 1465#Line # pre-multiplies Matrix by scale ## 1466#Populate 1467 1468#Example 1469#Image 3 1470SkMatrix matrix; 1471SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1472SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1473matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1474matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2); 1475canvas->concat(matrix); 1476canvas->drawBitmap(source, 0, 0); 1477## 1478 1479#SeeAlso postScale setScale MakeScale 1480 1481#Method ## 1482 1483# ------------------------------------------------------------------------------ 1484 1485#Method void preScale(SkScalar sx, SkScalar sy) 1486#In Set 1487#In Operators 1488#Populate 1489 1490#Example 1491#Image 3 1492SkMatrix matrix; 1493SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1494SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1495matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1496matrix.preScale(.75f, 1.5f); 1497canvas->concat(matrix); 1498canvas->drawBitmap(source, 0, 0); 1499## 1500 1501#SeeAlso postScale setScale MakeScale 1502 1503#Method ## 1504 1505# ------------------------------------------------------------------------------ 1506 1507#Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py) 1508#In Set 1509#In Operators 1510#Line # pre-multiplies Matrix by rotation ## 1511#Populate 1512 1513#Example 1514#Image 3 1515SkMatrix matrix; 1516SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1517SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1518matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1519matrix.preRotate(45, source.width() / 2, source.height() / 2); 1520canvas->concat(matrix); 1521canvas->drawBitmap(source, 0, 0); 1522## 1523 1524#SeeAlso postRotate setRotate 1525 1526#Method ## 1527 1528# ------------------------------------------------------------------------------ 1529 1530#Method void preRotate(SkScalar degrees) 1531#Populate 1532 1533#Example 1534#Image 3 1535SkMatrix matrix; 1536SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1537SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1538matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1539matrix.preRotate(45); 1540canvas->concat(matrix); 1541canvas->drawBitmap(source, 0, 0); 1542## 1543 1544#SeeAlso postRotate setRotate 1545 1546#Method ## 1547 1548# ------------------------------------------------------------------------------ 1549 1550#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) 1551#In Set 1552#In Operators 1553#Line # pre-multiplies Matrix by skew ## 1554#Populate 1555 1556#Example 1557#Image 3 1558SkMatrix matrix; 1559SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1560SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1561matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1562matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2); 1563canvas->concat(matrix); 1564canvas->drawBitmap(source, 0, 0); 1565## 1566 1567#SeeAlso postSkew setSkew 1568 1569#Method ## 1570 1571# ------------------------------------------------------------------------------ 1572 1573#Method void preSkew(SkScalar kx, SkScalar ky) 1574#Populate 1575 1576#Example 1577#Image 3 1578SkMatrix matrix; 1579SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1580SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1581matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1582matrix.preSkew(.5f, 0); 1583canvas->concat(matrix); 1584canvas->drawBitmap(source, 0, 0); 1585## 1586 1587#SeeAlso postSkew setSkew 1588 1589#Method ## 1590 1591# ------------------------------------------------------------------------------ 1592 1593#Method void preConcat(const SkMatrix& other) 1594#In Set 1595#In Operators 1596#Line # pre-multiplies Matrix by Matrix parameter ## 1597#Populate 1598 1599#Example 1600#Image 3 1601#Description 1602setPolyToPoly creates perspective matrices, one the inverse of the other. 1603Multiplying the matrix by its inverse turns into an identity matrix. 1604## 1605SkMatrix matrix, matrix2; 1606SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1607SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1608matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1609matrix2.setPolyToPoly(perspect, bitmapBounds, 4); 1610matrix.preConcat(matrix2); 1611canvas->concat(matrix); 1612canvas->drawBitmap(source, 0, 0); 1613## 1614 1615#SeeAlso postConcat setConcat Concat 1616 1617#Method ## 1618 1619# ------------------------------------------------------------------------------ 1620 1621#Method void postTranslate(SkScalar dx, SkScalar dy) 1622#In Set 1623#In Operators 1624#Line # post-multiplies Matrix by translation ## 1625#Populate 1626 1627#Example 1628#Height 160 1629#Description 1630Compare with preTranslate example. 1631## 1632 SkPaint paint; 1633 paint.setAntiAlias(true); 1634 SkRect rect = {20, 20, 100, 100}; 1635 for (int i = 0; i < 2; ++i ) { 1636 SkMatrix matrix; 1637 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320); 1638 { 1639 SkAutoCanvasRestore acr(canvas, true); 1640 canvas->concat(matrix); 1641 paint.setColor(SK_ColorGRAY); 1642 canvas->drawRect(rect, paint); 1643 } 1644 paint.setColor(SK_ColorRED); 1645 for (int j = 0; j < 2; ++j ) { 1646 SkAutoCanvasRestore acr(canvas, true); 1647 matrix.postTranslate(40, 40); 1648 canvas->concat(matrix); 1649 canvas->drawCircle(0, 0, 3, paint); 1650 } 1651 } 1652## 1653 1654#SeeAlso preTranslate setTranslate MakeTrans 1655 1656#Method ## 1657 1658# ------------------------------------------------------------------------------ 1659 1660#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) 1661#In Set 1662#In Operators 1663#Line # post-multiplies Matrix by scale ## 1664#Populate 1665 1666#Example 1667#Image 3 1668SkMatrix matrix; 1669SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1670SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1671matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1672matrix.postScale(.75f, 1.5f, source.width() / 2, source.height() / 2); 1673canvas->concat(matrix); 1674canvas->drawBitmap(source, 0, 0); 1675## 1676 1677#SeeAlso preScale setScale MakeScale 1678 1679## 1680 1681# ------------------------------------------------------------------------------ 1682 1683#Method void postScale(SkScalar sx, SkScalar sy) 1684#Populate 1685 1686#Example 1687#Image 3 1688SkMatrix matrix; 1689SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1690SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1691matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1692matrix.postScale(.75f, 1.5f); 1693canvas->concat(matrix); 1694canvas->drawBitmap(source, 0, 0); 1695## 1696 1697#SeeAlso preScale setScale MakeScale 1698 1699## 1700 1701# ------------------------------------------------------------------------------ 1702 1703#Method bool postIDiv(int divx, int divy) 1704#In Set 1705#In Operators 1706#Line # post-multiplies Matrix by inverse scale ## 1707Sets Matrix to Matrix constructed from scaling by (1/divx, 1/divy), 1708multiplied by Matrix. 1709 1710Returns false if either divx or divy is zero. 1711 1712Given: 1713 1714#Code 1715#Literal 1716 | J K L | | sx 0 0 | 1717Matrix = | M N O |, I(divx, divy) = | 0 sy 0 | 1718 | P Q R | | 0 0 1 | 1719## 1720 1721where 1722 1723#Code 1724#Literal 1725sx = 1 / divx 1726sy = 1 / divy 1727## 1728 1729sets Matrix to: 1730 1731#Code 1732#Literal 1733 | sx 0 0 | | J K L | | sx*J sx*K sx*L | 1734I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | 1735 | 0 0 1 | | P Q R | | P Q R | 1736## 1737 1738#Param divx integer divisor for inverse scale on x-axis ## 1739#Param divy integer divisor for inverse scale on y-axis ## 1740 1741#Return true on successful scale ## 1742 1743#Example 1744#Image 3 1745SkMatrix matrix; 1746SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1747SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1748matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1749matrix.postIDiv(1, 2); 1750canvas->concat(matrix); 1751canvas->drawBitmap(source, 0, 0); 1752## 1753 1754#SeeAlso postScale MakeScale 1755 1756## 1757 1758# ------------------------------------------------------------------------------ 1759 1760#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py) 1761#In Set 1762#In Operators 1763#Line # post-multiplies Matrix by rotation ## 1764#Populate 1765 1766#Example 1767#Image 3 1768SkMatrix matrix; 1769SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1770SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1771matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1772matrix.postRotate(45, source.width() / 2, source.height() / 2); 1773canvas->concat(matrix); 1774canvas->drawBitmap(source, 0, 0); 1775## 1776 1777#SeeAlso preRotate setRotate 1778 1779## 1780 1781# ------------------------------------------------------------------------------ 1782 1783#Method void postRotate(SkScalar degrees) 1784#Populate 1785 1786#Example 1787#Image 3 1788SkMatrix matrix; 1789SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1790SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1791matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1792matrix.postRotate(45); 1793canvas->concat(matrix); 1794canvas->drawBitmap(source, 0, 0); 1795## 1796 1797#SeeAlso preRotate setRotate 1798 1799## 1800 1801# ------------------------------------------------------------------------------ 1802 1803#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) 1804#In Set 1805#In Operators 1806#Line # post-multiplies Matrix by skew ## 1807#Populate 1808 1809#Example 1810#Image 3 1811SkMatrix matrix; 1812SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1813SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1814matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1815matrix.postSkew(.5f, 0, source.width() / 2, source.height() / 2); 1816canvas->concat(matrix); 1817canvas->drawBitmap(source, 0, 0); 1818## 1819 1820#SeeAlso preSkew setSkew 1821 1822## 1823 1824# ------------------------------------------------------------------------------ 1825 1826#Method void postSkew(SkScalar kx, SkScalar ky) 1827#Populate 1828 1829#Example 1830#Image 3 1831SkMatrix matrix; 1832SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1833SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1834matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1835matrix.postSkew(.5f, 0); 1836canvas->concat(matrix); 1837canvas->drawBitmap(source, 0, 0); 1838## 1839 1840#SeeAlso preSkew setSkew 1841 1842## 1843 1844# ------------------------------------------------------------------------------ 1845 1846#Method void postConcat(const SkMatrix& other) 1847#In Set 1848#In Operators 1849#Line # post-multiplies Matrix by Matrix parameter ## 1850#Populate 1851 1852#Example 1853#Image 3 1854#Height 64 1855SkMatrix matrix; 1856SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1857SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1858matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1859matrix.postConcat(matrix); 1860canvas->concat(matrix); 1861canvas->drawBitmap(source, 0, 0); 1862## 1863 1864#SeeAlso preConcat setConcat Concat 1865 1866## 1867 1868# ------------------------------------------------------------------------------ 1869 1870#Enum ScaleToFit 1871#Line # options to map Rects ## 1872#Code 1873 enum ScaleToFit { 1874 kFill_ScaleToFit, 1875 kStart_ScaleToFit, 1876 kCenter_ScaleToFit, 1877 kEnd_ScaleToFit, 1878 }; 1879## 1880 1881ScaleToFit describes how Matrix is constructed to map one Rect to another. 1882ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling, 1883or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies 1884how Matrix maps to the side or center of the destination Rect. 1885 1886#Const kFill_ScaleToFit 0 1887#Line # scales about x-axis and y-axis to fill destination Rect ## 1888 Computes Matrix that scales about x-axis and y-axis independently, so that 1889 source Rect is mapped to completely fill destination Rect. The aspect ratio 1890 of source Rect may change. 1891## 1892#Const kStart_ScaleToFit 1 1893#Line # scales and aligns to left and top ## 1894 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect 1895 width or height to destination Rect. Aligns mapping to left and top edges 1896 of destination Rect. 1897## 1898#Const kCenter_ScaleToFit 2 1899#Line # scales and aligns to center ## 1900 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect 1901 width or height to destination Rect. Aligns mapping to center of destination 1902 Rect. 1903## 1904#Const kEnd_ScaleToFit 3 1905#Line # scales and aligns to right and bottom ## 1906 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect 1907 width or height to destination Rect. Aligns mapping to right and bottom 1908 edges of destination Rect. 1909## 1910 1911#Example 1912 const char* labels[] = { "Fill", "Start", "Center", "End" }; 1913 SkRect rects[] = {{5, 5, 59, 59}, {5, 74, 59, 108}, {10, 123, 44, 172}, {10, 187, 54, 231}}; 1914 SkRect bounds; 1915 source.getBounds(&bounds); 1916 SkPaint paint; 1917 paint.setAntiAlias(true); 1918 for (auto fit : { SkMatrix::kFill_ScaleToFit, SkMatrix::kStart_ScaleToFit, 1919 SkMatrix::kCenter_ScaleToFit, SkMatrix::kEnd_ScaleToFit } ) { 1920 for (auto rect : rects ) { 1921 canvas->drawRect(rect, paint); 1922 SkMatrix matrix; 1923 if (!matrix.setRectToRect(bounds, rect, fit)) { 1924 continue; 1925 } 1926 SkAutoCanvasRestore acr(canvas, true); 1927 canvas->concat(matrix); 1928 canvas->drawBitmap(source, 0, 0); 1929 } 1930 canvas->drawString(labels[fit], 10, 255, paint); 1931 canvas->translate(64, 0); 1932 } 1933## 1934 1935#SeeAlso setRectToRect MakeRectToRect setPolyToPoly 1936 1937## 1938 1939# ------------------------------------------------------------------------------ 1940 1941#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) 1942#In Set 1943#Line # sets to map one Rect to another ## 1944#Populate 1945 1946#Example 1947 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} }; 1948 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} }; 1949 for (auto src : srcs) { 1950 for (auto dst : dsts) { 1951 SkMatrix matrix; 1952 matrix.setAll(-1, -1, -1, -1, -1, -1, -1, -1, -1); 1953 bool success = matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); 1954 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g success: %s\n", 1955 src.fLeft, src.fTop, src.fRight, src.fBottom, 1956 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, success ? "true" : "false"); 1957 matrix.dump(); 1958 } 1959 } 1960#StdOut 1961src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false 1962[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 1963src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false 1964[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 1965src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true 1966[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 1967src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true 1968[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000] 1969## 1970## 1971 1972#SeeAlso MakeRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty 1973 1974## 1975 1976# ------------------------------------------------------------------------------ 1977 1978#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) 1979#In Constructors 1980#Line # constructs from source Rect to destination Rect ## 1981#Populate 1982 1983#Example 1984 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} }; 1985 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} }; 1986 for (auto src : srcs) { 1987 for (auto dst : dsts) { 1988 SkMatrix matrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); 1989 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g\n", 1990 src.fLeft, src.fTop, src.fRight, src.fBottom, 1991 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom); 1992 matrix.dump(); 1993 } 1994 } 1995#StdOut 1996src: 0, 0, 0, 0 dst: 0, 0, 0, 0 1997[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 1998src: 0, 0, 0, 0 dst: 5, 6, 8, 9 1999[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 2000src: 1, 2, 3, 4 dst: 0, 0, 0, 0 2001[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 2002src: 1, 2, 3, 4 dst: 5, 6, 8, 9 2003[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000] 2004## 2005## 2006 2007#SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty 2008 2009## 2010 2011# ------------------------------------------------------------------------------ 2012 2013#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count) 2014#In Set 2015#Line # sets to map one to four points to an equal array of points ## 2016#Populate 2017 2018#Example 2019 const SkPoint src[] = { { 0, 0}, {30, 0}, {30, -30}, { 0, -30} }; 2020 const SkPoint dst[] = { {50, 0}, {80, -10}, {90, -30}, {60, -40} }; 2021 SkPaint blackPaint; 2022 blackPaint.setAntiAlias(true); 2023 SkFont font(nullptr, 42); 2024 SkPaint redPaint = blackPaint; 2025 redPaint.setColor(SK_ColorRED); 2026 for (int count : { 1, 2, 3, 4 } ) { 2027 canvas->translate(35, 55); 2028 for (int index = 0; index < count; ++index) { 2029 canvas->drawCircle(src[index], 3, blackPaint); 2030 canvas->drawCircle(dst[index], 3, blackPaint); 2031 if (index > 0) { 2032 canvas->drawLine(src[index], src[index - 1], font, blackPaint); 2033 canvas->drawLine(dst[index], dst[index - 1], font, blackPaint); 2034 } 2035 } 2036 SkMatrix matrix; 2037 matrix.setPolyToPoly(src, dst, count); 2038 canvas->drawString("A", src[0].fX, src[0].fY, font, redPaint); 2039 SkAutoCanvasRestore acr(canvas, true); 2040 canvas->concat(matrix); 2041 canvas->drawString("A", src[0].fX, src[0].fY, font, redPaint); 2042 } 2043## 2044 2045#SeeAlso setRectToRect MakeRectToRect 2046 2047## 2048 2049# ------------------------------------------------------------------------------ 2050 2051#Method bool invert(SkMatrix* inverse) const 2052#In Operators 2053#Line # returns inverse, if possible ## 2054#Populate 2055 2056#Example 2057#Height 128 2058 const SkPoint src[] = { { 10, 120}, {120, 120}, {120, 10}, { 10, 10} }; 2059 const SkPoint dst[] = { {150, 120}, {200, 100}, {240, 30}, { 130, 40} }; 2060 SkPaint paint; 2061 paint.setAntiAlias(true); 2062 SkMatrix matrix; 2063 matrix.setPolyToPoly(src, dst, 4); 2064 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, src, paint); 2065 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, dst, paint); 2066 paint.setColor(SK_ColorBLUE); 2067 paint.setStrokeWidth(3); 2068 paint.setStrokeCap(SkPaint::kRound_Cap); 2069 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint); 2070 if (matrix.invert(&matrix)) { 2071 canvas->concat(matrix); 2072 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint); 2073 } 2074## 2075 2076#SeeAlso Concat 2077 2078## 2079 2080# ------------------------------------------------------------------------------ 2081 2082#Method static void SetAffineIdentity(SkScalar affine[6]) 2083#In Constructors 2084#Line # sets 3x2 array to identity ## 2085#Populate 2086 2087#Example 2088 SkScalar affine[6]; 2089 SkMatrix::SetAffineIdentity(affine); 2090 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" }; 2091 for (int i = 0; i < 6; ++i) { 2092 SkDebugf("%s: %g ", names[i], affine[i]); 2093 } 2094 SkDebugf("\n"); 2095#StdOut 2096ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0 2097## 2098## 2099 2100#SeeAlso setAffine asAffine 2101 2102## 2103 2104# ------------------------------------------------------------------------------ 2105 2106#Method bool asAffine(SkScalar affine[6]) const 2107#In Constructors 2108#Line # copies to 3x2 array ## 2109#Populate 2110 2111#Example 2112SkMatrix matrix; 2113matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1); 2114SkScalar affine[6]; 2115if (matrix.asAffine(affine)) { 2116 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" }; 2117 for (int i = 0; i < 6; ++i) { 2118 SkDebugf("%s: %g ", names[i], affine[i]); 2119 } 2120 SkDebugf("\n"); 2121} 2122#StdOut 2123ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7 2124## 2125## 2126 2127#SeeAlso setAffine SetAffineIdentity 2128 2129## 2130 2131# ------------------------------------------------------------------------------ 2132 2133#Method void setAffine(const SkScalar affine[6]) 2134#In Constructors 2135#In Set 2136#Line # sets left two columns ## 2137#Populate 2138 2139#Example 2140SkMatrix matrix; 2141matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1); 2142SkScalar affine[6]; 2143if (matrix.asAffine(affine)) { 2144 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" }; 2145 for (int i = 0; i < 6; ++i) { 2146 SkDebugf("%s: %g ", names[i], affine[i]); 2147 } 2148 SkDebugf("\n"); 2149 matrix.reset(); 2150 matrix.setAffine(affine); 2151 matrix.dump(); 2152} 2153#StdOut 2154ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7 2155[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000] 2156## 2157## 2158 2159#SeeAlso asAffine SetAffineIdentity 2160 2161## 2162 2163# ------------------------------------------------------------------------------ 2164#Subtopic Transform 2165#Line # map points with Matrix ## 2166## 2167 2168#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const 2169#In Transform 2170#Line # maps Point array ## 2171#Populate 2172 2173#Example 2174 SkMatrix matrix; 2175 matrix.reset(); 2176 const int count = 4; 2177 SkPoint src[count]; 2178 matrix.mapRectToQuad(src, {40, 70, 180, 220} ); 2179 SkPaint paint; 2180 paint.setARGB(77, 23, 99, 154); 2181 for (int i = 0; i < 5; ++i) { 2182 SkPoint dst[count]; 2183 matrix.mapPoints(dst, src, count); 2184 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, dst, paint); 2185 matrix.preRotate(35, 128, 128); 2186 } 2187## 2188 2189#SeeAlso mapXY mapHomogeneousPoints mapVectors 2190 2191## 2192 2193# ------------------------------------------------------------------------------ 2194 2195#Method void mapPoints(SkPoint pts[], int count) const 2196#Populate 2197 2198#Example 2199 SkMatrix matrix; 2200 matrix.setRotate(35, 128, 128); 2201 const int count = 4; 2202 SkPoint pts[count]; 2203 matrix.mapRectToQuad(pts, {40, 70, 180, 220} ); 2204 SkPaint paint; 2205 paint.setARGB(77, 23, 99, 154); 2206 for (int i = 0; i < 5; ++i) { 2207 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, pts, paint); 2208 matrix.mapPoints(pts, count); 2209 } 2210## 2211 2212#SeeAlso mapXY mapHomogeneousPoints mapVectors 2213 2214## 2215 2216# ------------------------------------------------------------------------------ 2217 2218#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const 2219#In Transform 2220#Line # maps Point3 array ## 2221#Populate 2222 2223#Example 2224 SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3}, 2225 {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}}; 2226 int lines[] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 }; 2227 constexpr int count = SK_ARRAY_COUNT(src); 2228 auto debugster = [=](SkPoint3 src[]) -> void { 2229 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) { 2230 const SkPoint3& s = src[lines[i]]; 2231 const SkPoint3& e = src[lines[i + 1]]; 2232 SkPaint paint; 2233 paint.setARGB(77, 23, 99, 154); 2234 canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint); 2235 } 2236 }; 2237 canvas->save(); 2238 canvas->translate(5, 5); 2239 canvas->scale(15, 15); 2240 debugster(src); 2241 canvas->restore(); 2242 canvas->translate(128, 128); 2243 SkMatrix matrix; 2244 matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1); 2245 matrix.mapHomogeneousPoints(src, src, count); 2246 debugster(src); 2247## 2248 2249#SeeAlso mapPoints mapXY mapVectors 2250 2251## 2252 2253# ------------------------------------------------------------------------------ 2254 2255#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const 2256#In Transform 2257#Line # maps Point ## 2258#Populate 2259 2260#Example 2261 SkPaint paint; 2262 paint.setAntiAlias(true); 2263 SkMatrix matrix; 2264 matrix.setRotate(60, 128, 128); 2265 SkPoint lines[] = {{50, 50}, {150, 50}, {150, 150}}; 2266 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); ++i) { 2267 SkPoint pt; 2268 matrix.mapXY(lines[i].fX, lines[i].fY, &pt); 2269 canvas->drawCircle(pt.fX, pt.fY, 3, paint); 2270 } 2271 canvas->concat(matrix); 2272 canvas->drawPoints(SkCanvas::kPolygon_PointMode, SK_ARRAY_COUNT(lines), lines, paint); 2273## 2274 2275#SeeAlso mapPoints mapVectors 2276 2277## 2278 2279# ------------------------------------------------------------------------------ 2280 2281#Method SkPoint mapXY(SkScalar x, SkScalar y) const 2282#Populate 2283 2284#Example 2285#Image 4 2286SkMatrix matrix; 2287SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {30, 206}}; 2288SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2289matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2290SkPaint paint; 2291paint.setAntiAlias(true); 2292paint.setStrokeWidth(3); 2293for (int x : { 0, source.width() } ) { 2294 for (int y : { 0, source.height() } ) { 2295 canvas->drawPoint(matrix.mapXY(x, y), paint); 2296 } 2297} 2298canvas->concat(matrix); 2299canvas->drawBitmap(source, 0, 0); 2300## 2301 2302#SeeAlso mapPoints mapVectors 2303 2304## 2305 2306# ------------------------------------------------------------------------------ 2307 2308#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const 2309#In Transform 2310#Line # maps Vector array ## 2311#Populate 2312 2313#Example 2314 SkPaint paint; 2315 paint.setAntiAlias(true); 2316 paint.setStyle(SkPaint::kStroke_Style); 2317 SkMatrix matrix; 2318 matrix.reset(); 2319 const SkVector radii[] = {{8, 4}, {9, 1}, {6, 2}, {7, 3}}; 2320 for (int i = 0; i < 4; ++i) { 2321 SkVector rScaled[4]; 2322 matrix.preScale(1.5f, 2.f); 2323 matrix.mapVectors(rScaled, radii, SK_ARRAY_COUNT(radii)); 2324 SkRRect rrect; 2325 rrect.setRectRadii({20, 20, 180, 70}, rScaled); 2326 canvas->drawRRect(rrect, paint); 2327 canvas->translate(0, 60); 2328 } 2329## 2330 2331#SeeAlso mapVector mapPoints mapXY 2332 2333## 2334 2335# ------------------------------------------------------------------------------ 2336 2337#Method void mapVectors(SkVector vecs[], int count) const 2338#Populate 2339 2340#Example 2341 SkPaint paint; 2342 paint.setAntiAlias(true); 2343 paint.setStyle(SkPaint::kStroke_Style); 2344 SkMatrix matrix; 2345 matrix.setScale(2, 3); 2346 SkVector radii[] = {{7, 7}, {3, 3}, {2, 2}, {4, 0}}; 2347 for (int i = 0; i < 4; ++i) { 2348 SkRRect rrect; 2349 rrect.setRectRadii({20, 20, 180, 70}, radii); 2350 canvas->drawRRect(rrect, paint); 2351 canvas->translate(0, 60); 2352 matrix.mapVectors(radii, SK_ARRAY_COUNT(radii)); 2353 } 2354## 2355 2356#SeeAlso mapVector mapPoints mapXY 2357 2358## 2359 2360# ------------------------------------------------------------------------------ 2361 2362#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const 2363#In Transform 2364#Line # maps Vector ## 2365#Populate 2366 2367#Example 2368 SkPaint paint; 2369 paint.setColor(SK_ColorGREEN); 2370 SkFont font(nullptr, 48); 2371 SkMatrix matrix; 2372 matrix.setRotate(90); 2373 SkVector offset = { 7, 7 }; 2374 for (int i = 0; i < 4; ++i) { 2375 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3, 2376 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr)); 2377 matrix.mapVector(offset.fX, offset.fY, &offset); 2378 canvas->translate(0, 60); 2379 canvas->drawString("Text", 50, 0, font, paint); 2380 } 2381## 2382 2383#SeeAlso mapVectors mapPoints mapXY 2384 2385## 2386 2387# ------------------------------------------------------------------------------ 2388 2389#Method SkVector mapVector(SkScalar dx, SkScalar dy) const 2390#Populate 2391 2392#Example 2393 SkPaint paint; 2394 paint.setColor(SK_ColorGREEN); 2395 SkFont font(nullptr, 48); 2396 SkMatrix matrix; 2397 matrix.setRotate(90); 2398 SkVector offset = { 7, 7 }; 2399 for (int i = 0; i < 4; ++i) { 2400 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3, 2401 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr)); 2402 offset = matrix.mapVector(offset.fX, offset.fY); 2403 canvas->translate(0, 60); 2404 canvas->drawString("Text", 50, 0, font, paint); 2405 } 2406## 2407 2408#SeeAlso mapVectors mapPoints mapXY 2409 2410## 2411 2412# ------------------------------------------------------------------------------ 2413 2414#Method bool mapRect(SkRect* dst, const SkRect& src) const 2415#In Transform 2416#Line # returns bounds of mapped Rect ## 2417#Populate 2418 2419#Example 2420 SkPaint paint; 2421 paint.setAntiAlias(true); 2422 SkMatrix matrix; 2423 matrix.setRotate(45, 128, 128); 2424 SkRect rotatedBounds, bounds = {40, 50, 190, 200}; 2425 matrix.mapRect(&rotatedBounds, bounds ); 2426 paint.setColor(SK_ColorGRAY); 2427 canvas->drawRect(rotatedBounds, paint); 2428 canvas->concat(matrix); 2429 paint.setColor(SK_ColorRED); 2430 canvas->drawRect(bounds, paint); 2431## 2432 2433#SeeAlso mapPoints rectStaysRect 2434 2435## 2436 2437# ------------------------------------------------------------------------------ 2438 2439#Method bool mapRect(SkRect* rect) const 2440#Populate 2441 2442#Example 2443 SkPaint paint; 2444 paint.setAntiAlias(true); 2445 SkMatrix matrix; 2446 matrix.setRotate(45, 128, 128); 2447 SkRect bounds = {40, 50, 190, 200}; 2448 matrix.mapRect(&bounds); 2449 paint.setColor(SK_ColorGRAY); 2450 canvas->drawRect(bounds, paint); 2451 canvas->concat(matrix); 2452 paint.setColor(SK_ColorRED); 2453 canvas->drawRect({40, 50, 190, 200}, paint); 2454## 2455 2456#SeeAlso mapRectScaleTranslate mapPoints rectStaysRect 2457 2458## 2459 2460# ------------------------------------------------------------------------------ 2461 2462#Method SkRect mapRect(const SkRect& src) const 2463#Populate 2464 2465#Example 2466 SkRect rect{110, 50, 180, 100}; 2467 SkMatrix matrix; 2468 matrix.setRotate(50, 28, 28); 2469 SkRect mapped = matrix.mapRect(rect); 2470 SkPaint paint; 2471 paint.setAntiAlias(true); 2472 paint.setStyle(SkPaint::kStroke_Style); 2473 canvas->drawRect(rect, paint); 2474 canvas->drawRect(mapped, paint); 2475 canvas->concat(matrix); 2476 canvas->drawRect(rect, paint); 2477## 2478 2479#SeeAlso mapRectToQuad mapRectScaleTranslate 2480#Method ## 2481 2482# ------------------------------------------------------------------------------ 2483 2484#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const 2485#In Transform 2486#Line # maps Rect to Point array ## 2487#Populate 2488 2489#Example 2490#Height 192 2491 SkPaint paint; 2492 paint.setAntiAlias(true); 2493 SkMatrix matrix; 2494 matrix.setRotate(60, 128, 128); 2495 SkRect rect = {50, 50, 150, 150}; 2496 SkPoint pts[4]; 2497 matrix.mapRectToQuad(pts, rect); 2498 for (int i = 0; i < 4; ++i) { 2499 canvas->drawCircle(pts[i].fX, pts[i].fY, 3, paint); 2500 } 2501 canvas->concat(matrix); 2502 paint.setStyle(SkPaint::kStroke_Style); 2503 canvas->drawRect(rect, paint); 2504## 2505 2506#SeeAlso mapRect mapRectScaleTranslate 2507 2508## 2509 2510# ------------------------------------------------------------------------------ 2511 2512#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const 2513#In Transform 2514#Line # returns bounds of mapped Rect ## 2515#Populate 2516 2517#Example 2518 SkPaint paint; 2519 SkMatrix matrix; 2520 SkRect rect = {100, 50, 150, 180}; 2521 matrix.setScale(2, .5f, rect.centerX(), rect.centerY()); 2522 SkRect rotated; 2523 matrix.mapRectScaleTranslate(&rotated, rect); 2524 paint.setStyle(SkPaint::kStroke_Style); 2525 canvas->drawRect(rect, paint); 2526 paint.setColor(SK_ColorRED); 2527 canvas->drawRect(rotated, paint); 2528## 2529 2530#SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect 2531 2532## 2533 2534# ------------------------------------------------------------------------------ 2535 2536#Method SkScalar mapRadius(SkScalar radius) const 2537#In Transform 2538#Line # returns mean radius of mapped Circle ## 2539#Populate 2540 2541#Example 2542#Description 2543The area enclosed by a square with sides equal to mappedRadius is the same as 2544the area enclosed by the ellipse major and minor axes. 2545## 2546 SkPaint paint; 2547 paint.setAntiAlias(true); 2548 SkMatrix matrix; 2549 const SkPoint center = {108, 93}; 2550 matrix.setScale(2, .5f, center.fX, center.fY); 2551 matrix.postRotate(45, center.fX, center.fY); 2552 const SkScalar circleRadius = 50; 2553 SkScalar mappedRadius = matrix.mapRadius(circleRadius); 2554 SkVector minorAxis, majorAxis; 2555 matrix.mapVector(0, circleRadius, &minorAxis); 2556 matrix.mapVector(circleRadius, 0, &majorAxis); 2557 SkString mappedArea; 2558 mappedArea.printf("area = %g", mappedRadius * mappedRadius); 2559 canvas->drawString(mappedArea, 145, 250, paint); 2560 canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint); 2561 paint.setColor(SK_ColorRED); 2562 SkString axArea; 2563 axArea.printf("area = %g", majorAxis.length() * minorAxis.length()); 2564 paint.setStyle(SkPaint::kFill_Style); 2565 canvas->drawString(axArea, 15, 250, paint); 2566 paint.setStyle(SkPaint::kStroke_Style); 2567 canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint); 2568 paint.setColor(SK_ColorBLACK); 2569 canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint); 2570 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint); 2571 canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint); 2572 canvas->concat(matrix); 2573 canvas->drawCircle(center.fX, center.fY, circleRadius, paint); 2574 paint.setColor(SK_ColorRED); 2575 canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint); 2576 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint); 2577## 2578 2579#SeeAlso mapVector 2580 2581## 2582 2583# ------------------------------------------------------------------------------ 2584#Method bool isFixedStepInX() const 2585#In Property 2586#Line # returns if transformation supports fixed step on x-axis ## 2587#Populate 2588 2589#Example 2590 SkMatrix matrix; 2591 for (SkScalar px : { 0.0f, 0.1f } ) { 2592 for (SkScalar py : { 0.0f, 0.1f } ) { 2593 for (SkScalar sy : { 1, 2 } ) { 2594 matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1); 2595 matrix.dump(); 2596 SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false"); 2597 } 2598 } 2599 } 2600#StdOut 2601[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 2602isFixedStepInX: true 2603[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000] 2604isFixedStepInX: true 2605[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000] 2606isFixedStepInX: true 2607[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000] 2608isFixedStepInX: true 2609[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000] 2610isFixedStepInX: false 2611[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000] 2612isFixedStepInX: false 2613[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000] 2614isFixedStepInX: false 2615[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000] 2616isFixedStepInX: false 2617## 2618## 2619 2620#SeeAlso fixedStepInX getType 2621 2622## 2623 2624# ------------------------------------------------------------------------------ 2625 2626#Method SkVector fixedStepInX(SkScalar y) const 2627#In Property 2628#Line # returns step on x-axis for a position on y-axis ## 2629#Populate 2630 2631#Example 2632#Image 3 2633 SkMatrix matrix; 2634 const SkPoint center = { 128, 128 }; 2635 matrix.setScale(20, 25, center.fX, center.fY); 2636 matrix.postRotate(75, center.fX, center.fY); 2637 { 2638 SkAutoCanvasRestore acr(canvas, true); 2639 canvas->concat(matrix); 2640 canvas->drawBitmap(source, 0, 0); 2641 } 2642 if (matrix.isFixedStepInX()) { 2643 SkPaint paint; 2644 paint.setAntiAlias(true); 2645 SkVector step = matrix.fixedStepInX(128); 2646 SkVector end = center + step; 2647 canvas->drawLine(center, end, paint); 2648 SkVector arrow = { step.fX + step.fY, step.fY - step.fX}; 2649 arrow = arrow * .25f; 2650 canvas->drawLine(end, end - arrow, paint); 2651 canvas->drawLine(end, {end.fX + arrow.fY, end.fY - arrow.fX}, paint); 2652 } 2653## 2654 2655#SeeAlso isFixedStepInX getType 2656 2657## 2658 2659# ------------------------------------------------------------------------------ 2660 2661#Method bool cheapEqualTo(const SkMatrix& m) const 2662#In Operators 2663#Line # compares Matrix pair using memcmp() ## 2664#Populate 2665 2666#Example 2667 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void { 2668 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix, 2669 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false"); 2670 }; 2671 SkMatrix a, b; 2672 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 2673 b.setIdentity(); 2674 debugster("identity", a, b); 2675 a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1); 2676 debugster("neg zero", a, b); 2677 a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1); 2678 debugster(" one NaN", a, b); 2679 b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1); 2680 debugster("both NaN", a, b); 2681#StdOut 2682identity: a == b a.cheapEqualTo(b): true 2683neg zero: a == b a.cheapEqualTo(b): false 2684 one NaN: a != b a.cheapEqualTo(b): false 2685both NaN: a != b a.cheapEqualTo(b): true 2686## 2687## 2688 2689#SeeAlso operator==(const SkMatrix& a, const SkMatrix& b) 2690 2691## 2692 2693# ------------------------------------------------------------------------------ 2694 2695#Method bool operator==(const SkMatrix& a, const SkMatrix& b) 2696 2697#Line # returns true if members are equal ## 2698#Populate 2699 2700#Example 2701 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void { 2702 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix, 2703 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false"); 2704 }; 2705 SkMatrix a, b; 2706 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 2707 b.setScale(2, 4); 2708 b.postScale(0.5f, 0.25f); 2709 debugster("identity", a, b); 2710#StdOut 2711identity: a == b a.cheapEqualTo(b): true 2712## 2713## 2714 2715#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b) 2716 2717## 2718 2719# ------------------------------------------------------------------------------ 2720 2721#Method bool operator!=(const SkMatrix& a, const SkMatrix& b) 2722 2723#Line # returns true if members are unequal ## 2724#Populate 2725 2726#Example 2727 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void { 2728 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix, 2729 a != b ? '!' : '=', a.cheapEqualTo(b) ? "true" : "false"); 2730 }; 2731 SkMatrix a, b; 2732 a.setAll(1, 0, 0, 0, 1, 0, 1, 0, 1); 2733 if (a.invert(&b)) { 2734 debugster("identity", a, b); 2735 } 2736## 2737 2738#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b) 2739 2740## 2741 2742# ------------------------------------------------------------------------------ 2743#Subtopic Utility 2744#Line # rarely called management functions ## 2745## 2746 2747#Method void dump() const 2748#In Utility 2749#Line # sends text representation using floats to standard output ## 2750#Populate 2751 2752#Example 2753 SkMatrix matrix; 2754 matrix.setRotate(45); 2755 matrix.dump(); 2756 SkMatrix nearlyEqual; 2757 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1); 2758 nearlyEqual.dump(); 2759 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!'); 2760#StdOut 2761[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000] 2762[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000] 2763matrix != nearlyEqual 2764## 2765## 2766 2767#SeeAlso SkPath::dump 2768 2769## 2770 2771# ------------------------------------------------------------------------------ 2772 2773#Method SkScalar getMinScale() const 2774#In Property 2775#Line # returns minimum scaling, if possible ## 2776#Populate 2777 2778#Example 2779 SkMatrix matrix; 2780 matrix.setScale(42, 24); 2781 SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale()); 2782#StdOut 2783matrix.getMinScale() 24 2784## 2785## 2786 2787#SeeAlso getMaxScale getMinMaxScales 2788 2789## 2790 2791# ------------------------------------------------------------------------------ 2792 2793#Method SkScalar getMaxScale() const 2794#In Property 2795#Line # returns maximum scaling, if possible ## 2796#Populate 2797 2798#Example 2799 SkMatrix matrix; 2800 matrix.setScale(42, 24); 2801 SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale()); 2802#StdOut 2803matrix.getMaxScale() 42 2804## 2805## 2806 2807#SeeAlso getMinScale getMinMaxScales 2808 2809## 2810 2811# ------------------------------------------------------------------------------ 2812 2813#Method bool getMinMaxScales(SkScalar scaleFactors[2]) const 2814#In Property 2815#Line # returns minimum and maximum scaling, if possible ## 2816#Populate 2817 2818#Example 2819 SkMatrix matrix; 2820 matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0); 2821 if (matrix.invert(&matrix)) { 2822 SkScalar factor[2] = {2, 2}; 2823 bool result = matrix.getMinMaxScales(factor); 2824 SkDebugf("matrix.getMinMaxScales() %s %g %g\n", 2825 result ? "true" : "false", factor[0], factor[1]); 2826 } 2827#StdOut 2828matrix.getMinMaxScales() false 2 2 2829## 2830## 2831 2832#SeeAlso getMinScale getMaxScale 2833 2834## 2835 2836# ------------------------------------------------------------------------------ 2837 2838#Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const 2839#In Property 2840#Line # separates scale if possible ## 2841Decomposes Matrix into scale components and whatever remains. Returns false if 2842Matrix could not be decomposed. 2843 2844Sets scale to portion of Matrix that scale axes. Sets remaining to Matrix 2845with scaling factored out. remaining may be passed as nullptr 2846to determine if Matrix can be decomposed without computing remainder. 2847 2848Returns true if scale components are found. scale and remaining are 2849unchanged if Matrix contains perspective; scale factors are not finite, or 2850are nearly zero. 2851 2852On success: #Formula # Matrix = scale * Remaining ##. 2853 2854#Param scale axes scaling factors; may be nullptr ## 2855#Param remaining Matrix without scaling; may be nullptr ## 2856 2857#Return true if scale can be computed ## 2858 2859#Example 2860 SkMatrix matrix; 2861 matrix.setRotate(90 * SK_Scalar1); 2862 matrix.postScale(1.f / 4, 1.f / 2); 2863 matrix.dump(); 2864 SkSize scale = {SK_ScalarNaN, SK_ScalarNaN}; 2865 SkMatrix remaining; 2866 remaining.reset(); 2867 bool success = matrix.decomposeScale(&scale, &remaining); 2868 SkDebugf("success: %s ", success ? "true" : "false"); 2869 SkDebugf("scale: %g, %g\n", scale.width(), scale.height()); 2870 remaining.dump(); 2871 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height()); 2872 SkMatrix combined = SkMatrix::Concat(scaleMatrix, remaining); 2873 combined.dump(); 2874#StdOut 2875[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 2876success: true scale: 0.5, 0.25 2877[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 2878[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 2879## 2880## 2881 2882#SeeAlso setScale MakeScale 2883 2884## 2885 2886# ------------------------------------------------------------------------------ 2887 2888#Method static const SkMatrix& I() 2889#In Constructors 2890#Line # returns a reference to a const identity Matrix ## 2891#Populate 2892 2893#Example 2894 SkMatrix m1, m2, m3; 2895 m1.reset(); 2896 m2.setIdentity(); 2897 m3 = SkMatrix::I(); 2898 SkDebugf("m1 %c= m2\n", m1 == m2 ? '=' : '!'); 2899 SkDebugf("m2 %c= m3\n", m1 == m2 ? '=' : '!'); 2900#StdOut 2901m1 == m2 2902m2 == m3 2903## 2904## 2905 2906#SeeAlso reset() setIdentity 2907 2908## 2909 2910# ------------------------------------------------------------------------------ 2911 2912#Method static const SkMatrix& InvalidMatrix() 2913#In Constructors 2914#Line # returns a reference to a const invalid Matrix ## 2915#Populate 2916 2917#Example 2918 SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX()); 2919#StdOut 2920scaleX 3.40282e+38 2921## 2922## 2923 2924#SeeAlso getType 2925 2926## 2927 2928# ------------------------------------------------------------------------------ 2929 2930#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) 2931#In Operators 2932#Line # returns the concatenation of Matrix pair ## 2933#Populate 2934 2935#Example 2936#Height 64 2937#Image 4 2938#Description 2939setPolyToPoly creates perspective matrices, one the inverse of the other. 2940Multiplying the matrix by its inverse turns into an identity matrix. 2941## 2942SkMatrix matrix, matrix2; 2943SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2944SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2945matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2946matrix2.setPolyToPoly(perspect, bitmapBounds, 4); 2947SkMatrix concat = SkMatrix::Concat(matrix, matrix2); 2948canvas->concat(concat); 2949canvas->drawBitmap(source, 0, 0); 2950## 2951 2952#SeeAlso preConcat postConcat 2953 2954## 2955 2956# ------------------------------------------------------------------------------ 2957 2958#Method void dirtyMatrixTypeCache() 2959#In Utility 2960#Line # sets internal cache to unknown state ## 2961#Populate 2962 2963#Example 2964SkMatrix matrix; 2965matrix.setIdentity(); 2966SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX); 2967SkScalar& skewRef = matrix[SkMatrix::kMSkewX]; 2968skewRef = 0; 2969SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 2970skewRef = 1; 2971SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 2972matrix.dirtyMatrixTypeCache(); 2973SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX); 2974#StdOut 2975with identity matrix: x = 24 2976after skew x mod: x = 24 2977after 2nd skew x mod: x = 24 2978after dirty cache: x = 66 2979## 2980## 2981 2982#SeeAlso operator[](int index) getType 2983 2984## 2985 2986# ------------------------------------------------------------------------------ 2987 2988#Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) 2989#In Constructors 2990#In Set 2991#Line # sets to scale and translate ## 2992#Populate 2993 2994#Example 2995SkMatrix matrix; 2996matrix.setScaleTranslate(1, 2, 3, 4); 2997matrix.dump(); 2998#StdOut 2999[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000] 3000## 3001## 3002 3003#SeeAlso setScale preTranslate postTranslate 3004 3005## 3006 3007# ------------------------------------------------------------------------------ 3008 3009#Method bool isFinite() const 3010#In Property 3011#Line # returns if all Matrix values are not infinity, NaN ## 3012#Populate 3013 3014#Example 3015SkMatrix matrix = SkMatrix::MakeTrans(SK_ScalarNaN, 0); 3016matrix.dump(); 3017SkDebugf("matrix is finite: %s\n", matrix.isFinite() ? "true" : "false"); 3018SkDebugf("matrix %c= matrix\n", matrix == matrix ? '=' : '!'); 3019#StdOut 3020[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 3021matrix is finite: false 3022matrix != matrix 3023## 3024## 3025 3026#SeeAlso operator== 3027 3028## 3029 3030#Class SkMatrix ## 3031 3032#Topic Matrix ## 3033