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