1#Topic Matrix 2#Alias Matrices 3#Alias Matrix_Reference 4 5#Subtopic Overview 6 #Subtopic Subtopics 7 #Populate 8 ## 9## 10 11#Class SkMatrix 12 13Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping 14Points and Vectors with translation, scaling, skewing, rotation, and 15perspective. 16 17Matrix elements are in row major order. Matrix does not have a constructor, 18so it must be explicitly initialized. setIdentity initializes Matrix 19so it has no effect. setTranslate, setScale, setSkew, setRotate, set9 and setAll 20initializes all Matrix elements with the corresponding mapping. 21 22Matrix includes a hidden variable that classifies the type of matrix to 23improve performance. Matrix is not thread safe unless getType is called first. 24 25#Subtopic Constructors 26#Populate 27## 28 29#Subtopic Operators 30#Populate 31## 32 33#Subtopic Member_Functions 34#Populate 35## 36 37# ------------------------------------------------------------------------------ 38 39#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) 40 41#Line # constructs from scale in x and y ## 42Sets Matrix to scale by (sx, sy). Returned matrix is: 43 44#Code 45#Literal 46| sx 0 0 | 47| 0 sy 0 | 48| 0 0 1 | 49## 50 51#Param sx horizontal scale factor ## 52#Param sy vertical scale factor ## 53 54#Return Matrix with scale ## 55 56#Example 57#Image 4 58canvas->concat(SkMatrix::MakeScale(4, 3)); 59canvas->drawBitmap(source, 0, 0); 60## 61 62#SeeAlso setScale postScale preScale 63 64## 65 66# ------------------------------------------------------------------------------ 67 68#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) 69 70Sets Matrix to scale by (scale, scale). Returned matrix is: 71 72#Code 73#Literal 74| scale 0 0 | 75| 0 scale 0 | 76| 0 0 1 | 77## 78 79#Param scale horizontal and vertical scale factor ## 80 81#Return Matrix with scale ## 82 83#Example 84#Image 4 85canvas->concat(SkMatrix::MakeScale(4)); 86canvas->drawBitmap(source, 0, 0); 87## 88 89#SeeAlso setScale postScale preScale 90 91## 92 93# ------------------------------------------------------------------------------ 94 95#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) 96 97#Line # constructs from translate in x and y ## 98Sets Matrix to translate by (dx, dy). Returned matrix is: 99 100#Code 101#Literal 102| 1 0 dx | 103| 0 1 dy | 104| 0 0 1 | 105## 106 107#Param dx horizontal translation ## 108#Param dy vertical translation ## 109 110#Return Matrix with translation ## 111 112#Example 113#Image 4 114SkMatrix matrix = SkMatrix::MakeTrans(64, 48); 115for (int i = 0; i < 4; ++i) { 116 canvas->drawBitmap(source, 0, 0); 117 canvas->concat(matrix); 118} 119## 120 121#SeeAlso setTranslate postTranslate preTranslate 122 123## 124 125# ------------------------------------------------------------------------------ 126 127#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, 128 SkScalar skewY, SkScalar scaleY, SkScalar transY, 129 SkScalar pers0, SkScalar pers1, SkScalar pers2) 130#Line # constructs all nine values ## 131 132 133Sets Matrix to: 134 135#Code 136#Literal 137| scaleX skewX transX | 138| skewY scaleY transY | 139| pers0 pers1 pers2 | 140## 141 142#Param scaleX horizontal scale factor ## 143#Param skewX horizontal skew factor ## 144#Param transX horizontal translation ## 145#Param skewY vertical skew factor ## 146#Param scaleY vertical scale factor ## 147#Param transY vertical translation ## 148#Param pers0 input x perspective factor ## 149#Param pers1 input y perspective factor ## 150#Param pers2 perspective scale factor ## 151 152#Return Matrix constructed from parameters ## 153 154#Example 155 SkPaint p; 156 p.setAntiAlias(true); 157 p.setTextSize(64); 158 for (SkScalar sx : { -1, 1 } ) { 159 for (SkScalar sy : { -1, 1 } ) { 160 SkAutoCanvasRestore autoRestore(canvas, true); 161 SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1); 162 canvas->concat(m); 163 canvas->drawString("K", 0, 0, p); 164 } 165 } 166## 167 168#SeeAlso setAll set9 postConcat preConcat 169 170## 171 172 173# ------------------------------------------------------------------------------ 174 175#Enum TypeMask 176 177#Code 178 enum TypeMask { 179 kIdentity_Mask = 0, 180 kTranslate_Mask = 0x01, 181 kScale_Mask = 0x02, 182 kAffine_Mask = 0x04, 183 kPerspective_Mask = 0x08, 184 }; 185## 186 187Enum of bit fields for mask returned by getType. 188Used to identify the complexity of Matrix, to optimize performance. 189 190#Const kIdentity_Mask 0 191all bits clear if Matrix is identity 192## 193#Const kTranslate_Mask 1 194set if Matrix has translation 195## 196#Const kScale_Mask 2 197set if Matrix has x or y scale 198## 199#Const kAffine_Mask 4 200set if Matrix skews or rotates 201## 202#Const kPerspective_Mask 8 203set if Matrix has perspective 204## 205 206#Example 207 auto debugster = [](const char* prefix, const SkMatrix& matrix) -> void { 208 SkString typeMask; 209 typeMask += SkMatrix::kIdentity_Mask == matrix.getType() ? "kIdentity_Mask " : ""; 210 typeMask += SkMatrix::kTranslate_Mask & matrix.getType() ? "kTranslate_Mask " : ""; 211 typeMask += SkMatrix::kScale_Mask & matrix.getType() ? "kScale_Mask " : ""; 212 typeMask += SkMatrix::kAffine_Mask & matrix.getType() ? "kAffine_Mask " : ""; 213 typeMask += SkMatrix::kPerspective_Mask & matrix.getType() ? "kPerspective_Mask" : ""; 214 SkDebugf("after %s: %s\n", prefix, typeMask.c_str()); 215 }; 216SkMatrix matrix; 217matrix.reset(); 218debugster("reset", matrix); 219matrix.postTranslate(1, 0); 220debugster("postTranslate", matrix); 221matrix.postScale(2, 1); 222debugster("postScale", matrix); 223matrix.postRotate(45); 224debugster("postScale", matrix); 225SkPoint polys[][4] = {{{0, 0}, {0, 1}, {1, 1}, {1, 0}}, {{0, 0}, {0, 1}, {2, 1}, {1, 0}}}; 226matrix.setPolyToPoly(polys[0], polys[1], 4); 227debugster("setPolyToPoly", matrix); 228#StdOut 229after reset: kIdentity_Mask 230after postTranslate: kTranslate_Mask 231after postScale: kTranslate_Mask kScale_Mask 232after postScale: kTranslate_Mask kScale_Mask kAffine_Mask 233after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask 234## 235## 236 237#SeeAlso getType 238 239## 240 241# ------------------------------------------------------------------------------ 242 243#Method TypeMask getType() const 244 245#Line # returns transform complexity ## 246Returns a bit field describing the transformations the matrix may 247perform. The bit field is computed conservatively, so it may include 248false positives. For example, when kPerspective_Mask is set, all 249other bits are set. 250 251#Return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask, 252 kAffine_Mask, kPerspective_Mask 253## 254 255#Example 256SkMatrix matrix; 257matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 258SkDebugf("identity flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType()); 259matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, .5f); 260SkDebugf("set all flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType()); 261#StdOut 262identity flags hex: 0 decimal: 0 263set all flags hex: f decimal: 15 264## 265## 266 267#SeeAlso TypeMask 268 269## 270 271# ------------------------------------------------------------------------------ 272 273#Method bool isIdentity() const 274 275#Line # returns if matrix equals the identity Matrix ## 276Returns true if Matrix is identity. Identity matrix is: 277 278#Code 279#Literal 280| 1 0 0 | 281| 0 1 0 | 282| 0 0 1 | 283## 284 285#Return true if Matrix has no effect ## 286 287#Example 288SkMatrix matrix; 289matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 290SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false"); 291matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 2); 292SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false"); 293#StdOut 294is identity: true 295is identity: false 296## 297## 298 299#SeeAlso reset() setIdentity getType 300 301## 302 303# ------------------------------------------------------------------------------ 304 305#Method bool isScaleTranslate() const 306 307#Line # returns if transform is limited to scale and translate ## 308Returns true if Matrix at most scales and translates. Matrix may be identity, 309contain only scale elements, only translate elements, or both. Matrix form is: 310 311#Code 312#Literal 313| scale-x 0 translate-x | 314| 0 scale-y translate-y | 315| 0 0 1 | 316## 317 318#Return true if Matrix is identity; or scales, translates, or both ## 319 320#Example 321SkMatrix matrix; 322for (SkScalar scaleX : { 1, 2 } ) { 323 for (SkScalar translateX : { 0, 20 } ) { 324 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1); 325 SkDebugf("is scale-translate: %s\n", matrix.isScaleTranslate() ? "true" : "false"); 326 } 327} 328#StdOut 329is scale-translate: true 330is scale-translate: true 331is scale-translate: true 332is scale-translate: true 333## 334## 335 336#SeeAlso setScale isTranslate setTranslate getType 337 338## 339 340# ------------------------------------------------------------------------------ 341 342#Method bool isTranslate() const 343 344#Line # returns if transform is limited to translate ## 345Returns true if Matrix is identity, or translates. Matrix form is: 346 347#Code 348#Literal 349| 1 0 translate-x | 350| 0 1 translate-y | 351| 0 0 1 | 352## 353 354#Return true if Matrix is identity, or translates ## 355 356#Example 357SkMatrix matrix; 358for (SkScalar scaleX : { 1, 2 } ) { 359 for (SkScalar translateX : { 0, 20 } ) { 360 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1); 361 SkDebugf("is translate: %s\n", matrix.isTranslate() ? "true" : "false"); 362 } 363} 364#StdOut 365is translate: true 366is translate: true 367is translate: false 368is translate: false 369## 370## 371 372#SeeAlso setTranslate getType 373 374## 375 376# ------------------------------------------------------------------------------ 377 378#Method bool rectStaysRect() const 379 380#Line # returns if mapped Rect can be represented by another Rect ## 381Returns true Matrix maps Rect to another Rect. If true, Matrix is identity, 382or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all 383cases, Matrix may also have translation. Matrix form is either: 384 385#Code 386#Literal 387| scale-x 0 translate-x | 388| 0 scale-y translate-y | 389| 0 0 1 | 390## 391 392or 393 394#Code 395#Literal 396| 0 rotate-x translate-x | 397| rotate-y 0 translate-y | 398| 0 0 1 | 399## 400 401for non-zero values of scale-x, scale-y, rotate-x, and rotate-y. 402 403Also called preservesAxisAlignment; use the one that provides better inline 404documentation. 405 406#Return true if Matrix maps one Rect into another ## 407 408#Example 409SkMatrix matrix; 410for (SkScalar angle: { 0, 90, 180, 270 } ) { 411 matrix.setRotate(angle); 412 SkDebugf("rectStaysRect: %s\n", matrix.rectStaysRect() ? "true" : "false"); 413} 414#StdOut 415rectStaysRect: true 416rectStaysRect: true 417rectStaysRect: true 418rectStaysRect: true 419## 420## 421 422#SeeAlso preservesAxisAlignment preservesRightAngles 423 424## 425 426# ------------------------------------------------------------------------------ 427 428#Method bool preservesAxisAlignment() const 429 430#Line # returns if mapping restricts to 90 degree multiples and mirroring ## 431 432Returns true Matrix maps Rect to another Rect. If true, Matrix is identity, 433or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all 434cases, Matrix may also have translation. Matrix form is either: 435 436#Code 437#Literal 438| scale-x 0 translate-x | 439| 0 scale-y translate-y | 440| 0 0 1 | 441## 442 443or 444 445#Code 446#Literal 447| 0 rotate-x translate-x | 448| rotate-y 0 translate-y | 449| 0 0 1 | 450## 451 452for non-zero values of scale-x, scale-y, rotate-x, and rotate-y. 453 454Also called rectStaysRect; use the one that provides better inline 455documentation. 456 457#Return true if Matrix maps one Rect into another ## 458 459#Example 460SkMatrix matrix; 461for (SkScalar angle: { 0, 90, 180, 270 } ) { 462 matrix.setRotate(angle); 463 SkDebugf("preservesAxisAlignment: %s\n", matrix.preservesAxisAlignment() ? "true" : "false"); 464} 465#StdOut 466preservesAxisAlignment: true 467preservesAxisAlignment: true 468preservesAxisAlignment: true 469preservesAxisAlignment: true 470## 471## 472 473#SeeAlso rectStaysRect preservesRightAngles 474 475## 476 477# ------------------------------------------------------------------------------ 478 479#Method bool hasPerspective() const 480 481#Line # returns if transform includes perspective ## 482Returns true if the matrix contains perspective elements. Matrix form is: 483 484#Code 485#Literal 486| -- -- -- | 487| -- -- -- | 488| perspective-x perspective-y perspective-scale | 489## 490 491where perspective-x or perspective-y is non-zero, or perspective-scale is 492not one. All other elements may have any value. 493 494#Return true if Matrix is in most general form ## 495 496#Example 497#Image 4 498SkMatrix matrix; 499SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 500SkRect::Make(source.bounds()).toQuad(bitmapBounds); 501matrix.setPolyToPoly(bitmapBounds, perspect, 4); 502canvas->concat(matrix); 503SkString string; 504string.printf("hasPerspective %s", matrix.hasPerspective() ? "true" : "false"); 505canvas->drawBitmap(source, 0, 0); 506SkPaint paint; 507paint.setAntiAlias(true); 508paint.setTextSize(48); 509canvas->drawString(string, 0, source.bounds().height() + 48, paint); 510## 511 512#SeeAlso setAll set9 MakeAll 513 514## 515 516# ------------------------------------------------------------------------------ 517 518#Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const 519 520#Line # returns if transform is limited to square scale and rotation ## 521Returns true if Matrix contains only translation, rotation, reflection, and 522uniform scale. 523Returns false if Matrix contains different scales, skewing, perspective, or 524degenerate forms that collapse to a line or point. 525 526Describes that the Matrix makes rendering with and without the matrix are 527visually alike; a transformed circle remains a circle. Mathematically, this is 528referred to as similarity of a Euclidean_Space, or a similarity transformation. 529 530Preserves right angles, keeping the arms of the angle equal lengths. 531 532#Param tol to be deprecated ## 533 534#Return true if Matrix only rotates, uniformly scales, translates ## 535 536#Example 537#Description 538String is drawn four times through but only two are visible. Drawing the pair 539with isSimilarity false reveals the pair not visible through the matrix. 540## 541 SkPaint p; 542 p.setAntiAlias(true); 543 SkMatrix m; 544 int below = 175; 545 for (SkScalar sx : { -1, 1 } ) { 546 for (SkScalar sy : { -1, 1 } ) { 547 m.setAll(sx, 1, 128, 1, sy, 32, 0, 0, 1); 548 bool isSimilarity = m.isSimilarity(); 549 SkString str; 550 str.printf("sx: %g sy: %g sim: %s", sx, sy, isSimilarity ? "true" : "false"); 551 { 552 SkAutoCanvasRestore autoRestore(canvas, true); 553 canvas->concat(m); 554 canvas->drawString(str, 0, 0, p); 555 } 556 if (!isSimilarity) { 557 canvas->drawString(str, 40, below, p); 558 below += 20; 559 } 560 } 561 } 562## 563 564#SeeAlso isScaleTranslate preservesRightAngles rectStaysRect isFixedStepInX 565 566## 567 568# ------------------------------------------------------------------------------ 569 570#Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const 571 572#Line # returns if mapped 90 angle remains 90 degrees ## 573Returns true if Matrix contains only translation, rotation, reflection, and 574scale. Scale may differ along rotated axes. 575Returns false if Matrix skewing, perspective, or degenerate forms that collapse 576to a line or point. 577 578Preserves right angles, but not requiring that the arms of the angle 579retain equal lengths. 580 581#Param tol to be deprecated ## 582 583#Return true if Matrix only rotates, scales, translates ## 584 585#Example 586#Height 128 587#Description 588Equal scale is both similar and preserves right angles. 589Unequal scale is not similar but preserves right angles. 590Skews are not similar and do not preserve right angles. 591## 592SkPaint p; 593p.setAntiAlias(true); 594SkMatrix m; 595int pos = 0; 596for (SkScalar sx : { 1, 2 } ) { 597 for (SkScalar kx : { 0, 1 } ) { 598 m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1); 599 bool isSimilarity = m.isSimilarity(); 600 bool preservesRightAngles = m.preservesRightAngles(); 601 SkString str; 602 str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "", 603 preservesRightAngles ? "right" : ""); 604 SkAutoCanvasRestore autoRestore(canvas, true); 605 canvas->concat(m); 606 canvas->drawString(str, 0, pos, p); 607 pos += 20; 608 } 609} 610## 611 612#SeeAlso isScaleTranslate isSimilarity rectStaysRect isFixedStepInX 613 614## 615 616# ------------------------------------------------------------------------------ 617 618#Enum 619 620#Code 621 enum { 622 kMScaleX, 623 kMSkewX, 624 kMTransX, 625 kMSkewY, 626 kMScaleY, 627 kMTransY, 628 kMPersp0, 629 kMPersp1, 630 kMPersp2, 631 }; 632## 633 634Matrix organizes its values in row order. These members correspond to 635each value in Matrix. 636 637#Const kMScaleX 0 638horizontal scale factor 639## 640#Const kMSkewX 1 641horizontal skew factor 642## 643#Const kMTransX 2 644horizontal translation 645## 646#Const kMSkewY 3 647vertical skew factor 648## 649#Const kMScaleY 4 650vertical scale factor 651## 652#Const kMTransY 5 653vertical translation 654## 655#Const kMPersp0 6 656input x perspective factor 657## 658#Const kMPersp1 7 659input y perspective factor 660## 661#Const kMPersp2 8 662perspective bias 663## 664 665#Example 666SkPaint black; 667black.setAntiAlias(true); 668black.setTextSize(48); 669SkPaint gray = black; 670gray.setColor(0xFF9f9f9f); 671SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 }; 672for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX, 673 SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY, 674 SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) { 675 SkMatrix m; 676 m.setIdentity(); 677 m.set(i, offset[i]); 678 SkAutoCanvasRestore autoRestore(canvas, true); 679 canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88); 680 canvas->drawString("&", 0, 0, gray); 681 canvas->concat(m); 682 canvas->drawString("&", 0, 0, black); 683} 684## 685 686#SeeAlso get() set() 687 688## 689 690# ------------------------------------------------------------------------------ 691 692#Enum 693 694#Code 695 enum { 696 kAScaleX, 697 kASkewY, 698 kASkewX, 699 kAScaleY, 700 kATransX, 701 kATransY, 702 }; 703## 704 705Affine arrays are in column major order to match the matrix used by 706PDF and XPS. 707 708#Const kAScaleX 0 709horizontal scale factor 710## 711#Const kASkewY 1 712vertical skew factor 713## 714#Const kASkewX 2 715horizontal skew factor 716## 717#Const kAScaleY 3 718vertical scale factor 719## 720#Const kATransX 4 721horizontal translation 722## 723#Const kATransY 5 724vertical translation 725## 726 727#NoExample 728## 729 730#SeeAlso SetAffineIdentity asAffine setAffine 731 732## 733 734# ------------------------------------------------------------------------------ 735 736#Method SkScalar operator[](int index)_const 737 738#Line # returns Matrix value ## 739Returns one matrix value. Asserts if index is out of range and SK_DEBUG is 740defined. 741 742#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 743 kMPersp0, kMPersp1, kMPersp2 744## 745 746#Return value corresponding to index ## 747 748#Example 749SkMatrix matrix; 750matrix.setScale(42, 24); 751SkDebugf("matrix[SkMatrix::kMScaleX] %c= 42\n", matrix[SkMatrix::kMScaleX] == 42 ? '=' : '!'); 752SkDebugf("matrix[SkMatrix::kMScaleY] %c= 24\n", matrix[SkMatrix::kMScaleY] == 24 ? '=' : '!'); 753#StdOut 754matrix[SkMatrix::kMScaleX] == 42 755matrix[SkMatrix::kMScaleY] == 24 756## 757## 758 759#SeeAlso get set 760 761## 762 763# ------------------------------------------------------------------------------ 764 765#Method SkScalar get(int index) const 766 767#Line # returns one of nine Matrix values ## 768Returns one matrix value. Asserts if index is out of range and SK_DEBUG is 769defined. 770 771#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 772 kMPersp0, kMPersp1, kMPersp2 773## 774 775#Return value corresponding to index ## 776 777#Example 778SkMatrix matrix; 779matrix.setSkew(42, 24); 780SkDebugf("matrix.get(SkMatrix::kMSkewX) %c= 42\n", 781 matrix.get(SkMatrix::kMSkewX) == 42 ? '=' : '!'); 782SkDebugf("matrix.get(SkMatrix::kMSkewY) %c= 24\n", 783 matrix.get(SkMatrix::kMSkewY) == 24 ? '=' : '!'); 784#StdOut 785matrix.get(SkMatrix::kMSkewX) == 42 786matrix.get(SkMatrix::kMSkewY) == 24 787## 788## 789 790#SeeAlso operator[](int index) set 791 792## 793 794# ------------------------------------------------------------------------------ 795 796#Method SkScalar getScaleX() const 797 798#Line # returns horizontal scale factor ## 799Returns scale factor multiplied by x input, contributing to x output. 800With mapPoints, scales Points along the x-axis. 801 802#Return horizontal scale factor ## 803 804#Example 805SkMatrix matrix; 806matrix.setScale(42, 24); 807SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!'); 808#StdOut 809matrix.getScaleX() == 42 810## 811## 812 813#SeeAlso get getScaleY setScaleX setScale 814 815## 816 817# ------------------------------------------------------------------------------ 818 819#Method SkScalar getScaleY() const 820 821#Line # returns vertical scale factor ## 822Returns scale factor multiplied by y input, contributing to y output. 823With mapPoints, scales Points along the y-axis. 824 825#Return vertical scale factor ## 826 827#Example 828SkMatrix matrix; 829matrix.setScale(42, 24); 830SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!'); 831#StdOut 832matrix.getScaleY() == 24 833## 834## 835 836#SeeAlso get getScaleX setScaleY setScale 837 838## 839 840# ------------------------------------------------------------------------------ 841 842#Method SkScalar getSkewY() const 843 844#Line # returns vertical skew factor ## 845Returns scale factor multiplied by x input, contributing to y output. 846With mapPoints, skews Points along the y-axis. 847Skew x and y together can rotate Points. 848 849#Return vertical skew factor ## 850 851#Example 852SkMatrix matrix; 853matrix.setSkew(42, 24); 854SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!'); 855#StdOut 856matrix.getSkewY() == 24 857## 858## 859 860#SeeAlso get getSkewX setSkewY setSkew 861 862## 863 864# ------------------------------------------------------------------------------ 865 866#Method SkScalar getSkewX() const 867 868#Line # returns horizontal skew factor ## 869Returns scale factor multiplied by y input, contributing to x output. 870With mapPoints, skews Points along the x-axis. 871Skew x and y together can rotate Points. 872 873#Return horizontal scale factor ## 874 875#Example 876SkMatrix matrix; 877matrix.setSkew(42, 24); 878SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!'); 879#StdOut 880matrix.getSkewX() == 42 881## 882## 883 884#SeeAlso get getSkewY setSkewX setSkew 885 886## 887 888# ------------------------------------------------------------------------------ 889 890#Method SkScalar getTranslateX() const 891 892#Line # returns horizontal translation ## 893Returns translation contributing to x output. 894With mapPoints, moves Points along the x-axis. 895 896#Return horizontal translation factor ## 897 898#Example 899SkMatrix matrix; 900matrix.setTranslate(42, 24); 901SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!'); 902#StdOut 903matrix.getTranslateX() == 42 904## 905## 906 907#SeeAlso get getTranslateY setTranslateX setTranslate 908 909## 910 911# ------------------------------------------------------------------------------ 912 913#Method SkScalar getTranslateY() const 914 915#Line # returns vertical translation ## 916Returns translation contributing to y output. 917With mapPoints, moves Points along the y-axis. 918 919#Return vertical translation factor ## 920 921#Example 922SkMatrix matrix; 923matrix.setTranslate(42, 24); 924SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!'); 925#StdOut 926matrix.getTranslateY() == 24 927## 928## 929 930#SeeAlso get getTranslateX setTranslateY setTranslate 931 932## 933 934# ------------------------------------------------------------------------------ 935 936#Method SkScalar getPerspX() const 937 938#Line # returns input x perspective factor ## 939Returns factor scaling input x relative to input y. 940 941#Return input x perspective factor ## 942 943#Example 944 SkMatrix m; 945 m.setIdentity(); 946 m.set(SkMatrix::kMPersp0, -0.004f); 947 SkAutoCanvasRestore autoRestore(canvas, true); 948 canvas->translate(22, 144); 949 SkPaint black; 950 black.setAntiAlias(true); 951 black.setTextSize(24); 952 SkPaint gray = black; 953 gray.setColor(0xFF9f9f9f); 954 SkString string; 955 string.appendScalar(m.getPerspX()); 956 canvas->drawString(string, 0, -72, gray); 957 canvas->concat(m); 958 canvas->drawString(string, 0, 0, black); 959## 960 961#SeeAlso kMPersp0 getPerspY 962 963## 964 965# ------------------------------------------------------------------------------ 966 967#Method SkScalar getPerspY() const 968 969#Line # returns input y perspective factor ## 970 971Returns factor scaling input y relative to input x. 972 973#Return input y perspective factor ## 974 975#Example 976 SkMatrix m; 977 m.setIdentity(); 978 m.set(SkMatrix::kMPersp1, -0.004f); 979 SkAutoCanvasRestore autoRestore(canvas, true); 980 canvas->translate(22, 144); 981 SkPaint black; 982 black.setAntiAlias(true); 983 black.setTextSize(24); 984 SkPaint gray = black; 985 gray.setColor(0xFF9f9f9f); 986 SkString string; 987 string.appendScalar(m.getPerspY()); 988 canvas->drawString(string, 0, -72, gray); 989 canvas->concat(m); 990 canvas->drawString(string, 0, 0, black); 991## 992 993#SeeAlso kMPersp1 getPerspX 994 995## 996 997# ------------------------------------------------------------------------------ 998 999#Method SkScalar& operator[](int index) 1000 1001#Line # returns writable reference to Matrix value ## 1002Returns writable Matrix value. Asserts if index is out of range and SK_DEBUG is 1003defined. Clears internal cache anticipating that caller will change Matrix value. 1004 1005Next call to read Matrix state may recompute cache; subsequent writes to Matrix 1006value must be followed by dirtyMatrixTypeCache. 1007 1008#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 1009 kMPersp0, kMPersp1, kMPersp2 1010## 1011 1012#Return writable value corresponding to index ## 1013 1014#Example 1015SkMatrix matrix; 1016matrix.setIdentity(); 1017SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX); 1018SkScalar& skewRef = matrix[SkMatrix::kMSkewX]; 1019skewRef = 0; 1020SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 1021skewRef = 1; 1022SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 1023matrix.dirtyMatrixTypeCache(); 1024SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX); 1025#StdOut 1026with identity matrix: x = 24 1027after skew x mod: x = 24 1028after 2nd skew x mod: x = 24 1029after dirty cache: x = 66 1030## 1031## 1032 1033#SeeAlso get dirtyMatrixTypeCache set 1034 1035## 1036 1037# ------------------------------------------------------------------------------ 1038 1039#Method void set(int index, SkScalar value) 1040 1041#Line # sets one value ## 1042Sets Matrix value. Asserts if index is out of range and SK_DEBUG is 1043defined. Safer than operator[]; internal cache is always maintained. 1044 1045#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 1046 kMPersp0, kMPersp1, kMPersp2 1047## 1048#Param value Scalar to store in Matrix ## 1049 1050#Example 1051SkMatrix matrix; 1052matrix.setIdentity(); 1053SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX); 1054matrix.set(SkMatrix::kMSkewX, 0); 1055SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 1056matrix.set(SkMatrix::kMSkewX, 1); 1057SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 1058#StdOut 1059with identity matrix: x = 24 1060after skew x mod: x = 24 1061after 2nd skew x mod: x = 66 1062## 1063## 1064 1065#SeeAlso operator[] get 1066 1067#Method ## 1068 1069# ------------------------------------------------------------------------------ 1070 1071#Method void setScaleX(SkScalar v) 1072 1073#Line # sets horizontal scale factor ## 1074Sets horizontal scale factor. 1075 1076#Param v horizontal scale factor to store ## 1077 1078#Example 1079#Height 64 1080SkPaint paint; 1081paint.setAntiAlias(true); 1082paint.setTextSize(24); 1083canvas->drawString("normal", 12, 24, paint); 1084SkMatrix matrix; 1085matrix.setIdentity(); 1086matrix.setScaleX(3); 1087canvas->concat(matrix); 1088canvas->drawString("x scale", 0, 48, paint); 1089## 1090 1091#SeeAlso set setScale setScaleY 1092 1093#Method ## 1094 1095# ------------------------------------------------------------------------------ 1096 1097#Method void setScaleY(SkScalar v) 1098 1099#Line # sets vertical scale factor ## 1100Sets vertical scale factor. 1101 1102#Param v vertical scale factor to store ## 1103 1104#Example 1105#Height 192 1106SkPaint paint; 1107paint.setAntiAlias(true); 1108paint.setTextSize(24); 1109canvas->drawString("normal", 12, 24, paint); 1110SkMatrix matrix; 1111matrix.setIdentity(); 1112matrix.setScaleY(3); 1113canvas->concat(matrix); 1114canvas->drawString("y scale", 12, 48, paint); 1115## 1116 1117#SeeAlso set setScale setScaleX 1118 1119#Method ## 1120 1121# ------------------------------------------------------------------------------ 1122 1123#Method void setSkewY(SkScalar v) 1124 1125#Line # sets vertical skew factor ## 1126Sets vertical skew factor. 1127 1128#Param v vertical skew factor to store ## 1129 1130#Example 1131#Height 96 1132SkPaint paint; 1133paint.setAntiAlias(true); 1134paint.setTextSize(24); 1135canvas->drawString("normal", 12, 24, paint); 1136SkMatrix matrix; 1137matrix.setIdentity(); 1138matrix.setSkewY(.3f); 1139canvas->concat(matrix); 1140canvas->drawString("y skew", 12, 48, paint); 1141## 1142 1143#SeeAlso set setSkew setSkewX 1144 1145#Method ## 1146 1147# ------------------------------------------------------------------------------ 1148 1149#Method void setSkewX(SkScalar v) 1150 1151#Line # sets horizontal skew factor ## 1152Sets horizontal skew factor. 1153 1154#Param v horizontal skew factor to store ## 1155 1156#Example 1157#Height 64 1158SkPaint paint; 1159paint.setAntiAlias(true); 1160paint.setTextSize(24); 1161canvas->drawString("normal", 12, 24, paint); 1162SkMatrix matrix; 1163matrix.setIdentity(); 1164matrix.setSkewX(-.7f); 1165canvas->concat(matrix); 1166canvas->drawString("x skew", 36, 48, paint); 1167## 1168 1169#SeeAlso set setSkew setSkewX 1170 1171#Method ## 1172 1173# ------------------------------------------------------------------------------ 1174 1175#Method void setTranslateX(SkScalar v) 1176 1177#Line # sets horizontal translation ## 1178Sets horizontal translation. 1179 1180#Param v horizontal translation to store ## 1181 1182#Example 1183#Height 48 1184SkPaint paint; 1185paint.setAntiAlias(true); 1186paint.setTextSize(24); 1187canvas->drawString("normal", 8, 24, paint); 1188SkMatrix matrix; 1189matrix.setIdentity(); 1190matrix.setTranslateX(96); 1191canvas->concat(matrix); 1192canvas->drawString("x translate", 8, 24, paint); 1193## 1194 1195#SeeAlso set setTranslate setTranslateY 1196 1197#Method ## 1198 1199# ------------------------------------------------------------------------------ 1200 1201#Method void setTranslateY(SkScalar v) 1202 1203#Line # sets vertical translation ## 1204Sets vertical translation. 1205 1206#Param v vertical translation to store ## 1207 1208#Example 1209#Height 64 1210SkPaint paint; 1211paint.setAntiAlias(true); 1212paint.setTextSize(24); 1213canvas->drawString("normal", 8, 24, paint); 1214SkMatrix matrix; 1215matrix.setIdentity(); 1216matrix.setTranslateY(24); 1217canvas->concat(matrix); 1218canvas->drawString("y translate", 8, 24, paint); 1219## 1220 1221#SeeAlso set setTranslate setTranslateX 1222 1223#Method ## 1224 1225# ------------------------------------------------------------------------------ 1226 1227#Method void setPerspX(SkScalar v) 1228 1229#Line # sets input x perspective factor ## 1230Sets input x perspective factor, which causes mapXY to vary input x inversely 1231proportional to input y. 1232 1233#Param v perspective factor ## 1234 1235#Example 1236#Image 4 1237for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) { 1238 SkMatrix matrix; 1239 matrix.setIdentity(); 1240 matrix.setPerspX(perspX); 1241 canvas->save(); 1242 canvas->concat(matrix); 1243 canvas->drawBitmap(source, 0, 0); 1244 canvas->restore(); 1245 canvas->translate(64, 64); 1246} 1247## 1248 1249#SeeAlso getPerspX set setAll set9 MakeAll 1250 1251#Method ## 1252 1253# ------------------------------------------------------------------------------ 1254 1255#Method void setPerspY(SkScalar v) 1256 1257#Line # sets input y perspective factor ## 1258Sets input y perspective factor, which causes mapXY to vary input y inversely 1259proportional to input x. 1260 1261#Param v perspective factor ## 1262 1263#Example 1264#Image 4 1265for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) { 1266 SkMatrix matrix; 1267 matrix.setIdentity(); 1268 matrix.setPerspY(perspX); 1269 canvas->save(); 1270 canvas->concat(matrix); 1271 canvas->drawBitmap(source, 0, 0); 1272 canvas->restore(); 1273 canvas->translate(64, 64); 1274} 1275## 1276 1277#SeeAlso getPerspY set setAll set9 MakeAll 1278 1279#Method ## 1280 1281# ------------------------------------------------------------------------------ 1282 1283#Method void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, 1284 SkScalar skewY, SkScalar scaleY, SkScalar transY, 1285 SkScalar persp0, SkScalar persp1, SkScalar persp2) 1286#Line # sets all values from parameters ## 1287 1288Sets all values from parameters. Sets matrix to: 1289 1290#Code 1291#Literal 1292| scaleX skewX transX | 1293| skewY scaleY transY | 1294| persp0 persp1 persp2 | 1295## 1296 1297#Param scaleX horizontal scale factor to store ## 1298#Param skewX horizontal skew factor to store ## 1299#Param transX horizontal translation to store ## 1300#Param skewY vertical skew factor to store ## 1301#Param scaleY vertical scale factor to store ## 1302#Param transY vertical translation to store ## 1303#Param persp0 input x perspective factor to store ## 1304#Param persp1 input y perspective factor to store ## 1305#Param persp2 perspective scale factor to store ## 1306 1307#Example 1308#Height 128 1309 SkPaint p; 1310 p.setAntiAlias(true); 1311 p.setTextSize(64); 1312 SkMatrix m; 1313 for (SkScalar sx : { -1, 1 } ) { 1314 for (SkScalar sy : { -1, 1 } ) { 1315 SkAutoCanvasRestore autoRestore(canvas, true); 1316 m.setAll(sx, 1, 128, 0, sy, 64, 0, 0, 1); 1317 canvas->concat(m); 1318 canvas->drawString("K", 0, 0, p); 1319 } 1320 } 1321## 1322 1323#SeeAlso set9 MakeAll 1324 1325#Method ## 1326 1327# ------------------------------------------------------------------------------ 1328 1329#Method void get9(SkScalar buffer[9]) const 1330 1331#Line # returns all nine Matrix values ## 1332Copies nine Scalar values contained by Matrix into buffer, in member value 1333ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 1334kMPersp0, kMPersp1, kMPersp2. 1335 1336#Param buffer storage for nine Scalar values ## 1337 1338#Example 1339SkMatrix matrix = SkMatrix::MakeRectToRect({0, 0, 1, 1}, {3, 4, 7, 9}, 1340 SkMatrix::kFill_ScaleToFit); 1341SkScalar b[9]; 1342matrix.get9(b); 1343SkDebugf("{%g, %g, %g},\n{%g, %g, %g},\n{%g, %g, %g}\n", b[0], b[1], b[2], 1344 b[3], b[4], b[5], b[6], b[7], b[8]); 1345#StdOut 1346{4, 0, 3}, 1347{0, 5, 4}, 1348{0, 0, 1} 1349## 1350## 1351 1352#SeeAlso set9 1353 1354#Method ## 1355 1356# ------------------------------------------------------------------------------ 1357 1358#Method void set9(const SkScalar buffer[9]) 1359 1360#Line # sets all values from Scalar array ## 1361Sets Matrix to nine Scalar values in buffer, in member value ascending order: 1362kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1, 1363kMPersp2. 1364 1365Sets matrix to: 1366 1367#Code 1368#Literal 1369| buffer[0] buffer[1] buffer[2] | 1370| buffer[3] buffer[4] buffer[5] | 1371| buffer[6] buffer[7] buffer[8] | 1372## 1373 1374In the future, set9 followed by get9 may not return the same values. Since Matrix 1375maps non-homogeneous coordinates, scaling all nine values produces an equivalent 1376transformation, possibly improving precision. 1377 1378#Param buffer nine Scalar values ## 1379 1380#Example 1381#Image 4 1382SkMatrix m; 1383SkScalar buffer[9] = {4, 0, 3, 0, 5, 4, 0, 0, 1}; 1384m.set9(buffer); 1385canvas->concat(m); 1386canvas->drawBitmap(source, 0, 0); 1387## 1388 1389#SeeAlso setAll get9 MakeAll 1390 1391#Method ## 1392 1393# ------------------------------------------------------------------------------ 1394 1395#Method void reset() 1396 1397#Line # sets Matrix to identity ## 1398Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to: 1399 1400#Code 1401#Literal 1402| 1 0 0 | 1403| 0 1 0 | 1404| 0 0 1 | 1405## 1406 1407Also called setIdentity(); use the one that provides better inline 1408documentation. 1409 1410#Example 1411SkMatrix m; 1412m.reset(); 1413SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false"); 1414#StdOut 1415m.isIdentity(): true 1416## 1417## 1418 1419#SeeAlso isIdentity setIdentity 1420 1421#Method ## 1422 1423# ------------------------------------------------------------------------------ 1424 1425#Method void setIdentity() 1426 1427#Line # sets Matrix to identity ## 1428Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to: 1429 1430#Code 1431#Literal 1432| 1 0 0 | 1433| 0 1 0 | 1434| 0 0 1 | 1435## 1436 1437Also called reset(); use the one that provides better inline 1438documentation. 1439 1440#Example 1441SkMatrix m; 1442m.setIdentity(); 1443SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false"); 1444#StdOut 1445m.isIdentity(): true 1446## 1447## 1448 1449#SeeAlso isIdentity reset 1450 1451#Method ## 1452 1453# ------------------------------------------------------------------------------ 1454 1455#Method void setTranslate(SkScalar dx, SkScalar dy) 1456 1457#Line # sets to translate in x and y ## 1458Sets Matrix to translate by (dx, dy). 1459 1460#Param dx horizontal translation ## 1461#Param dy vertical translation ## 1462 1463#Example 1464#Height 64 1465SkPaint paint; 1466paint.setAntiAlias(true); 1467paint.setTextSize(24); 1468canvas->drawString("normal", 8, 24, paint); 1469SkMatrix matrix; 1470matrix.setTranslate(96, 24); 1471canvas->concat(matrix); 1472canvas->drawString("translate", 8, 24, paint); 1473## 1474 1475#SeeAlso setTranslateX setTranslateY 1476 1477#Method ## 1478 1479# ------------------------------------------------------------------------------ 1480 1481#Method void setTranslate(const SkVector& v) 1482 1483Sets Matrix to translate by (v.fX, v.fY). 1484 1485#Param v Vector containing horizontal and vertical translation ## 1486 1487#Example 1488#Height 64 1489SkPaint paint; 1490paint.setAntiAlias(true); 1491paint.setTextSize(24); 1492canvas->drawString("normal", 8, 24, paint); 1493SkMatrix matrix; 1494matrix.setTranslate({96, 24}); 1495canvas->concat(matrix); 1496canvas->drawString("translate", 8, 24, paint); 1497## 1498 1499#SeeAlso setTranslateX setTranslateY MakeTrans 1500 1501#Method ## 1502 1503# ------------------------------------------------------------------------------ 1504 1505#Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) 1506 1507#Line # sets to scale about a point ## 1508Sets Matrix to scale by sx and sy, about a pivot point at (px, py). 1509The pivot point is unchanged when mapped with Matrix. 1510 1511#Param sx horizontal scale factor ## 1512#Param sy vertical scale factor ## 1513#Param px pivot x ## 1514#Param py pivot y ## 1515 1516#Example 1517#Height 128 1518 SkPaint p; 1519 p.setAntiAlias(true); 1520 p.setTextSize(64); 1521 SkMatrix m; 1522 for (SkScalar sx : { -1, 1 } ) { 1523 for (SkScalar sy : { -1, 1 } ) { 1524 SkAutoCanvasRestore autoRestore(canvas, true); 1525 m.setScale(sx, sy, 128, 64); 1526 canvas->concat(m); 1527 canvas->drawString("%", 128, 64, p); 1528 } 1529 } 1530## 1531 1532#SeeAlso setScaleX setScaleY MakeScale preScale postScale 1533 1534#Method ## 1535 1536# ------------------------------------------------------------------------------ 1537 1538#Method void setScale(SkScalar sx, SkScalar sy) 1539 1540Sets Matrix to scale by sx and sy about at pivot point at (0, 0). 1541 1542#Param sx horizontal scale factor ## 1543#Param sy vertical scale factor ## 1544 1545#Example 1546#Height 128 1547 SkPaint p; 1548 p.setAntiAlias(true); 1549 p.setTextSize(64); 1550 SkMatrix m; 1551 for (SkScalar sx : { -1, 1 } ) { 1552 for (SkScalar sy : { -1, 1 } ) { 1553 SkAutoCanvasRestore autoRestore(canvas, true); 1554 m.setScale(sx, sy); 1555 m.postTranslate(128, 64); 1556 canvas->concat(m); 1557 canvas->drawString("@", 0, 0, p); 1558 } 1559 } 1560## 1561 1562#SeeAlso setScaleX setScaleY MakeScale preScale postScale 1563 1564#Method ## 1565 1566# ------------------------------------------------------------------------------ 1567 1568#Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py) 1569 1570#Line # sets to rotate about a point ## 1571Sets Matrix to rotate by degrees about a pivot point at (px, py). 1572The pivot point is unchanged when mapped with Matrix. 1573 1574Positive degrees rotates clockwise. 1575 1576#Param degrees angle of axes relative to upright axes ## 1577#Param px pivot x ## 1578#Param py pivot y ## 1579 1580#Example 1581#Height 128 1582 SkPaint paint; 1583 paint.setColor(SK_ColorGRAY); 1584 paint.setAntiAlias(true); 1585 SkRect rect = {20, 20, 100, 100}; 1586 canvas->drawRect(rect, paint); 1587 paint.setColor(SK_ColorRED); 1588 SkMatrix matrix; 1589 matrix.setRotate(25, rect.centerX(), rect.centerY()); 1590 canvas->concat(matrix); 1591 canvas->drawRect(rect, paint); 1592## 1593 1594#SeeAlso setSinCos preRotate postRotate 1595 1596#Method ## 1597 1598# ------------------------------------------------------------------------------ 1599 1600#Method void setRotate(SkScalar degrees) 1601 1602Sets Matrix to rotate by degrees about a pivot point at (0, 0). 1603Positive degrees rotates clockwise. 1604 1605#Param degrees angle of axes relative to upright axes ## 1606 1607#Example 1608#Height 128 1609 SkPaint paint; 1610 paint.setColor(SK_ColorGRAY); 1611 paint.setAntiAlias(true); 1612 SkRect rect = {20, 20, 100, 100}; 1613 canvas->drawRect(rect, paint); 1614 paint.setColor(SK_ColorRED); 1615 SkMatrix matrix; 1616 matrix.setRotate(25); 1617 canvas->translate(rect.centerX(), rect.centerY()); 1618 canvas->concat(matrix); 1619 canvas->translate(-rect.centerX(), -rect.centerY()); 1620 canvas->drawRect(rect, paint); 1621## 1622 1623#SeeAlso setSinCos preRotate postRotate 1624 1625#Method ## 1626 1627# ------------------------------------------------------------------------------ 1628 1629#Method void setSinCos(SkScalar sinValue, SkScalar cosValue, 1630 SkScalar px, SkScalar py) 1631#Line # sets to rotate and scale about a point ## 1632 1633Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (px, py). 1634The pivot point is unchanged when mapped with Matrix. 1635 1636Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). 1637Vector length specifies scale. 1638 1639#Param sinValue rotation vector x component ## 1640#Param cosValue rotation vector y component ## 1641#Param px pivot x ## 1642#Param py pivot y ## 1643 1644#Example 1645#Height 128 1646 SkPaint paint; 1647 paint.setColor(SK_ColorGRAY); 1648 paint.setAntiAlias(true); 1649 SkRect rect = {20, 20, 100, 100}; 1650 canvas->drawRect(rect, paint); 1651 paint.setColor(SK_ColorRED); 1652 SkMatrix matrix; 1653 matrix.setSinCos(.25f, .85f, rect.centerX(), rect.centerY()); 1654 canvas->concat(matrix); 1655 canvas->drawRect(rect, paint); 1656## 1657 1658#SeeAlso setRotate setScale setRSXform 1659 1660#Method ## 1661 1662# ------------------------------------------------------------------------------ 1663 1664#Method void setSinCos(SkScalar sinValue, SkScalar cosValue) 1665 1666Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (0, 0). 1667 1668Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). 1669Vector length specifies scale. 1670 1671#Param sinValue rotation vector x component ## 1672#Param cosValue rotation vector y component ## 1673 1674#Example 1675#Description 1676Canvas needs offset after applying Matrix to pivot about Rect center. 1677## 1678#Height 128 1679 SkPaint paint; 1680 paint.setColor(SK_ColorGRAY); 1681 paint.setAntiAlias(true); 1682 SkRect rect = {20, 20, 100, 100}; 1683 canvas->drawRect(rect, paint); 1684 paint.setColor(SK_ColorRED); 1685 SkMatrix matrix; 1686 matrix.setSinCos(.25f, .85f); 1687 matrix.postTranslate(rect.centerX(), rect.centerY()); 1688 canvas->concat(matrix); 1689 canvas->translate(-rect.centerX(), -rect.centerY()); 1690 canvas->drawRect(rect, paint); 1691## 1692 1693#SeeAlso setRotate setScale setRSXform 1694 1695#Method ## 1696 1697# ------------------------------------------------------------------------------ 1698 1699#Method SkMatrix& setRSXform(const SkRSXform& rsxForm) 1700 1701#Line # sets to rotate, scale, and translate ## 1702Sets Matrix to rotate, scale, and translate using a compressed matrix form. 1703 1704Vector (rsxForm.fSSin, rsxForm.fSCos) describes the angle of rotation relative 1705to (0, 1). Vector length specifies scale. Mapped point is rotated and scaled 1706by Vector, then translated by (rsxForm.fTx, rsxForm.fTy). 1707 1708#Param rsxForm compressed RSXform matrix ## 1709 1710#Return reference to Matrix ## 1711 1712#Example 1713#Description 1714Canvas needs offset after applying Matrix to pivot about Rect center. 1715## 1716#Height 128 1717 SkPaint paint; 1718 paint.setColor(SK_ColorGRAY); 1719 paint.setAntiAlias(true); 1720 SkRect rect = {20, 20, 100, 100}; 1721 canvas->drawRect(rect, paint); 1722 paint.setColor(SK_ColorRED); 1723 SkMatrix matrix; 1724 matrix.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY())); 1725 canvas->concat(matrix); 1726 canvas->translate(-rect.centerX(), -rect.centerY()); 1727 canvas->drawRect(rect, paint); 1728## 1729 1730#SeeAlso setSinCos setScale setTranslate 1731 1732#Method ## 1733 1734# ------------------------------------------------------------------------------ 1735 1736#Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) 1737 1738#Line # sets to skew about a point ## 1739Sets Matrix to skew by kx and ky, about a pivot point at (px, py). 1740The pivot point is unchanged when mapped with Matrix. 1741 1742#Param kx horizontal skew factor ## 1743#Param ky vertical skew factor ## 1744#Param px pivot x ## 1745#Param py pivot y ## 1746 1747#Example 1748 SkPaint p; 1749 p.setAntiAlias(true); 1750 p.setTextSize(48); 1751 SkMatrix m; 1752 for (SkScalar sx : { -1, 0, 1 } ) { 1753 for (SkScalar sy : { -1, 0, 1 } ) { 1754 SkAutoCanvasRestore autoRestore(canvas, true); 1755 m.setSkew(sx, sy, 96 + 64 * sx, 128 + 48 * sy); 1756 canvas->concat(m); 1757 canvas->drawString("K", 96 + 64 * sx, 128 + 48 * sy, p); 1758 } 1759 } 1760## 1761 1762#SeeAlso setSkewX setSkewY preSkew postSkew 1763 1764#Method ## 1765 1766# ------------------------------------------------------------------------------ 1767 1768#Method void setSkew(SkScalar kx, SkScalar ky) 1769 1770Sets Matrix to skew by kx and ky, about a pivot point at (0, 0). 1771 1772#Param kx horizontal skew factor ## 1773#Param ky vertical skew factor ## 1774 1775#Example 1776 SkPaint p; 1777 p.setAntiAlias(true); 1778 p.setTextSize(48); 1779 SkMatrix m; 1780 for (SkScalar sx : { -1, 0, 1 } ) { 1781 for (SkScalar sy : { -1, 0, 1 } ) { 1782 SkAutoCanvasRestore autoRestore(canvas, true); 1783 m.setSkew(sx, sy); 1784 m.postTranslate(96 + 64 * sx, 128 + 48 * sy); 1785 canvas->concat(m); 1786 canvas->drawString("K", 0, 0, p); 1787 } 1788 } 1789## 1790 1791#SeeAlso setSkewX setSkewY preSkew postSkew 1792 1793#Method ## 1794 1795# ------------------------------------------------------------------------------ 1796 1797#Method void setConcat(const SkMatrix& a, const SkMatrix& b) 1798 1799#Line # sets to Matrix parameter multiplied by Matrix parameter ## 1800Sets Matrix to Matrix a multiplied by Matrix b. Either a or b may be this. 1801 1802Given: 1803 1804#Code 1805#Literal 1806 | A B C | | J K L | 1807a = | D E F |, b = | M N O | 1808 | G H I | | P Q R | 1809## 1810 1811sets Matrix to: 1812 1813#Code 1814#Literal 1815 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 1816a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 1817 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 1818## 1819 1820#Param a Matrix on left side of multiply expression ## 1821#Param b Matrix on right side of multiply expression ## 1822 1823#Example 1824#Image 3 1825#Description 1826setPolyToPoly creates perspective matrices, one the inverse of the other. 1827Multiplying the matrix by its inverse turns into an identity matrix. 1828## 1829SkMatrix matrix, matrix2; 1830SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1831SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1832matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1833matrix2.setPolyToPoly(perspect, bitmapBounds, 4); 1834matrix.setConcat(matrix, matrix2); 1835canvas->concat(matrix); 1836canvas->drawBitmap(source, 0, 0); 1837## 1838 1839#SeeAlso Concat preConcat postConcat SkCanvas::concat 1840 1841#Method ## 1842 1843# ------------------------------------------------------------------------------ 1844 1845#Method void preTranslate(SkScalar dx, SkScalar dy) 1846 1847#Line # pre-multiplies Matrix by translation ## 1848Sets Matrix to Matrix multiplied by Matrix constructed from translation (dx, dy). 1849This can be thought of as moving the point to be mapped before applying Matrix. 1850 1851Given: 1852 1853#Code 1854#Literal 1855 | A B C | | 1 0 dx | 1856Matrix = | D E F |, T(dx, dy) = | 0 1 dy | 1857 | G H I | | 0 0 1 | 1858## 1859 1860sets Matrix to: 1861 1862#Code 1863#Literal 1864 | A B C | | 1 0 dx | | A B A*dx+B*dy+C | 1865Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F | 1866 | G H I | | 0 0 1 | | G H G*dx+H*dy+I | 1867## 1868 1869#Param dx x translation before applying Matrix ## 1870#Param dy y translation before applying Matrix ## 1871 1872#Example 1873#Height 160 1874 SkPaint paint; 1875 paint.setAntiAlias(true); 1876 SkRect rect = {20, 20, 100, 100}; 1877 for (int i = 0; i < 2; ++i ) { 1878 SkMatrix matrix; 1879 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320); 1880 { 1881 SkAutoCanvasRestore acr(canvas, true); 1882 canvas->concat(matrix); 1883 paint.setColor(SK_ColorGRAY); 1884 canvas->drawRect(rect, paint); 1885 } 1886 paint.setColor(SK_ColorRED); 1887 for (int j = 0; j < 2; ++j ) { 1888 SkAutoCanvasRestore acr(canvas, true); 1889 matrix.preTranslate(40, 40); 1890 canvas->concat(matrix); 1891 canvas->drawCircle(0, 0, 3, paint); 1892 } 1893 } 1894## 1895 1896#SeeAlso postTranslate setTranslate MakeTrans 1897 1898#Method ## 1899 1900# ------------------------------------------------------------------------------ 1901 1902#Method void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) 1903 1904#Line # pre-multiplies Matrix by scale ## 1905Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy) 1906about pivot point (px, py). 1907This can be thought of as scaling about a pivot point before applying Matrix. 1908 1909Given: 1910 1911#Code 1912#Literal 1913 | A B C | | sx 0 dx | 1914Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy | 1915 | G H I | | 0 0 1 | 1916## 1917 1918where 1919 1920#Code 1921#Literal 1922dx = px - sx * px 1923dy = py - sy * py 1924## 1925 1926sets Matrix to: 1927 1928#Code 1929#Literal 1930 | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C | 1931Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F | 1932 | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I | 1933## 1934 1935#Param sx horizontal scale factor ## 1936#Param sy vertical scale factor ## 1937#Param px pivot x ## 1938#Param py pivot y ## 1939 1940#Example 1941#Image 3 1942SkMatrix matrix; 1943SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1944SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1945matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1946matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2); 1947canvas->concat(matrix); 1948canvas->drawBitmap(source, 0, 0); 1949## 1950 1951#SeeAlso postScale setScale MakeScale 1952 1953#Method ## 1954 1955# ------------------------------------------------------------------------------ 1956 1957#Method void preScale(SkScalar sx, SkScalar sy) 1958 1959Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy) 1960about pivot point (0, 0). 1961This can be thought of as scaling about the origin before applying Matrix. 1962 1963Given: 1964 1965#Code 1966#Literal 1967 | A B C | | sx 0 0 | 1968Matrix = | D E F |, S(sx, sy) = | 0 sy 0 | 1969 | G H I | | 0 0 1 | 1970## 1971 1972sets Matrix to: 1973 1974#Code 1975#Literal 1976 | A B C | | sx 0 0 | | A*sx B*sy C | 1977Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F | 1978 | G H I | | 0 0 1 | | G*sx H*sy I | 1979## 1980 1981#Param sx horizontal scale factor ## 1982#Param sy vertical scale factor ## 1983 1984#Example 1985#Image 3 1986SkMatrix matrix; 1987SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 1988SkRect::Make(source.bounds()).toQuad(bitmapBounds); 1989matrix.setPolyToPoly(bitmapBounds, perspect, 4); 1990matrix.preScale(.75f, 1.5f); 1991canvas->concat(matrix); 1992canvas->drawBitmap(source, 0, 0); 1993## 1994 1995#SeeAlso postScale setScale MakeScale 1996 1997#Method ## 1998 1999# ------------------------------------------------------------------------------ 2000 2001#Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py) 2002 2003#Line # pre-multiplies Matrix by rotation ## 2004Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees 2005about pivot point (px, py). 2006This can be thought of as rotating about a pivot point before applying Matrix. 2007 2008Positive degrees rotates clockwise. 2009 2010Given: 2011 2012#Code 2013#Literal 2014 | A B C | | c -s dx | 2015Matrix = | D E F |, R(degrees, px, py) = | s c dy | 2016 | G H I | | 0 0 1 | 2017## 2018 2019where 2020 2021#Code 2022#Literal 2023c = cos(degrees) 2024s = sin(degrees) 2025dx = s * py + (1 - c) * px 2026dy = -s * px + (1 - c) * py 2027## 2028 2029sets Matrix to: 2030 2031#Code 2032#Literal 2033 | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C | 2034Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F | 2035 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I | 2036## 2037 2038#Param degrees angle of axes relative to upright axes ## 2039#Param px pivot x ## 2040#Param py pivot y ## 2041 2042#Example 2043#Image 3 2044SkMatrix matrix; 2045SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2046SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2047matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2048matrix.preRotate(45, source.width() / 2, source.height() / 2); 2049canvas->concat(matrix); 2050canvas->drawBitmap(source, 0, 0); 2051## 2052 2053#SeeAlso postRotate setRotate 2054 2055#Method ## 2056 2057# ------------------------------------------------------------------------------ 2058 2059#Method void preRotate(SkScalar degrees) 2060 2061Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees 2062about pivot point (0, 0). 2063This can be thought of as rotating about the origin before applying Matrix. 2064 2065Positive degrees rotates clockwise. 2066 2067Given: 2068 2069#Code 2070#Literal 2071 | A B C | | c -s 0 | 2072Matrix = | D E F |, R(degrees, px, py) = | s c 0 | 2073 | G H I | | 0 0 1 | 2074## 2075 2076where 2077 2078#Code 2079#Literal 2080c = cos(degrees) 2081s = sin(degrees) 2082## 2083 2084sets Matrix to: 2085 2086#Code 2087#Literal 2088 | A B C | | c -s 0 | | Ac+Bs -As+Bc C | 2089Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F | 2090 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I | 2091## 2092 2093#Param degrees angle of axes relative to upright axes ## 2094 2095#Example 2096#Image 3 2097SkMatrix matrix; 2098SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2099SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2100matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2101matrix.preRotate(45); 2102canvas->concat(matrix); 2103canvas->drawBitmap(source, 0, 0); 2104## 2105 2106#SeeAlso postRotate setRotate 2107 2108#Method ## 2109 2110# ------------------------------------------------------------------------------ 2111 2112#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) 2113 2114#Line # pre-multiplies Matrix by skew ## 2115Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky) 2116about pivot point (px, py). 2117This can be thought of as skewing about a pivot point before applying Matrix. 2118 2119Given: 2120 2121#Code 2122#Literal 2123 | A B C | | 1 kx dx | 2124Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy | 2125 | G H I | | 0 0 1 | 2126## 2127 2128where 2129 2130#Code 2131#Literal 2132dx = -kx * py 2133dy = -ky * px 2134## 2135 2136sets Matrix to: 2137 2138#Code 2139#Literal 2140 | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C | 2141Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F | 2142 | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I | 2143## 2144 2145#Param kx horizontal skew factor ## 2146#Param ky vertical skew factor ## 2147#Param px pivot x ## 2148#Param py pivot y ## 2149 2150#Example 2151#Image 3 2152SkMatrix matrix; 2153SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2154SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2155matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2156matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2); 2157canvas->concat(matrix); 2158canvas->drawBitmap(source, 0, 0); 2159## 2160 2161#SeeAlso postSkew setSkew 2162 2163#Method ## 2164 2165# ------------------------------------------------------------------------------ 2166 2167#Method void preSkew(SkScalar kx, SkScalar ky) 2168 2169Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky) 2170about pivot point (0, 0). 2171This can be thought of as skewing about the origin before applying Matrix. 2172 2173Given: 2174 2175#Code 2176#Literal 2177 | A B C | | 1 kx 0 | 2178Matrix = | D E F |, K(kx, ky) = | ky 1 0 | 2179 | G H I | | 0 0 1 | 2180## 2181 2182sets Matrix to: 2183 2184#Code 2185#Literal 2186 | A B C | | 1 kx 0 | | A+B*ky A*kx+B C | 2187Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F | 2188 | G H I | | 0 0 1 | | G+H*ky G*kx+H I | 2189## 2190 2191#Param kx horizontal skew factor ## 2192#Param ky vertical skew factor ## 2193 2194#Example 2195#Image 3 2196SkMatrix matrix; 2197SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2198SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2199matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2200matrix.preSkew(.5f, 0); 2201canvas->concat(matrix); 2202canvas->drawBitmap(source, 0, 0); 2203## 2204 2205#SeeAlso postSkew setSkew 2206 2207#Method ## 2208 2209# ------------------------------------------------------------------------------ 2210 2211#Method void preConcat(const SkMatrix& other) 2212 2213#Line # pre-multiplies Matrix by Matrix parameter ## 2214Sets Matrix to Matrix multiplied by Matrix other. 2215This can be thought of mapping by other before applying Matrix. 2216 2217Given: 2218 2219#Code 2220#Literal 2221 | A B C | | J K L | 2222Matrix = | D E F |, other = | M N O | 2223 | G H I | | P Q R | 2224## 2225 2226sets Matrix to: 2227 2228#Code 2229#Literal 2230 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 2231Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 2232 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 2233## 2234 2235#Param other Matrix on right side of multiply expression ## 2236 2237#Example 2238#Image 3 2239#Description 2240setPolyToPoly creates perspective matrices, one the inverse of the other. 2241Multiplying the matrix by its inverse turns into an identity matrix. 2242## 2243SkMatrix matrix, matrix2; 2244SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2245SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2246matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2247matrix2.setPolyToPoly(perspect, bitmapBounds, 4); 2248matrix.preConcat(matrix2); 2249canvas->concat(matrix); 2250canvas->drawBitmap(source, 0, 0); 2251## 2252 2253#SeeAlso postConcat setConcat Concat 2254 2255#Method ## 2256 2257# ------------------------------------------------------------------------------ 2258 2259#Method void postTranslate(SkScalar dx, SkScalar dy) 2260 2261#Line # post-multiplies Matrix by translation ## 2262Sets Matrix to Matrix constructed from translation (dx, dy) multiplied by Matrix. 2263This can be thought of as moving the point to be mapped after applying Matrix. 2264 2265Given: 2266 2267#Code 2268#Literal 2269 | J K L | | 1 0 dx | 2270Matrix = | M N O |, T(dx, dy) = | 0 1 dy | 2271 | P Q R | | 0 0 1 | 2272## 2273 2274sets Matrix to: 2275 2276#Code 2277#Literal 2278 | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R | 2279T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R | 2280 | 0 0 1 | | P Q R | | P Q R | 2281## 2282 2283#Param dx x translation after applying Matrix ## 2284#Param dy y translation after applying Matrix ## 2285 2286#Example 2287#Height 160 2288#Description 2289Compare with preTranslate example. 2290## 2291 SkPaint paint; 2292 paint.setAntiAlias(true); 2293 SkRect rect = {20, 20, 100, 100}; 2294 for (int i = 0; i < 2; ++i ) { 2295 SkMatrix matrix; 2296 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320); 2297 { 2298 SkAutoCanvasRestore acr(canvas, true); 2299 canvas->concat(matrix); 2300 paint.setColor(SK_ColorGRAY); 2301 canvas->drawRect(rect, paint); 2302 } 2303 paint.setColor(SK_ColorRED); 2304 for (int j = 0; j < 2; ++j ) { 2305 SkAutoCanvasRestore acr(canvas, true); 2306 matrix.postTranslate(40, 40); 2307 canvas->concat(matrix); 2308 canvas->drawCircle(0, 0, 3, paint); 2309 } 2310 } 2311## 2312 2313#SeeAlso preTranslate setTranslate MakeTrans 2314 2315#Method ## 2316 2317# ------------------------------------------------------------------------------ 2318 2319#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) 2320 2321#Line # post-multiplies Matrix by scale ## 2322Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point 2323(px, py), multiplied by Matrix. 2324This can be thought of as scaling about a pivot point after applying Matrix. 2325 2326Given: 2327 2328#Code 2329#Literal 2330 | J K L | | sx 0 dx | 2331Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy | 2332 | P Q R | | 0 0 1 | 2333## 2334 2335where 2336 2337#Code 2338#Literal 2339dx = px - sx * px 2340dy = py - sy * py 2341## 2342 2343sets Matrix to: 2344 2345#Code 2346#Literal 2347 | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R | 2348S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R | 2349 | 0 0 1 | | P Q R | | P Q R | 2350## 2351 2352#Param sx horizontal scale factor ## 2353#Param sy vertical scale factor ## 2354#Param px pivot x ## 2355#Param py pivot y ## 2356 2357#Example 2358#Image 3 2359SkMatrix matrix; 2360SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2361SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2362matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2363matrix.postScale(.75f, 1.5f, source.width() / 2, source.height() / 2); 2364canvas->concat(matrix); 2365canvas->drawBitmap(source, 0, 0); 2366## 2367 2368#SeeAlso preScale setScale MakeScale 2369 2370## 2371 2372# ------------------------------------------------------------------------------ 2373 2374#Method void postScale(SkScalar sx, SkScalar sy) 2375 2376Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point 2377(0, 0), multiplied by Matrix. 2378This can be thought of as scaling about the origin after applying Matrix. 2379 2380Given: 2381 2382#Code 2383#Literal 2384 | J K L | | sx 0 0 | 2385Matrix = | M N O |, S(sx, sy) = | 0 sy 0 | 2386 | P Q R | | 0 0 1 | 2387## 2388 2389sets Matrix to: 2390 2391#Code 2392#Literal 2393 | sx 0 0 | | J K L | | sx*J sx*K sx*L | 2394S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | 2395 | 0 0 1 | | P Q R | | P Q R | 2396## 2397 2398#Param sx horizontal scale factor ## 2399#Param sy vertical scale factor ## 2400 2401#Example 2402#Image 3 2403SkMatrix matrix; 2404SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2405SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2406matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2407matrix.postScale(.75f, 1.5f); 2408canvas->concat(matrix); 2409canvas->drawBitmap(source, 0, 0); 2410## 2411 2412#SeeAlso preScale setScale MakeScale 2413 2414## 2415 2416# ------------------------------------------------------------------------------ 2417 2418#Method bool postIDiv(int divx, int divy) 2419 2420#Line # post-multiplies Matrix by inverse scale ## 2421Sets Matrix to Matrix constructed from scaling by 2422#Formula 2423(1/divx, 1/divy) 2424## 2425about pivot point (px, py), multiplied by Matrix. 2426 2427Returns false if either divx or divy is zero. 2428 2429Given: 2430 2431#Code 2432#Literal 2433 | J K L | | sx 0 0 | 2434Matrix = | M N O |, I(divx, divy) = | 0 sy 0 | 2435 | P Q R | | 0 0 1 | 2436## 2437 2438where 2439 2440#Code 2441#Literal 2442sx = 1 / divx 2443sy = 1 / divy 2444## 2445 2446sets Matrix to: 2447 2448#Code 2449#Literal 2450 | sx 0 0 | | J K L | | sx*J sx*K sx*L | 2451I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | 2452 | 0 0 1 | | P Q R | | P Q R | 2453## 2454 2455#Param divx integer divisor for inverse scale in x ## 2456#Param divy integer divisor for inverse scale in y ## 2457 2458#Return true on successful scale ## 2459 2460#Example 2461#Image 3 2462SkMatrix matrix, matrix2; 2463SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2464SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2465matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2466matrix.postIDiv(1, 2); 2467canvas->concat(matrix); 2468canvas->drawBitmap(source, 0, 0); 2469## 2470 2471#SeeAlso postScale MakeScale 2472 2473## 2474 2475# ------------------------------------------------------------------------------ 2476 2477#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py) 2478 2479#Line # post-multiplies Matrix by rotation ## 2480Sets Matrix to Matrix constructed from rotating by degrees about pivot point 2481(px, py), multiplied by Matrix. 2482This can be thought of as rotating about a pivot point after applying Matrix. 2483 2484Positive degrees rotates clockwise. 2485 2486Given: 2487 2488#Code 2489#Literal 2490 | J K L | | c -s dx | 2491Matrix = | M N O |, R(degrees, px, py) = | s c dy | 2492 | P Q R | | 0 0 1 | 2493## 2494 2495where 2496 2497#Code 2498#Literal 2499c = cos(degrees) 2500s = sin(degrees) 2501dx = s * py + (1 - c) * px 2502dy = -s * px + (1 - c) * py 2503## 2504 2505sets Matrix to: 2506 2507#Code 2508#Literal 2509 |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R| 2510R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R| 2511 |0 0 1| |P Q R| | P Q R| 2512## 2513 2514#Param degrees angle of axes relative to upright axes ## 2515#Param px pivot x ## 2516#Param py pivot y ## 2517 2518#Example 2519#Image 3 2520SkMatrix matrix; 2521SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2522SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2523matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2524matrix.postRotate(45, source.width() / 2, source.height() / 2); 2525canvas->concat(matrix); 2526canvas->drawBitmap(source, 0, 0); 2527## 2528 2529#SeeAlso preRotate setRotate 2530 2531## 2532 2533# ------------------------------------------------------------------------------ 2534 2535#Method void postRotate(SkScalar degrees) 2536 2537Sets Matrix to Matrix constructed from rotating by degrees about pivot point 2538(0, 0), multiplied by Matrix. 2539This can be thought of as rotating about the origin after applying Matrix. 2540 2541Positive degrees rotates clockwise. 2542 2543Given: 2544 2545#Code 2546#Literal 2547 | J K L | | c -s 0 | 2548Matrix = | M N O |, R(degrees, px, py) = | s c 0 | 2549 | P Q R | | 0 0 1 | 2550## 2551 2552where 2553 2554#Code 2555#Literal 2556c = cos(degrees) 2557s = sin(degrees) 2558## 2559 2560sets Matrix to: 2561 2562#Code 2563#Literal 2564 | c -s dx | | J K L | | cJ-sM cK-sN cL-sO | 2565R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO | 2566 | 0 0 1 | | P Q R | | P Q R | 2567## 2568 2569#Param degrees angle of axes relative to upright axes ## 2570 2571#Example 2572#Image 3 2573SkMatrix matrix; 2574SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2575SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2576matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2577matrix.postRotate(45); 2578canvas->concat(matrix); 2579canvas->drawBitmap(source, 0, 0); 2580## 2581 2582#SeeAlso preRotate setRotate 2583 2584## 2585 2586# ------------------------------------------------------------------------------ 2587 2588#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py) 2589 2590#Line # post-multiplies Matrix by skew ## 2591Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point 2592(px, py), multiplied by Matrix. 2593This can be thought of as skewing about a pivot point after applying Matrix. 2594 2595Given: 2596 2597#Code 2598#Literal 2599 | J K L | | 1 kx dx | 2600Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy | 2601 | P Q R | | 0 0 1 | 2602## 2603 2604where 2605 2606#Code 2607#Literal 2608dx = -kx * py 2609dy = -ky * px 2610## 2611 2612sets Matrix to: 2613 2614#Code 2615#Literal 2616 | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R| 2617K(kx, ky, px, py) * Matrix = |ky 1 dy| |M N O| = |ky*J+M+dy*P ky*K+N+dy*Q ky*L+O+dy*R| 2618 | 0 0 1| |P Q R| | P Q R| 2619## 2620 2621#Param kx horizontal skew factor ## 2622#Param ky vertical skew factor ## 2623#Param px pivot x ## 2624#Param py pivot y ## 2625 2626#Example 2627#Image 3 2628SkMatrix matrix; 2629SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2630SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2631matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2632matrix.postSkew(.5f, 0, source.width() / 2, source.height() / 2); 2633canvas->concat(matrix); 2634canvas->drawBitmap(source, 0, 0); 2635## 2636 2637#SeeAlso preSkew setSkew 2638 2639## 2640 2641# ------------------------------------------------------------------------------ 2642 2643#Method void postSkew(SkScalar kx, SkScalar ky) 2644 2645Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point 2646(0, 0), multiplied by Matrix. 2647This can be thought of as skewing about the origin after applying Matrix. 2648 2649Given: 2650 2651#Code 2652#Literal 2653 | J K L | | 1 kx 0 | 2654Matrix = | M N O |, K(kx, ky) = | ky 1 0 | 2655 | P Q R | | 0 0 1 | 2656## 2657 2658sets Matrix to: 2659 2660#Code 2661#Literal 2662 | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O | 2663K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O | 2664 | 0 0 1 | | P Q R | | P Q R | 2665## 2666 2667#Param kx horizontal skew factor ## 2668#Param ky vertical skew factor ## 2669 2670#Example 2671#Image 3 2672SkMatrix matrix; 2673SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2674SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2675matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2676matrix.postSkew(.5f, 0); 2677canvas->concat(matrix); 2678canvas->drawBitmap(source, 0, 0); 2679## 2680 2681#SeeAlso preSkew setSkew 2682 2683## 2684 2685# ------------------------------------------------------------------------------ 2686 2687#Method void postConcat(const SkMatrix& other) 2688 2689#Line # post-multiplies Matrix by Matrix parameter ## 2690Sets Matrix to Matrix other multiplied by Matrix. 2691This can be thought of mapping by other after applying Matrix. 2692 2693Given: 2694 2695#Code 2696#Literal 2697 | J K L | | A B C | 2698Matrix = | M N O |, other = | D E F | 2699 | P Q R | | G H I | 2700## 2701 2702sets Matrix to: 2703 2704#Code 2705#Literal 2706 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 2707other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 2708 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 2709## 2710 2711#Param other Matrix on left side of multiply expression ## 2712 2713#Example 2714#Image 3 2715#Height 64 2716SkMatrix matrix, matrix2; 2717SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 2718SkRect::Make(source.bounds()).toQuad(bitmapBounds); 2719matrix.setPolyToPoly(bitmapBounds, perspect, 4); 2720matrix.postConcat(matrix); 2721canvas->concat(matrix); 2722canvas->drawBitmap(source, 0, 0); 2723## 2724 2725#SeeAlso preConcat setConcat Concat 2726 2727## 2728 2729# ------------------------------------------------------------------------------ 2730 2731#Enum ScaleToFit 2732 2733#Code 2734 enum ScaleToFit { 2735 kFill_ScaleToFit, 2736 kStart_ScaleToFit, 2737 kCenter_ScaleToFit, 2738 kEnd_ScaleToFit, 2739 }; 2740## 2741 2742ScaleToFit describes how Matrix is constructed to map one Rect to another. 2743ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling, 2744or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies 2745how Matrix maps to the side or center of the destination Rect. 2746 2747#Const kFill_ScaleToFit 0 2748 Computes Matrix that scales in x and y independently, so that source Rect is 2749 mapped to completely fill destination Rect. The aspect ratio of source Rect 2750 may change. 2751## 2752#Const kStart_ScaleToFit 1 2753 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect 2754 width or height to destination Rect. Aligns mapping to left and top edges 2755 of destination Rect. 2756## 2757#Const kCenter_ScaleToFit 2 2758 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect 2759 width or height to destination Rect. Aligns mapping to center of destination 2760 Rect. 2761## 2762#Const kEnd_ScaleToFit 3 2763 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect 2764 width or height to destination Rect. Aligns mapping to right and bottom 2765 edges of destination Rect. 2766## 2767 2768#Example 2769 const char* labels[] = { "Fill", "Start", "Center", "End" }; 2770 SkRect rects[] = {{5, 5, 59, 59}, {5, 74, 59, 108}, {10, 123, 44, 172}, {10, 187, 54, 231}}; 2771 SkRect bounds; 2772 source.getBounds(&bounds); 2773 SkPaint paint; 2774 paint.setAntiAlias(true); 2775 for (auto fit : { SkMatrix::kFill_ScaleToFit, SkMatrix::kStart_ScaleToFit, 2776 SkMatrix::kCenter_ScaleToFit, SkMatrix::kEnd_ScaleToFit } ) { 2777 for (auto rect : rects ) { 2778 canvas->drawRect(rect, paint); 2779 SkMatrix matrix; 2780 if (!matrix.setRectToRect(bounds, rect, fit)) { 2781 continue; 2782 } 2783 SkAutoCanvasRestore acr(canvas, true); 2784 canvas->concat(matrix); 2785 canvas->drawBitmap(source, 0, 0); 2786 } 2787 canvas->drawString(labels[fit], 10, 255, paint); 2788 canvas->translate(64, 0); 2789 } 2790## 2791 2792#SeeAlso setRectToRect MakeRectToRect setPolyToPoly 2793 2794## 2795 2796# ------------------------------------------------------------------------------ 2797 2798#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) 2799 2800#Line # sets to map one Rect to another ## 2801Sets Matrix to scale and translate src Rect to dst Rect. stf selects whether 2802mapping completely fills dst or preserves the aspect ratio, and how to align 2803src within dst. Returns false if src is empty, and sets Matrix to identity. 2804Returns true if dst is empty, and sets Matrix to: 2805 2806#Code 2807#Literal 2808| 0 0 0 | 2809| 0 0 0 | 2810| 0 0 1 | 2811## 2812 2813#Param src Rect to map from ## 2814#Param dst Rect to map to ## 2815#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, 2816 kCenter_ScaleToFit, kEnd_ScaleToFit 2817## 2818 2819#Return true if Matrix can represent Rect mapping ## 2820 2821#Example 2822 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} }; 2823 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} }; 2824 for (auto src : srcs) { 2825 for (auto dst : dsts) { 2826 SkMatrix matrix; 2827 matrix.setAll(-1, -1, -1, -1, -1, -1, -1, -1, -1); 2828 bool success = matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); 2829 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g success: %s\n", 2830 src.fLeft, src.fTop, src.fRight, src.fBottom, 2831 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, success ? "true" : "false"); 2832 matrix.dump(); 2833 } 2834 } 2835#StdOut 2836src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false 2837[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 2838src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false 2839[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 2840src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true 2841[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 2842src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true 2843[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000] 2844## 2845## 2846 2847#SeeAlso MakeRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty 2848 2849## 2850 2851# ------------------------------------------------------------------------------ 2852 2853#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) 2854 2855#Line # constructs from source Rect to destination Rect ## 2856Returns Matrix set to scale and translate src Rect to dst Rect. stf selects 2857whether mapping completely fills dst or preserves the aspect ratio, and how to 2858align src within dst. Returns the identity Matrix if src is empty. If dst is 2859empty, returns Matrix set to: 2860 2861#Code 2862#Literal 2863| 0 0 0 | 2864| 0 0 0 | 2865| 0 0 1 | 2866## 2867 2868#Param src Rect to map from ## 2869#Param dst Rect to map to ## 2870#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, 2871 kCenter_ScaleToFit, kEnd_ScaleToFit 2872## 2873 2874#Return Matrix mapping src to dst ## 2875 2876#Example 2877 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} }; 2878 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} }; 2879 for (auto src : srcs) { 2880 for (auto dst : dsts) { 2881 SkMatrix matrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); 2882 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g\n", 2883 src.fLeft, src.fTop, src.fRight, src.fBottom, 2884 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom); 2885 matrix.dump(); 2886 } 2887 } 2888#StdOut 2889src: 0, 0, 0, 0 dst: 0, 0, 0, 0 2890[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 2891src: 0, 0, 0, 0 dst: 5, 6, 8, 9 2892[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 2893src: 1, 2, 3, 4 dst: 0, 0, 0, 0 2894[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 2895src: 1, 2, 3, 4 dst: 5, 6, 8, 9 2896[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000] 2897## 2898## 2899 2900#SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty 2901 2902## 2903 2904# ------------------------------------------------------------------------------ 2905 2906#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count) 2907 2908#Line # sets to map one to four points to an equal array of points ## 2909Sets Matrix to map src to dst. count must be zero or greater, and four or less. 2910 2911If count is zero, sets Matrix to identity and returns true. 2912If count is one, sets Matrix to translate and returns true. 2913If count is two or more, sets Matrix to map Points if possible; returns false 2914if Matrix cannot be constructed. If count is four, Matrix may include 2915perspective. 2916 2917#Param src Points to map from ## 2918#Param dst Points to map to ## 2919#Param count number of Points in src and dst ## 2920 2921#Return true if Matrix was constructed successfully 2922## 2923 2924#Example 2925 const SkPoint src[] = { { 0, 0}, {30, 0}, {30, -30}, { 0, -30} }; 2926 const SkPoint dst[] = { {50, 0}, {80, -10}, {90, -30}, {60, -40} }; 2927 SkPaint blackPaint; 2928 blackPaint.setAntiAlias(true); 2929 blackPaint.setTextSize(42); 2930 SkPaint redPaint = blackPaint; 2931 redPaint.setColor(SK_ColorRED); 2932 for (int count : { 1, 2, 3, 4 } ) { 2933 canvas->translate(35, 55); 2934 for (int index = 0; index < count; ++index) { 2935 canvas->drawCircle(src[index], 3, blackPaint); 2936 canvas->drawCircle(dst[index], 3, blackPaint); 2937 if (index > 0) { 2938 canvas->drawLine(src[index], src[index - 1], blackPaint); 2939 canvas->drawLine(dst[index], dst[index - 1], blackPaint); 2940 } 2941 } 2942 SkMatrix matrix; 2943 matrix.setPolyToPoly(src, dst, count); 2944 canvas->drawString("A", src[0].fX, src[0].fY, redPaint); 2945 SkAutoCanvasRestore acr(canvas, true); 2946 canvas->concat(matrix); 2947 canvas->drawString("A", src[0].fX, src[0].fY, redPaint); 2948 } 2949## 2950 2951#SeeAlso setRectToRect MakeRectToRect 2952 2953## 2954 2955# ------------------------------------------------------------------------------ 2956 2957#Method bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const 2958 2959#Line # returns inverse, if possible ## 2960Sets inverse to reciprocal matrix, returning true if Matrix can be inverted. 2961Geometrically, if Matrix maps from source to destination, inverse Matrix 2962maps from destination to source. If Matrix can not be inverted, inverse is 2963unchanged. 2964 2965#Param inverse storage for inverted Matrix; may be nullptr ## 2966 2967#Return true if Matrix can be inverted ## 2968 2969#Example 2970#Height 128 2971 const SkPoint src[] = { { 10, 120}, {120, 120}, {120, 10}, { 10, 10} }; 2972 const SkPoint dst[] = { {150, 120}, {200, 100}, {240, 30}, { 130, 40} }; 2973 SkPaint paint; 2974 paint.setAntiAlias(true); 2975 SkMatrix matrix; 2976 matrix.setPolyToPoly(src, dst, 4); 2977 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, src, paint); 2978 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, dst, paint); 2979 paint.setColor(SK_ColorBLUE); 2980 paint.setStrokeWidth(3); 2981 paint.setStrokeCap(SkPaint::kRound_Cap); 2982 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint); 2983 matrix.invert(&matrix); 2984 canvas->concat(matrix); 2985 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint); 2986## 2987 2988#SeeAlso Concat 2989 2990## 2991 2992# ------------------------------------------------------------------------------ 2993 2994#Method static void SetAffineIdentity(SkScalar affine[6]) 2995 2996#Line # sets 3x2 array to identity ## 2997Fills affine with identity values in column major order. 2998Sets affine to: 2999 3000#Code 3001#Literal 3002| 1 0 0 | 3003| 0 1 0 | 3004## 3005 3006Affine 3x2 matrices in column major order are used by OpenGL and XPS. 3007 3008#Param affine storage for 3x2 affine matrix ## 3009 3010#Example 3011 SkScalar affine[6]; 3012 SkMatrix::SetAffineIdentity(affine); 3013 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" }; 3014 for (int i = 0; i < 6; ++i) { 3015 SkDebugf("%s: %g ", names[i], affine[i]); 3016 } 3017 SkDebugf("\n"); 3018#StdOut 3019ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0 3020## 3021## 3022 3023#SeeAlso setAffine asAffine 3024 3025## 3026 3027# ------------------------------------------------------------------------------ 3028 3029#Method bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const 3030 3031#Line # copies to 3x2 array ## 3032Fills affine in column major order. Sets affine to: 3033 3034#Code 3035#Literal 3036| scale-x skew-x translate-x | 3037| skew-y scale-y translate-y | 3038## 3039 3040If Matrix contains perspective, returns false and leaves affine unchanged. 3041 3042#Param affine storage for 3x2 affine matrix; may be nullptr ## 3043 3044#Return true if Matrix does not contain perspective ## 3045 3046#Example 3047SkMatrix matrix; 3048matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1); 3049SkScalar affine[6]; 3050matrix.asAffine(affine); 3051const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" }; 3052for (int i = 0; i < 6; ++i) { 3053 SkDebugf("%s: %g ", names[i], affine[i]); 3054} 3055SkDebugf("\n"); 3056#StdOut 3057ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7 3058## 3059## 3060 3061#SeeAlso setAffine SetAffineIdentity 3062 3063## 3064 3065# ------------------------------------------------------------------------------ 3066 3067#Method void setAffine(const SkScalar affine[6]) 3068 3069#Line # sets left two columns ## 3070Sets Matrix to affine values, passed in column major order. Given affine, 3071column, then row, as: 3072 3073#Code 3074#Literal 3075| scale-x skew-x translate-x | 3076| skew-y scale-y translate-y | 3077## 3078 3079Matrix is set, row, then column, to: 3080 3081#Code 3082#Literal 3083| scale-x skew-x translate-x | 3084| skew-y scale-y translate-y | 3085| 0 0 1 | 3086## 3087 3088#Param affine 3x2 affine matrix ## 3089 3090#Example 3091SkMatrix matrix; 3092matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1); 3093SkScalar affine[6]; 3094matrix.asAffine(affine); 3095const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" }; 3096for (int i = 0; i < 6; ++i) { 3097 SkDebugf("%s: %g ", names[i], affine[i]); 3098} 3099SkDebugf("\n"); 3100matrix.reset(); 3101matrix.setAffine(affine); 3102matrix.dump(); 3103#StdOut 3104ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7 3105[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000] 3106## 3107## 3108 3109#SeeAlso asAffine SetAffineIdentity 3110 3111## 3112 3113# ------------------------------------------------------------------------------ 3114 3115#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const 3116 3117#Line # maps Point array ## 3118Maps src Point array of length count to dst Point array of equal or greater 3119length. Points are mapped by multiplying each Point by Matrix. Given: 3120 3121#Code 3122#Literal 3123 | A B C | | x | 3124Matrix = | D E F |, pt = | y | 3125 | G H I | | 1 | 3126## 3127 3128where 3129 3130#Code 3131#Literal 3132for (i = 0; i < count; ++i) { 3133 x = src[i].fX 3134 y = src[i].fY 3135} 3136## 3137 3138each dst Point is computed as: 3139 3140#Code 3141#Literal 3142 |A B C| |x| Ax+By+C Dx+Ey+F 3143Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 3144 |G H I| |1| Gx+Hy+I Gx+Hy+I 3145## 3146 3147src and dst may point to the same storage. 3148 3149#Param dst storage for mapped Points ## 3150#Param src Points to transform ## 3151#Param count number of Points to transform ## 3152 3153#Example 3154 SkMatrix matrix; 3155 matrix.reset(); 3156 const int count = 4; 3157 SkPoint src[count]; 3158 matrix.mapRectToQuad(src, {40, 70, 180, 220} ); 3159 SkPaint paint; 3160 paint.setARGB(77, 23, 99, 154); 3161 for (int i = 0; i < 5; ++i) { 3162 SkPoint dst[count]; 3163 matrix.mapPoints(dst, src, count); 3164 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, dst, paint); 3165 matrix.preRotate(35, 128, 128); 3166 } 3167## 3168 3169#SeeAlso mapXY mapHomogeneousPoints mapVectors 3170 3171## 3172 3173# ------------------------------------------------------------------------------ 3174 3175#Method void mapPoints(SkPoint pts[], int count) const 3176 3177Maps pts Point array of length count in place. Points are mapped by multiplying 3178each Point by Matrix. Given: 3179 3180#Code 3181#Literal 3182 | A B C | | x | 3183Matrix = | D E F |, pt = | y | 3184 | G H I | | 1 | 3185## 3186 3187where 3188 3189#Code 3190#Literal 3191for (i = 0; i < count; ++i) { 3192 x = pts[i].fX 3193 y = pts[i].fY 3194} 3195## 3196 3197each resulting pts Point is computed as: 3198 3199#Code 3200#Literal 3201 |A B C| |x| Ax+By+C Dx+Ey+F 3202Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 3203 |G H I| |1| Gx+Hy+I Gx+Hy+I 3204## 3205 3206#Param pts storage for mapped Points ## 3207#Param count number of Points to transform ## 3208 3209#Example 3210 SkMatrix matrix; 3211 matrix.setRotate(35, 128, 128); 3212 const int count = 4; 3213 SkPoint pts[count]; 3214 matrix.mapRectToQuad(pts, {40, 70, 180, 220} ); 3215 SkPaint paint; 3216 paint.setARGB(77, 23, 99, 154); 3217 for (int i = 0; i < 5; ++i) { 3218 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, pts, paint); 3219 matrix.mapPoints(pts, count); 3220 } 3221## 3222 3223#SeeAlso mapXY mapHomogeneousPoints mapVectors 3224 3225## 3226 3227# ------------------------------------------------------------------------------ 3228 3229#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const 3230 3231#Line # maps Point3 array ## 3232Maps src Point3 array of length count to dst Point3 array, which must of length count or 3233greater. Point3 array is mapped by multiplying each Point3 by Matrix. Given: 3234 3235#Code 3236#Literal 3237 | A B C | | x | 3238Matrix = | D E F |, src = | y | 3239 | G H I | | z | 3240## 3241 3242each resulting dst Point is computed as: 3243 3244#Code 3245#Literal 3246 |A B C| |x| 3247Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz| 3248 |G H I| |z| 3249## 3250 3251#Param dst storage for mapped Point3 array ## 3252#Param src Point3 array to transform ## 3253#Param count items in Point3 array to transform ## 3254 3255#Example 3256 SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3}, 3257 {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}}; 3258 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 }; 3259 constexpr int count = SK_ARRAY_COUNT(src); 3260 auto debugster = [=](SkPoint3 src[]) -> void { 3261 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) { 3262 const SkPoint3& s = src[lines[i]]; 3263 const SkPoint3& e = src[lines[i + 1]]; 3264 SkPaint paint; 3265 paint.setARGB(77, 23, 99, 154); 3266 canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint); 3267 } 3268 }; 3269 canvas->save(); 3270 canvas->translate(5, 5); 3271 canvas->scale(15, 15); 3272 debugster(src); 3273 canvas->restore(); 3274 canvas->translate(128, 128); 3275 SkMatrix matrix; 3276 matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1); 3277 matrix.mapHomogeneousPoints(src, src, count); 3278 debugster(src); 3279## 3280 3281#SeeAlso mapPoints mapXY mapVectors 3282 3283## 3284 3285# ------------------------------------------------------------------------------ 3286 3287#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const 3288 3289#Line # maps Point ## 3290Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given: 3291 3292#Code 3293#Literal 3294 | A B C | | x | 3295Matrix = | D E F |, pt = | y | 3296 | G H I | | 1 | 3297## 3298 3299result is computed as: 3300 3301#Code 3302#Literal 3303 |A B C| |x| Ax+By+C Dx+Ey+F 3304Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 3305 |G H I| |1| Gx+Hy+I Gx+Hy+I 3306## 3307 3308#Param x x-coordinate of Point to map ## 3309#Param y y-coordinate of Point to map ## 3310#Param result storage for mapped Point ## 3311 3312#Example 3313 SkPaint paint; 3314 paint.setAntiAlias(true); 3315 SkMatrix matrix; 3316 matrix.setRotate(60, 128, 128); 3317 SkPoint lines[] = {{50, 50}, {150, 50}, {150, 150}}; 3318 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); ++i) { 3319 SkPoint pt; 3320 matrix.mapXY(lines[i].fX, lines[i].fY, &pt); 3321 canvas->drawCircle(pt.fX, pt.fY, 3, paint); 3322 } 3323 canvas->concat(matrix); 3324 canvas->drawPoints(SkCanvas::kPolygon_PointMode, SK_ARRAY_COUNT(lines), lines, paint); 3325## 3326 3327#SeeAlso mapPoints mapVectors 3328 3329## 3330 3331# ------------------------------------------------------------------------------ 3332 3333#Method SkPoint mapXY(SkScalar x, SkScalar y) const 3334 3335Returns Point (x, y) multiplied by Matrix. Given: 3336 3337#Code 3338#Literal 3339 | A B C | | x | 3340Matrix = | D E F |, pt = | y | 3341 | G H I | | 1 | 3342## 3343 3344result is computed as: 3345 3346#Code 3347#Literal 3348 |A B C| |x| Ax+By+C Dx+Ey+F 3349Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 3350 |G H I| |1| Gx+Hy+I Gx+Hy+I 3351## 3352 3353#Param x x-coordinate of Point to map ## 3354#Param y y-coordinate of Point to map ## 3355 3356#Return mapped Point ## 3357 3358#Example 3359#Image 4 3360SkMatrix matrix; 3361SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {30, 206}}; 3362SkRect::Make(source.bounds()).toQuad(bitmapBounds); 3363matrix.setPolyToPoly(bitmapBounds, perspect, 4); 3364SkPaint paint; 3365paint.setAntiAlias(true); 3366paint.setStrokeWidth(3); 3367for (int x : { 0, source.width() } ) { 3368 for (int y : { 0, source.height() } ) { 3369 canvas->drawPoint(matrix.mapXY(x, y), paint); 3370 } 3371} 3372canvas->concat(matrix); 3373canvas->drawBitmap(source, 0, 0); 3374## 3375 3376#SeeAlso mapPoints mapVectors 3377 3378## 3379 3380# ------------------------------------------------------------------------------ 3381 3382#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const 3383 3384#Line # maps Vector array ## 3385Maps src Vector array of length count to Vector Point array of equal or greater 3386length. Vectors are mapped by multiplying each Vector by Matrix, treating 3387Matrix translation as zero. Given: 3388 3389#Code 3390#Literal 3391 | A B 0 | | x | 3392Matrix = | D E 0 |, src = | y | 3393 | G H I | | 1 | 3394## 3395 3396where 3397 3398#Code 3399#Literal 3400for (i = 0; i < count; ++i) { 3401 x = src[i].fX 3402 y = src[i].fY 3403} 3404## 3405 3406each dst Vector is computed as: 3407 3408#Code 3409#Literal 3410 |A B 0| |x| Ax+By Dx+Ey 3411Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , ------- 3412 |G H I| |1| Gx+Hy+I Gx+Hy+I 3413## 3414 3415src and dst may point to the same storage. 3416 3417#Param dst storage for mapped Vectors ## 3418#Param src Vectors to transform ## 3419#Param count number of Vectors to transform ## 3420 3421#Example 3422 SkPaint paint; 3423 paint.setAntiAlias(true); 3424 paint.setStyle(SkPaint::kStroke_Style); 3425 SkMatrix matrix; 3426 matrix.reset(); 3427 const SkVector radii[] = {{8, 4}, {9, 1}, {6, 2}, {7, 3}}; 3428 for (int i = 0; i < 4; ++i) { 3429 SkVector rScaled[4]; 3430 matrix.preScale(1.5f, 2.f); 3431 matrix.mapVectors(rScaled, radii, SK_ARRAY_COUNT(radii)); 3432 SkRRect rrect; 3433 rrect.setRectRadii({20, 20, 180, 70}, rScaled); 3434 canvas->drawRRect(rrect, paint); 3435 canvas->translate(0, 60); 3436 } 3437## 3438 3439#SeeAlso mapVector mapPoints mapXY 3440 3441## 3442 3443# ------------------------------------------------------------------------------ 3444 3445#Method void mapVectors(SkVector vecs[], int count) const 3446 3447Maps vecs Vector array of length count in place, multiplying each Vector by 3448Matrix, treating Matrix translation as zero. Given: 3449 3450#Code 3451#Literal 3452 | A B 0 | | x | 3453Matrix = | D E 0 |, vec = | y | 3454 | G H I | | 1 | 3455## 3456 3457where 3458 3459#Code 3460#Literal 3461for (i = 0; i < count; ++i) { 3462 x = vecs[i].fX 3463 y = vecs[i].fY 3464} 3465## 3466 3467each result Vector is computed as: 3468 3469#Code 3470#Literal 3471 |A B 0| |x| Ax+By Dx+Ey 3472Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , ------- 3473 |G H I| |1| Gx+Hy+I Gx+Hy+I 3474## 3475 3476#Param vecs Vectors to transform, and storage for mapped Vectors ## 3477#Param count number of Vectors to transform ## 3478 3479#Example 3480 SkPaint paint; 3481 paint.setAntiAlias(true); 3482 paint.setStyle(SkPaint::kStroke_Style); 3483 SkMatrix matrix; 3484 matrix.setScale(2, 3); 3485 SkVector radii[] = {{7, 7}, {3, 3}, {2, 2}, {4, 0}}; 3486 for (int i = 0; i < 4; ++i) { 3487 SkRRect rrect; 3488 rrect.setRectRadii({20, 20, 180, 70}, radii); 3489 canvas->drawRRect(rrect, paint); 3490 canvas->translate(0, 60); 3491 matrix.mapVectors(radii, SK_ARRAY_COUNT(radii)); 3492 } 3493## 3494 3495#SeeAlso mapVector mapPoints mapXY 3496 3497## 3498 3499# ------------------------------------------------------------------------------ 3500 3501#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const 3502 3503#Line # maps Vector ## 3504Maps Vector (x, y) to result. Vector is mapped by multiplying by Matrix, 3505treating Matrix translation as zero. Given: 3506 3507#Code 3508#Literal 3509 | A B 0 | | dx | 3510Matrix = | D E 0 |, vec = | dy | 3511 | G H I | | 1 | 3512## 3513 3514each result Vector is computed as: 3515 3516#Code 3517#Literal 3518#Outdent 3519 |A B 0| |dx| A*dx+B*dy D*dx+E*dy 3520Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , ----------- 3521 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I 3522## 3523 3524#Param dx x-coordinate of Vector to map ## 3525#Param dy y-coordinate of Vector to map ## 3526#Param result storage for mapped Vector ## 3527 3528#Example 3529 SkPaint paint; 3530 paint.setColor(SK_ColorGREEN); 3531 paint.setAntiAlias(true); 3532 paint.setTextSize(48); 3533 SkMatrix matrix; 3534 matrix.setRotate(90); 3535 SkVector offset = { 7, 7 }; 3536 for (int i = 0; i < 4; ++i) { 3537 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3, 3538 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr)); 3539 matrix.mapVector(offset.fX, offset.fY, &offset); 3540 canvas->translate(0, 60); 3541 canvas->drawString("Text", 50, 0, paint); 3542 } 3543## 3544 3545#SeeAlso mapVectors mapPoints mapXY 3546 3547## 3548 3549# ------------------------------------------------------------------------------ 3550 3551#Method SkVector mapVector(SkScalar dx, SkScalar dy) const 3552 3553Returns Vector (x, y) multiplied by Matrix, treating Matrix translation as zero. 3554Given: 3555 3556#Code 3557#Literal 3558 | A B 0 | | dx | 3559Matrix = | D E 0 |, vec = | dy | 3560 | G H I | | 1 | 3561## 3562 3563each result Vector is computed as: 3564 3565#Code 3566#Literal 3567#Outdent 3568 |A B 0| |dx| A*dx+B*dy D*dx+E*dy 3569Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , ----------- 3570 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I 3571## 3572 3573#Param dx x-coordinate of Vector to map ## 3574#Param dy y-coordinate of Vector to map ## 3575 3576#Return mapped Vector ## 3577 3578#Example 3579 SkPaint paint; 3580 paint.setColor(SK_ColorGREEN); 3581 paint.setAntiAlias(true); 3582 paint.setTextSize(48); 3583 SkMatrix matrix; 3584 matrix.setRotate(90); 3585 SkVector offset = { 7, 7 }; 3586 for (int i = 0; i < 4; ++i) { 3587 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3, 3588 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr)); 3589 offset = matrix.mapVector(offset.fX, offset.fY); 3590 canvas->translate(0, 60); 3591 canvas->drawString("Text", 50, 0, paint); 3592 } 3593## 3594 3595#SeeAlso mapVectors mapPoints mapXY 3596 3597## 3598 3599# ------------------------------------------------------------------------------ 3600 3601#Method bool mapRect(SkRect* dst, const SkRect& src) const 3602 3603#Line # returns bounds of mapped Rect ## 3604Sets dst to bounds of src corners mapped by Matrix. 3605Returns true if mapped corners are dst corners. 3606 3607Returned value is the same as calling rectStaysRect. 3608 3609#Param dst storage for bounds of mapped Points ## 3610#Param src Rect to map ## 3611 3612#Return true if dst is equivalent to mapped src ## 3613 3614#Example 3615 SkPaint paint; 3616 paint.setAntiAlias(true); 3617 SkMatrix matrix; 3618 matrix.setRotate(45, 128, 128); 3619 SkRect rotatedBounds, bounds = {40, 50, 190, 200}; 3620 matrix.mapRect(&rotatedBounds, bounds ); 3621 paint.setColor(SK_ColorGRAY); 3622 canvas->drawRect(rotatedBounds, paint); 3623 canvas->concat(matrix); 3624 paint.setColor(SK_ColorRED); 3625 canvas->drawRect(bounds, paint); 3626## 3627 3628#SeeAlso mapPoints rectStaysRect 3629 3630## 3631 3632# ------------------------------------------------------------------------------ 3633 3634#Method bool mapRect(SkRect* rect) const 3635 3636Sets rect to bounds of rect corners mapped by Matrix. 3637Returns true if mapped corners are computed rect corners. 3638 3639Returned value is the same as calling rectStaysRect. 3640 3641#Param rect rectangle to map, and storage for bounds of mapped corners ## 3642 3643#Return true if result is equivalent to mapped src ## 3644 3645#Example 3646 SkPaint paint; 3647 paint.setAntiAlias(true); 3648 SkMatrix matrix; 3649 matrix.setRotate(45, 128, 128); 3650 SkRect bounds = {40, 50, 190, 200}; 3651 matrix.mapRect(&bounds); 3652 paint.setColor(SK_ColorGRAY); 3653 canvas->drawRect(bounds, paint); 3654 canvas->concat(matrix); 3655 paint.setColor(SK_ColorRED); 3656 canvas->drawRect({40, 50, 190, 200}, paint); 3657## 3658 3659#SeeAlso mapRectScaleTranslate mapPoints rectStaysRect 3660 3661## 3662 3663# ------------------------------------------------------------------------------ 3664 3665#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const 3666 3667#Line # maps Rect to Point array ## 3668Maps four corners of rect to dst. Points are mapped by multiplying each 3669rect corner by Matrix. rect corner is processed in this order: 3670(rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), 3671(rect.fLeft, rect.fBottom). 3672 3673rect may be empty: rect.fLeft may be greater than or equal to rect.fRight; 3674rect.fTop may be greater than or equal to rect.fBottom. 3675 3676Given: 3677 3678#Code 3679#Literal 3680 | A B C | | x | 3681Matrix = | D E F |, pt = | y | 3682 | G H I | | 1 | 3683## 3684 3685where pt is initialized from each of (rect.fLeft, rect.fTop), 3686(rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom), 3687each dst Point is computed as: 3688 3689#Code 3690#Literal 3691 |A B C| |x| Ax+By+C Dx+Ey+F 3692Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 3693 |G H I| |1| Gx+Hy+I Gx+Hy+I 3694## 3695 3696#Param dst storage for mapped corner Points ## 3697#Param rect Rect to map ## 3698 3699#Example 3700#Height 192 3701 SkPaint paint; 3702 paint.setAntiAlias(true); 3703 SkMatrix matrix; 3704 matrix.setRotate(60, 128, 128); 3705 SkRect rect = {50, 50, 150, 150}; 3706 SkPoint pts[4]; 3707 matrix.mapRectToQuad(pts, rect); 3708 for (int i = 0; i < 4; ++i) { 3709 canvas->drawCircle(pts[i].fX, pts[i].fY, 3, paint); 3710 } 3711 canvas->concat(matrix); 3712 paint.setStyle(SkPaint::kStroke_Style); 3713 canvas->drawRect(rect, paint); 3714## 3715 3716#SeeAlso mapRect mapRectScaleTranslate 3717 3718## 3719 3720# ------------------------------------------------------------------------------ 3721 3722#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const 3723 3724#Line # returns bounds of mapped Rect ## 3725Sets dst to bounds of src corners mapped by Matrix. If matrix contains 3726elements other than scale or translate: asserts if SK_DEBUG is defined; 3727otherwise, results are undefined. 3728 3729#Param dst storage for bounds of mapped Points ## 3730#Param src Rect to map ## 3731 3732#Example 3733 SkPaint paint; 3734 SkMatrix matrix; 3735 SkRect rect = {100, 50, 150, 180}; 3736 matrix.setScale(2, .5f, rect.centerX(), rect.centerY()); 3737 SkRect rotated; 3738 matrix.mapRectScaleTranslate(&rotated, rect); 3739 paint.setStyle(SkPaint::kStroke_Style); 3740 canvas->drawRect(rect, paint); 3741 paint.setColor(SK_ColorRED); 3742 canvas->drawRect(rotated, paint); 3743## 3744 3745#SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect 3746 3747## 3748 3749# ------------------------------------------------------------------------------ 3750 3751#Method SkScalar mapRadius(SkScalar radius) const 3752 3753#Line # returns mean radius of mapped Circle ## 3754Returns geometric mean radius of ellipse formed by constructing Circle of 3755size radius, and mapping constructed Circle with Matrix. The result squared is 3756equal to the major axis length times the minor axis length. 3757Result is not meaningful if Matrix contains perspective elements. 3758 3759#Param radius Circle size to map ## 3760 3761#Return average mapped radius ## 3762 3763#Example 3764#Description 3765The area enclosed by a square with sides equal to mappedRadius is the same as 3766the area enclosed by the ellipse major and minor axes. 3767## 3768 SkPaint paint; 3769 paint.setAntiAlias(true); 3770 SkMatrix matrix; 3771 const SkPoint center = {108, 93}; 3772 matrix.setScale(2, .5f, center.fX, center.fY); 3773 matrix.postRotate(45, center.fX, center.fY); 3774 const SkScalar circleRadius = 50; 3775 SkScalar mappedRadius = matrix.mapRadius(circleRadius); 3776 SkVector minorAxis, majorAxis; 3777 matrix.mapVector(0, circleRadius, &minorAxis); 3778 matrix.mapVector(circleRadius, 0, &majorAxis); 3779 SkString mappedArea; 3780 mappedArea.printf("area = %g", mappedRadius * mappedRadius); 3781 canvas->drawString(mappedArea, 145, 250, paint); 3782 canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint); 3783 paint.setColor(SK_ColorRED); 3784 SkString axArea; 3785 axArea.printf("area = %g", majorAxis.length() * minorAxis.length()); 3786 paint.setStyle(SkPaint::kFill_Style); 3787 canvas->drawString(axArea, 15, 250, paint); 3788 paint.setStyle(SkPaint::kStroke_Style); 3789 canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint); 3790 paint.setColor(SK_ColorBLACK); 3791 canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint); 3792 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint); 3793 canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint); 3794 canvas->concat(matrix); 3795 canvas->drawCircle(center.fX, center.fY, circleRadius, paint); 3796 paint.setColor(SK_ColorRED); 3797 canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint); 3798 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint); 3799## 3800 3801#SeeAlso mapVector 3802 3803## 3804 3805# ------------------------------------------------------------------------------ 3806 3807#Method bool isFixedStepInX() const 3808 3809#Line # returns if transformation supports fixed step in x ## 3810Returns true if a unit step in x at some y mapped through Matrix can be 3811represented by a constant Vector. Returns true if getType returns kIdentity_Mask, 3812or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask. 3813 3814May return true if getType returns kPerspective_Mask, but only when Matrix 3815does not include rotation or skewing along the y-axis. 3816 3817#Return true if Matrix does not have complex perspective ## 3818 3819#Example 3820 SkMatrix matrix; 3821 for (SkScalar px : { 0.0f, 0.1f } ) { 3822 for (SkScalar py : { 0.0f, 0.1f } ) { 3823 for (SkScalar sy : { 1, 2 } ) { 3824 matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1); 3825 matrix.dump(); 3826 SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false"); 3827 } 3828 } 3829 } 3830#StdOut 3831[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 3832isFixedStepInX: true 3833[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000] 3834isFixedStepInX: true 3835[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000] 3836isFixedStepInX: true 3837[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000] 3838isFixedStepInX: true 3839[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000] 3840isFixedStepInX: false 3841[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000] 3842isFixedStepInX: false 3843[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000] 3844isFixedStepInX: false 3845[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000] 3846isFixedStepInX: false 3847## 3848## 3849 3850#SeeAlso fixedStepInX getType 3851 3852## 3853 3854# ------------------------------------------------------------------------------ 3855 3856#Method SkVector fixedStepInX(SkScalar y) const 3857 3858#Line # returns step in x for a position in y ## 3859Returns Vector representing a unit step in x at y mapped through Matrix. 3860If isFixedStepInX is false, returned value is undefined. 3861 3862#Param y position of line parallel to x-axis ## 3863 3864#Return Vector advance of mapped unit step in x ## 3865 3866#Example 3867#Image 3 3868 SkMatrix matrix; 3869 const SkPoint center = { 128, 128 }; 3870 matrix.setScale(20, 25, center.fX, center.fY); 3871 matrix.postRotate(75, center.fX, center.fY); 3872 { 3873 SkAutoCanvasRestore acr(canvas, true); 3874 canvas->concat(matrix); 3875 canvas->drawBitmap(source, 0, 0); 3876 } 3877 if (matrix.isFixedStepInX()) { 3878 SkPaint paint; 3879 paint.setAntiAlias(true); 3880 SkVector step = matrix.fixedStepInX(128); 3881 SkVector end = center + step; 3882 canvas->drawLine(center, end, paint); 3883 SkVector arrow = { step.fX + step.fY, step.fY - step.fX}; 3884 arrow = arrow * .25f; 3885 canvas->drawLine(end, end - arrow, paint); 3886 canvas->drawLine(end, {end.fX + arrow.fY, end.fY - arrow.fX}, paint); 3887 } 3888## 3889 3890#SeeAlso isFixedStepInX getType 3891 3892## 3893 3894# ------------------------------------------------------------------------------ 3895 3896#Method bool cheapEqualTo(const SkMatrix& m) const 3897 3898#Line # compares Matrix pair using memcmp() ## 3899Returns true if Matrix equals m, using an efficient comparison. 3900 3901Returns false when the sign of zero values is the different; when one 3902matrix has positive zero value and the other has negative zero value. 3903 3904Returns true even when both Matrices contain NaN. 3905 3906NaN never equals any value, including itself. To improve performance, NaN values 3907are treated as bit patterns that are equal if their bit patterns are equal. 3908 3909#Param m Matrix to compare ## 3910 3911#Return true if m and Matrix are represented by identical bit patterns ## 3912 3913#Example 3914 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void { 3915 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix, 3916 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false"); 3917 }; 3918 SkMatrix a, b; 3919 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 3920 b.setIdentity(); 3921 debugster("identity", a, b); 3922 a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1); 3923 debugster("neg zero", a, b); 3924 a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1); 3925 debugster(" one NaN", a, b); 3926 b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1); 3927 debugster("both NaN", a, b); 3928#StdOut 3929identity: a == b a.cheapEqualTo(b): true 3930neg zero: a == b a.cheapEqualTo(b): false 3931 one NaN: a != b a.cheapEqualTo(b): false 3932both NaN: a != b a.cheapEqualTo(b): true 3933## 3934## 3935 3936#SeeAlso operator==(const SkMatrix& a, const SkMatrix& b) 3937 3938## 3939 3940# ------------------------------------------------------------------------------ 3941 3942#Method bool operator==(const SkMatrix& a, const SkMatrix& b) 3943 3944#Line # returns true if members are equal ## 3945Compares a and b; returns true if a and b are numerically equal. Returns true 3946even if sign of zero values are different. Returns false if either Matrix 3947contains NaN, even if the other Matrix also contains NaN. 3948 3949#Param a Matrix to compare ## 3950#Param b Matrix to compare ## 3951 3952#Return true if m and Matrix are numerically equal ## 3953 3954#Example 3955 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void { 3956 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix, 3957 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false"); 3958 }; 3959 SkMatrix a, b; 3960 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1); 3961 b.setScale(2, 4); 3962 b.postScale(0.5f, 0.25f); 3963 debugster("identity", a, b); 3964#StdOut 3965identity: a == b a.cheapEqualTo(b): true 3966## 3967## 3968 3969#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b) 3970 3971## 3972 3973# ------------------------------------------------------------------------------ 3974 3975#Method bool operator!=(const SkMatrix& a, const SkMatrix& b) 3976 3977#Line # returns true if members are unequal ## 3978Compares a and b; returns true if a and b are not numerically equal. Returns false 3979even if sign of zero values are different. Returns true if either Matrix 3980contains NaN, even if the other Matrix also contains NaN. 3981 3982#Param a Matrix to compare ## 3983#Param b Matrix to compare ## 3984 3985#Return true if m and Matrix are numerically not equal ## 3986 3987#Example 3988 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void { 3989 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix, 3990 a != b ? '!' : '=', a.cheapEqualTo(b) ? "true" : "false"); 3991 }; 3992 SkMatrix a, b; 3993 a.setAll(1, 0, 0, 0, 1, 0, 1, 0, 1); 3994 a.invert(&b); 3995 debugster("identity", a, b); 3996## 3997 3998#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b) 3999 4000## 4001 4002# ------------------------------------------------------------------------------ 4003 4004#Method void dump() const 4005 4006#Line # sends text representation using floats to standard output ## 4007Writes text representation of Matrix to standard output. Floating point values 4008are written with limited precision; it may not be possible to reconstruct 4009original Matrix from output. 4010 4011#Example 4012 SkMatrix matrix; 4013 matrix.setRotate(45); 4014 matrix.dump(); 4015 SkMatrix nearlyEqual; 4016 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1); 4017 nearlyEqual.dump(); 4018 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!'); 4019#StdOut 4020[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000] 4021[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000] 4022matrix != nearlyEqual 4023## 4024## 4025 4026#SeeAlso toString 4027 4028## 4029 4030# ------------------------------------------------------------------------------ 4031 4032#Method void toString(SkString* str) const 4033 4034#Line # converts Matrix to machine readable form ## 4035Creates string representation of Matrix. Floating point values 4036are written with limited precision; it may not be possible to reconstruct 4037original Matrix from output. 4038 4039#Param str storage for string representation of Matrix ## 4040 4041#Example 4042 SkMatrix matrix; 4043 matrix.setRotate(45); 4044 SkString mStr, neStr; 4045 matrix.toString(&mStr); 4046 SkMatrix nearlyEqual; 4047 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1); 4048 nearlyEqual.toString(&neStr); 4049 SkDebugf("mStr %s\n", mStr.c_str()); 4050 SkDebugf("neStr %s\n", neStr.c_str()); 4051 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!'); 4052#StdOut 4053mStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000] 4054neStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000] 4055matrix != nearlyEqual 4056## 4057## 4058 4059#SeeAlso dump 4060 4061## 4062 4063# ------------------------------------------------------------------------------ 4064 4065#Method SkScalar getMinScale() const 4066 4067#Line # returns minimum scaling, if possible ## 4068Returns the minimum scaling factor of Matrix by decomposing the scaling and 4069skewing elements. 4070Returns -1 if scale factor overflows or Matrix contains perspective. 4071 4072#Return minimum scale factor 4073## 4074 4075#Example 4076 SkMatrix matrix; 4077 matrix.setScale(42, 24); 4078 SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale()); 4079#StdOut 4080matrix.getMinScale() 24 4081## 4082## 4083 4084#SeeAlso getMaxScale getMinMaxScales 4085 4086## 4087 4088# ------------------------------------------------------------------------------ 4089 4090#Method SkScalar getMaxScale() const 4091 4092#Line # returns maximum scaling, if possible ## 4093Returns the maximum scaling factor of Matrix by decomposing the scaling and 4094skewing elements. 4095Returns -1 if scale factor overflows or Matrix contains perspective. 4096 4097#Return maximum scale factor 4098## 4099 4100#Example 4101 SkMatrix matrix; 4102 matrix.setScale(42, 24); 4103 SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale()); 4104#StdOut 4105matrix.getMaxScale() 42 4106## 4107## 4108 4109#SeeAlso getMinScale getMinMaxScales 4110 4111## 4112 4113# ------------------------------------------------------------------------------ 4114 4115#Method bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const 4116 4117#Line # returns minimum and maximum scaling, if possible ## 4118Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the 4119maximum scaling factor. Scaling factors are computed by decomposing 4120the Matrix scaling and skewing elements. 4121 4122Returns true if scaleFactors are found; otherwise, returns false and sets 4123scaleFactors to undefined values. 4124 4125#Param scaleFactors storage for minimum and maximum scale factors ## 4126 4127#Return true if scale factors were computed correctly ## 4128 4129#Example 4130 SkMatrix matrix; 4131 matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0); 4132 matrix.invert(&matrix); 4133 SkScalar factor[2] = {2, 2}; 4134 bool result = matrix.getMinMaxScales(factor); 4135 SkDebugf("matrix.getMinMaxScales() %s %g %g\n", result ? "true" : "false", factor[0], factor[1]); 4136#StdOut 4137matrix.getMinMaxScales() false 2 2 4138## 4139## 4140 4141#SeeAlso getMinScale getMaxScale 4142 4143## 4144 4145# ------------------------------------------------------------------------------ 4146 4147#Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const 4148 4149#Line # separates scale if possible ## 4150Decomposes Matrix into scale components and whatever remains. Returns false if 4151Matrix could not be decomposed. 4152 4153Sets scale to portion of Matrix that scales in x and y. Sets remaining to Matrix 4154with x and y scaling factored out. remaining may be passed as nullptr 4155to determine if Matrix can be decomposed without computing remainder. 4156 4157Returns true if scale components are found. scale and remaining are 4158unchanged if Matrix contains perspective; scale factors are not finite, or 4159are nearly zero. 4160 4161On success 4162 4163#Formula 4164Matrix = scale * Remaining 4165## 4166 4167#Param scale x and y scaling factors; may be nullptr ## 4168#Param remaining Matrix without scaling; may be nullptr ## 4169 4170#Return true if scale can be computed ## 4171 4172#Example 4173 SkMatrix matrix; 4174 matrix.setRotate(90 * SK_Scalar1); 4175 matrix.postScale(1.f / 4, 1.f / 2); 4176 matrix.dump(); 4177 SkSize scale = {SK_ScalarNaN, SK_ScalarNaN}; 4178 SkMatrix remaining; 4179 remaining.reset(); 4180 bool success = matrix.decomposeScale(&scale, &remaining); 4181 SkDebugf("success: %s ", success ? "true" : "false"); 4182 SkDebugf("scale: %g, %g\n", scale.width(), scale.height()); 4183 remaining.dump(); 4184 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height()); 4185 SkMatrix combined = SkMatrix::Concat(scaleMatrix, remaining); 4186 combined.dump(); 4187#StdOut 4188[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 4189success: true scale: 0.5, 0.25 4190[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 4191[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000] 4192## 4193## 4194 4195#SeeAlso setScale MakeScale 4196 4197## 4198 4199# ------------------------------------------------------------------------------ 4200 4201#Method static const SkMatrix& I() 4202 4203#Line # returns a reference to a const identity Matrix ## 4204Returns reference to const identity Matrix. Returned Matrix is set to: 4205 4206#Code 4207#Literal 4208| 1 0 0 | 4209| 0 1 0 | 4210| 0 0 1 | 4211## 4212 4213#Return const identity Matrix ## 4214 4215#Example 4216 SkMatrix m1, m2, m3; 4217 m1.reset(); 4218 m2.setIdentity(); 4219 m3 = SkMatrix::I(); 4220 SkDebugf("m1 %c= m2\n", m1 == m2 ? '=' : '!'); 4221 SkDebugf("m2 %c= m3\n", m1 == m2 ? '=' : '!'); 4222#StdOut 4223m1 == m2 4224m2 == m3 4225## 4226## 4227 4228#SeeAlso reset() setIdentity 4229 4230## 4231 4232# ------------------------------------------------------------------------------ 4233 4234#Method static const SkMatrix& InvalidMatrix() 4235 4236#Line # returns a reference to a const invalid Matrix ## 4237Returns reference to a const Matrix with invalid values. Returned Matrix is set 4238to: 4239 4240#Code 4241#Literal 4242| SK_ScalarMax SK_ScalarMax SK_ScalarMax | 4243| SK_ScalarMax SK_ScalarMax SK_ScalarMax | 4244| SK_ScalarMax SK_ScalarMax SK_ScalarMax | 4245## 4246 4247#Return const invalid Matrix ## 4248 4249#Example 4250 SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX()); 4251#StdOut 4252scaleX 3.40282e+38 4253## 4254## 4255 4256#SeeAlso SeeAlso getType 4257 4258## 4259 4260# ------------------------------------------------------------------------------ 4261 4262#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) 4263 4264#Line # returns the concatenation of Matrix pair ## 4265Returns Matrix a multiplied by Matrix b. 4266 4267Given: 4268 4269#Code 4270#Literal 4271 | A B C | | J K L | 4272a = | D E F |, b = | M N O | 4273 | G H I | | P Q R | 4274## 4275 4276sets Matrix to: 4277 4278#Code 4279#Literal 4280 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 4281a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 4282 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 4283## 4284 4285#Param a Matrix on left side of multiply expression ## 4286#Param b Matrix on right side of multiply expression ## 4287 4288#Return Matrix computed from a times b ## 4289 4290#Example 4291#Height 64 4292#Image 4 4293#Description 4294setPolyToPoly creates perspective matrices, one the inverse of the other. 4295Multiplying the matrix by its inverse turns into an identity matrix. 4296## 4297SkMatrix matrix, matrix2; 4298SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}}; 4299SkRect::Make(source.bounds()).toQuad(bitmapBounds); 4300matrix.setPolyToPoly(bitmapBounds, perspect, 4); 4301matrix2.setPolyToPoly(perspect, bitmapBounds, 4); 4302SkMatrix concat = SkMatrix::Concat(matrix, matrix2); 4303canvas->concat(concat); 4304canvas->drawBitmap(source, 0, 0); 4305## 4306 4307#SeeAlso preConcat postConcat 4308 4309## 4310 4311# ------------------------------------------------------------------------------ 4312 4313#Method void dirtyMatrixTypeCache() 4314 4315#Line # sets internal cache to unknown state ## 4316Sets internal cache to unknown state. Use to force update after repeated 4317modifications to Matrix element reference returned by operator[](int index). 4318 4319#Example 4320SkMatrix matrix; 4321matrix.setIdentity(); 4322SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX); 4323SkScalar& skewRef = matrix[SkMatrix::kMSkewX]; 4324skewRef = 0; 4325SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 4326skewRef = 1; 4327SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX); 4328matrix.dirtyMatrixTypeCache(); 4329SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX); 4330#StdOut 4331with identity matrix: x = 24 4332after skew x mod: x = 24 4333after 2nd skew x mod: x = 24 4334after dirty cache: x = 66 4335## 4336## 4337 4338#SeeAlso operator[](int index) getType 4339 4340## 4341 4342# ------------------------------------------------------------------------------ 4343 4344#Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) 4345 4346#Line # sets to scale and translate ## 4347Initializes Matrix with scale and translate elements. 4348 4349#Code 4350#Literal 4351| sx 0 tx | 4352| 0 sy ty | 4353| 0 0 1 | 4354## 4355 4356#Param sx horizontal scale factor to store ## 4357#Param sy vertical scale factor to store ## 4358#Param tx horizontal translation to store ## 4359#Param ty vertical translation to store ## 4360 4361#Example 4362SkMatrix matrix; 4363matrix.setScaleTranslate(1, 2, 3, 4); 4364matrix.dump(); 4365#StdOut 4366[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000] 4367## 4368## 4369 4370#SeeAlso setScale preTranslate postTranslate 4371 4372## 4373 4374# ------------------------------------------------------------------------------ 4375 4376#Method bool isFinite() const 4377 4378#Line # returns if all Matrix values are not infinity, NaN ## 4379Returns true if all elements of the matrix are finite. Returns false if any 4380element is infinity, or NaN. 4381 4382#Return true if matrix has only finite elements ## 4383 4384#Example 4385SkMatrix matrix = SkMatrix::MakeTrans(SK_ScalarNaN, 0); 4386matrix.dump(); 4387SkDebugf("matrix is finite: %s\n", matrix.isFinite() ? "true" : "false"); 4388SkDebugf("matrix %c= matrix\n", matrix == matrix ? '=' : '!'); 4389#StdOut 4390[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000] 4391matrix is finite: false 4392matrix != matrix 4393## 4394## 4395 4396#SeeAlso operator== 4397 4398## 4399 4400#Class SkMatrix ## 4401 4402#Topic Matrix ## 4403