1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 /* Generated by tools/bookmaker from include/core/SkMatrix.h and docs/SkMatrix_Reference.bmh 9 on 2018-09-13 13:59:55. Additional documentation and examples can be found at: 10 https://skia.org/user/api/SkMatrix_Reference 11 12 You may edit either file directly. Structural changes to public interfaces require 13 editing both files. After editing docs/SkMatrix_Reference.bmh, run: 14 bookmaker -b docs -i include/core/SkMatrix.h -p 15 to create an updated version of this file. 16 */ 17 18 #ifndef SkMatrix_DEFINED 19 #define SkMatrix_DEFINED 20 21 #include "../private/SkMacros.h" 22 #include "../private/SkTo.h" 23 #include "SkRect.h" 24 25 struct SkRSXform; 26 struct SkPoint3; 27 class SkString; 28 29 /** \class SkMatrix 30 SkMatrix holds a 3x3 matrix for transforming coordinates. This allows mapping 31 SkPoint and vectors with translation, scaling, skewing, rotation, and 32 perspective. 33 34 SkMatrix elements are in row major order. SkMatrix does not have a constructor, 35 so it must be explicitly initialized. setIdentity() initializes SkMatrix 36 so it has no effect. setTranslate(), setScale(), setSkew(), setRotate(), set9 and setAll() 37 initializes all SkMatrix elements with the corresponding mapping. 38 39 SkMatrix includes a hidden variable that classifies the type of matrix to 40 improve performance. SkMatrix is not thread safe unless getType() is called first. 41 */ 42 SK_BEGIN_REQUIRE_DENSE 43 class SK_API SkMatrix { 44 public: 45 46 /** Sets SkMatrix to scale by (sx, sy). Returned matrix is: 47 48 | sx 0 0 | 49 | 0 sy 0 | 50 | 0 0 1 | 51 52 @param sx horizontal scale factor 53 @param sy vertical scale factor 54 @return SkMatrix with scale 55 */ MakeScale(SkScalar sx,SkScalar sy)56 static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) { 57 SkMatrix m; 58 m.setScale(sx, sy); 59 return m; 60 } 61 62 /** Sets SkMatrix to scale by (scale, scale). Returned matrix is: 63 64 | scale 0 0 | 65 | 0 scale 0 | 66 | 0 0 1 | 67 68 @param scale horizontal and vertical scale factor 69 @return SkMatrix with scale 70 */ MakeScale(SkScalar scale)71 static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) { 72 SkMatrix m; 73 m.setScale(scale, scale); 74 return m; 75 } 76 77 /** Sets SkMatrix to translate by (dx, dy). Returned matrix is: 78 79 | 1 0 dx | 80 | 0 1 dy | 81 | 0 0 1 | 82 83 @param dx horizontal translation 84 @param dy vertical translation 85 @return SkMatrix with translation 86 */ MakeTrans(SkScalar dx,SkScalar dy)87 static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) { 88 SkMatrix m; 89 m.setTranslate(dx, dy); 90 return m; 91 } 92 93 /** Sets SkMatrix to: 94 95 | scaleX skewX transX | 96 | skewY scaleY transY | 97 | pers0 pers1 pers2 | 98 99 @param scaleX horizontal scale factor 100 @param skewX horizontal skew factor 101 @param transX horizontal translation 102 @param skewY vertical skew factor 103 @param scaleY vertical scale factor 104 @param transY vertical translation 105 @param pers0 input x-axis perspective factor 106 @param pers1 input y-axis perspective factor 107 @param pers2 perspective scale factor 108 @return SkMatrix constructed from parameters 109 */ MakeAll(SkScalar scaleX,SkScalar skewX,SkScalar transX,SkScalar skewY,SkScalar scaleY,SkScalar transY,SkScalar pers0,SkScalar pers1,SkScalar pers2)110 static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, 111 SkScalar skewY, SkScalar scaleY, SkScalar transY, 112 SkScalar pers0, SkScalar pers1, SkScalar pers2) { 113 SkMatrix m; 114 m.setAll(scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2); 115 return m; 116 } 117 118 /** \enum SkMatrix::TypeMask 119 Enum of bit fields for mask returned by getType(). 120 Used to identify the complexity of SkMatrix, to optimize performance. 121 */ 122 enum TypeMask { 123 kIdentity_Mask = 0, //!< identity SkMatrix; all bits clear 124 kTranslate_Mask = 0x01, //!< translation SkMatrix 125 kScale_Mask = 0x02, //!< scale SkMatrix 126 kAffine_Mask = 0x04, //!< skew or rotate SkMatrix 127 kPerspective_Mask = 0x08, //!< perspective SkMatrix 128 }; 129 130 /** Returns a bit field describing the transformations the matrix may 131 perform. The bit field is computed conservatively, so it may include 132 false positives. For example, when kPerspective_Mask is set, all 133 other bits are set. 134 135 @return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask, 136 kAffine_Mask, kPerspective_Mask 137 */ getType()138 TypeMask getType() const { 139 if (fTypeMask & kUnknown_Mask) { 140 fTypeMask = this->computeTypeMask(); 141 } 142 // only return the public masks 143 return (TypeMask)(fTypeMask & 0xF); 144 } 145 146 /** Returns true if SkMatrix is identity. Identity matrix is: 147 148 | 1 0 0 | 149 | 0 1 0 | 150 | 0 0 1 | 151 152 @return true if SkMatrix has no effect 153 */ isIdentity()154 bool isIdentity() const { 155 return this->getType() == 0; 156 } 157 158 /** Returns true if SkMatrix at most scales and translates. SkMatrix may be identity, 159 contain only scale elements, only translate elements, or both. SkMatrix form is: 160 161 | scale-x 0 translate-x | 162 | 0 scale-y translate-y | 163 | 0 0 1 | 164 165 @return true if SkMatrix is identity; or scales, translates, or both 166 */ isScaleTranslate()167 bool isScaleTranslate() const { 168 return !(this->getType() & ~(kScale_Mask | kTranslate_Mask)); 169 } 170 171 /** Returns true if SkMatrix is identity, or translates. SkMatrix form is: 172 173 | 1 0 translate-x | 174 | 0 1 translate-y | 175 | 0 0 1 | 176 177 @return true if SkMatrix is identity, or translates 178 */ isTranslate()179 bool isTranslate() const { return !(this->getType() & ~(kTranslate_Mask)); } 180 181 /** Returns true SkMatrix maps SkRect to another SkRect. If true, SkMatrix is identity, 182 or scales, or rotates a multiple of 90 degrees, or mirrors on axes. In all 183 cases, SkMatrix may also have translation. SkMatrix form is either: 184 185 | scale-x 0 translate-x | 186 | 0 scale-y translate-y | 187 | 0 0 1 | 188 189 or 190 191 | 0 rotate-x translate-x | 192 | rotate-y 0 translate-y | 193 | 0 0 1 | 194 195 for non-zero values of scale-x, scale-y, rotate-x, and rotate-y. 196 197 Also called preservesAxisAlignment(); use the one that provides better inline 198 documentation. 199 200 @return true if SkMatrix maps one SkRect into another 201 */ rectStaysRect()202 bool rectStaysRect() const { 203 if (fTypeMask & kUnknown_Mask) { 204 fTypeMask = this->computeTypeMask(); 205 } 206 return (fTypeMask & kRectStaysRect_Mask) != 0; 207 } 208 209 /** Returns true SkMatrix maps SkRect to another SkRect. If true, SkMatrix is identity, 210 or scales, or rotates a multiple of 90 degrees, or mirrors on axes. In all 211 cases, SkMatrix may also have translation. SkMatrix form is either: 212 213 | scale-x 0 translate-x | 214 | 0 scale-y translate-y | 215 | 0 0 1 | 216 217 or 218 219 | 0 rotate-x translate-x | 220 | rotate-y 0 translate-y | 221 | 0 0 1 | 222 223 for non-zero values of scale-x, scale-y, rotate-x, and rotate-y. 224 225 Also called rectStaysRect(); use the one that provides better inline 226 documentation. 227 228 @return true if SkMatrix maps one SkRect into another 229 */ preservesAxisAlignment()230 bool preservesAxisAlignment() const { return this->rectStaysRect(); } 231 232 /** Returns true if the matrix contains perspective elements. SkMatrix form is: 233 234 | -- -- -- | 235 | -- -- -- | 236 | perspective-x perspective-y perspective-scale | 237 238 where perspective-x or perspective-y is non-zero, or perspective-scale is 239 not one. All other elements may have any value. 240 241 @return true if SkMatrix is in most general form 242 */ hasPerspective()243 bool hasPerspective() const { 244 return SkToBool(this->getPerspectiveTypeMaskOnly() & 245 kPerspective_Mask); 246 } 247 248 /** Returns true if SkMatrix contains only translation, rotation, reflection, and 249 uniform scale. 250 Returns false if SkMatrix contains different scales, skewing, perspective, or 251 degenerate forms that collapse to a line or point. 252 253 Describes that the SkMatrix makes rendering with and without the matrix are 254 visually alike; a transformed circle remains a circle. Mathematically, this is 255 referred to as similarity of a Euclidean space, or a similarity transformation. 256 257 Preserves right angles, keeping the arms of the angle equal lengths. 258 259 @param tol to be deprecated 260 @return true if SkMatrix only rotates, uniformly scales, translates 261 */ 262 bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const; 263 264 /** Returns true if SkMatrix contains only translation, rotation, reflection, and 265 scale. Scale may differ along rotated axes. 266 Returns false if SkMatrix skewing, perspective, or degenerate forms that collapse 267 to a line or point. 268 269 Preserves right angles, but not requiring that the arms of the angle 270 retain equal lengths. 271 272 @param tol to be deprecated 273 @return true if SkMatrix only rotates, scales, translates 274 */ 275 bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const; 276 277 /** SkMatrix organizes its values in row order. These members correspond to 278 each value in SkMatrix. 279 */ 280 static constexpr int kMScaleX = 0; //!< horizontal scale factor 281 static constexpr int kMSkewX = 1; //!< horizontal skew factor 282 static constexpr int kMTransX = 2; //!< horizontal translation 283 static constexpr int kMSkewY = 3; //!< vertical skew factor 284 static constexpr int kMScaleY = 4; //!< vertical scale factor 285 static constexpr int kMTransY = 5; //!< vertical translation 286 static constexpr int kMPersp0 = 6; //!< input x perspective factor 287 static constexpr int kMPersp1 = 7; //!< input y perspective factor 288 static constexpr int kMPersp2 = 8; //!< perspective bias 289 290 /** Affine arrays are in column major order to match the matrix used by 291 PDF and XPS. 292 */ 293 static constexpr int kAScaleX = 0; //!< horizontal scale factor 294 static constexpr int kASkewY = 1; //!< vertical skew factor 295 static constexpr int kASkewX = 2; //!< horizontal skew factor 296 static constexpr int kAScaleY = 3; //!< vertical scale factor 297 static constexpr int kATransX = 4; //!< horizontal translation 298 static constexpr int kATransY = 5; //!< vertical translation 299 300 /** Returns one matrix value. Asserts if index is out of range and SK_DEBUG is 301 defined. 302 303 @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 304 kMPersp0, kMPersp1, kMPersp2 305 @return value corresponding to index 306 */ 307 SkScalar operator[](int index) const { 308 SkASSERT((unsigned)index < 9); 309 return fMat[index]; 310 } 311 312 /** Returns one matrix value. Asserts if index is out of range and SK_DEBUG is 313 defined. 314 315 @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 316 kMPersp0, kMPersp1, kMPersp2 317 @return value corresponding to index 318 */ get(int index)319 SkScalar get(int index) const { 320 SkASSERT((unsigned)index < 9); 321 return fMat[index]; 322 } 323 324 /** Returns scale factor multiplied by x-axis input, contributing to x-axis output. 325 With mapPoints(), scales SkPoint along the x-axis. 326 327 @return horizontal scale factor 328 */ getScaleX()329 SkScalar getScaleX() const { return fMat[kMScaleX]; } 330 331 /** Returns scale factor multiplied by y-axis input, contributing to y-axis output. 332 With mapPoints(), scales SkPoint along the y-axis. 333 334 @return vertical scale factor 335 */ getScaleY()336 SkScalar getScaleY() const { return fMat[kMScaleY]; } 337 338 /** Returns scale factor multiplied by x-axis input, contributing to y-axis output. 339 With mapPoints(), skews SkPoint along the y-axis. 340 Skewing both axes can rotate SkPoint. 341 342 @return vertical skew factor 343 */ getSkewY()344 SkScalar getSkewY() const { return fMat[kMSkewY]; } 345 346 /** Returns scale factor multiplied by y-axis input, contributing to x-axis output. 347 With mapPoints(), skews SkPoint along the x-axis. 348 Skewing both axes can rotate SkPoint. 349 350 @return horizontal scale factor 351 */ getSkewX()352 SkScalar getSkewX() const { return fMat[kMSkewX]; } 353 354 /** Returns translation contributing to x-axis output. 355 With mapPoints(), moves SkPoint along the x-axis. 356 357 @return horizontal translation factor 358 */ getTranslateX()359 SkScalar getTranslateX() const { return fMat[kMTransX]; } 360 361 /** Returns translation contributing to y-axis output. 362 With mapPoints(), moves SkPoint along the y-axis. 363 364 @return vertical translation factor 365 */ getTranslateY()366 SkScalar getTranslateY() const { return fMat[kMTransY]; } 367 368 /** Returns factor scaling input x-axis relative to input y-axis. 369 370 @return input x-axis perspective factor 371 */ getPerspX()372 SkScalar getPerspX() const { return fMat[kMPersp0]; } 373 374 /** Returns factor scaling input y-axis relative to input x-axis. 375 376 @return input y-axis perspective factor 377 */ getPerspY()378 SkScalar getPerspY() const { return fMat[kMPersp1]; } 379 380 /** Returns writable SkMatrix value. Asserts if index is out of range and SK_DEBUG is 381 defined. Clears internal cache anticipating that caller will change SkMatrix value. 382 383 Next call to read SkMatrix state may recompute cache; subsequent writes to SkMatrix 384 value must be followed by dirtyMatrixTypeCache(). 385 386 @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 387 kMPersp0, kMPersp1, kMPersp2 388 @return writable value corresponding to index 389 */ 390 SkScalar& operator[](int index) { 391 SkASSERT((unsigned)index < 9); 392 this->setTypeMask(kUnknown_Mask); 393 return fMat[index]; 394 } 395 396 /** Sets SkMatrix value. Asserts if index is out of range and SK_DEBUG is 397 defined. Safer than operator[]; internal cache is always maintained. 398 399 @param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 400 kMPersp0, kMPersp1, kMPersp2 401 @param value scalar to store in SkMatrix 402 */ set(int index,SkScalar value)403 void set(int index, SkScalar value) { 404 SkASSERT((unsigned)index < 9); 405 fMat[index] = value; 406 this->setTypeMask(kUnknown_Mask); 407 } 408 409 /** Sets horizontal scale factor. 410 411 @param v horizontal scale factor to store 412 */ setScaleX(SkScalar v)413 void setScaleX(SkScalar v) { this->set(kMScaleX, v); } 414 415 /** Sets vertical scale factor. 416 417 @param v vertical scale factor to store 418 */ setScaleY(SkScalar v)419 void setScaleY(SkScalar v) { this->set(kMScaleY, v); } 420 421 /** Sets vertical skew factor. 422 423 @param v vertical skew factor to store 424 */ setSkewY(SkScalar v)425 void setSkewY(SkScalar v) { this->set(kMSkewY, v); } 426 427 /** Sets horizontal skew factor. 428 429 @param v horizontal skew factor to store 430 */ setSkewX(SkScalar v)431 void setSkewX(SkScalar v) { this->set(kMSkewX, v); } 432 433 /** Sets horizontal translation. 434 435 @param v horizontal translation to store 436 */ setTranslateX(SkScalar v)437 void setTranslateX(SkScalar v) { this->set(kMTransX, v); } 438 439 /** Sets vertical translation. 440 441 @param v vertical translation to store 442 */ setTranslateY(SkScalar v)443 void setTranslateY(SkScalar v) { this->set(kMTransY, v); } 444 445 /** Sets input x-axis perspective factor, which causes mapXY() to vary input x-axis values 446 inversely proportional to input y-axis values. 447 448 @param v perspective factor 449 */ setPerspX(SkScalar v)450 void setPerspX(SkScalar v) { this->set(kMPersp0, v); } 451 452 /** Sets input y-axis perspective factor, which causes mapXY() to vary input y-axis values 453 inversely proportional to input x-axis values. 454 455 @param v perspective factor 456 */ setPerspY(SkScalar v)457 void setPerspY(SkScalar v) { this->set(kMPersp1, v); } 458 459 /** Sets all values from parameters. Sets matrix to: 460 461 | scaleX skewX transX | 462 | skewY scaleY transY | 463 | persp0 persp1 persp2 | 464 465 @param scaleX horizontal scale factor to store 466 @param skewX horizontal skew factor to store 467 @param transX horizontal translation to store 468 @param skewY vertical skew factor to store 469 @param scaleY vertical scale factor to store 470 @param transY vertical translation to store 471 @param persp0 input x-axis values perspective factor to store 472 @param persp1 input y-axis values perspective factor to store 473 @param persp2 perspective scale factor to store 474 */ setAll(SkScalar scaleX,SkScalar skewX,SkScalar transX,SkScalar skewY,SkScalar scaleY,SkScalar transY,SkScalar persp0,SkScalar persp1,SkScalar persp2)475 void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, 476 SkScalar skewY, SkScalar scaleY, SkScalar transY, 477 SkScalar persp0, SkScalar persp1, SkScalar persp2) { 478 fMat[kMScaleX] = scaleX; 479 fMat[kMSkewX] = skewX; 480 fMat[kMTransX] = transX; 481 fMat[kMSkewY] = skewY; 482 fMat[kMScaleY] = scaleY; 483 fMat[kMTransY] = transY; 484 fMat[kMPersp0] = persp0; 485 fMat[kMPersp1] = persp1; 486 fMat[kMPersp2] = persp2; 487 this->setTypeMask(kUnknown_Mask); 488 } 489 490 /** Copies nine scalar values contained by SkMatrix into buffer, in member value 491 ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, 492 kMPersp0, kMPersp1, kMPersp2. 493 494 @param buffer storage for nine scalar values 495 */ get9(SkScalar buffer[9])496 void get9(SkScalar buffer[9]) const { 497 memcpy(buffer, fMat, 9 * sizeof(SkScalar)); 498 } 499 500 /** Sets SkMatrix to nine scalar values in buffer, in member value ascending order: 501 kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1, 502 kMPersp2. 503 504 Sets matrix to: 505 506 | buffer[0] buffer[1] buffer[2] | 507 | buffer[3] buffer[4] buffer[5] | 508 | buffer[6] buffer[7] buffer[8] | 509 510 In the future, set9 followed by get9 may not return the same values. Since SkMatrix 511 maps non-homogeneous coordinates, scaling all nine values produces an equivalent 512 transformation, possibly improving precision. 513 514 @param buffer nine scalar values 515 */ 516 void set9(const SkScalar buffer[9]); 517 518 /** Sets SkMatrix to identity; which has no effect on mapped SkPoint. Sets SkMatrix to: 519 520 | 1 0 0 | 521 | 0 1 0 | 522 | 0 0 1 | 523 524 Also called setIdentity(); use the one that provides better inline 525 documentation. 526 */ 527 void reset(); 528 529 /** Sets SkMatrix to identity; which has no effect on mapped SkPoint. Sets SkMatrix to: 530 531 | 1 0 0 | 532 | 0 1 0 | 533 | 0 0 1 | 534 535 Also called reset(); use the one that provides better inline 536 documentation. 537 */ setIdentity()538 void setIdentity() { this->reset(); } 539 540 /** Sets SkMatrix to translate by (dx, dy). 541 542 @param dx horizontal translation 543 @param dy vertical translation 544 */ 545 void setTranslate(SkScalar dx, SkScalar dy); 546 547 /** Sets SkMatrix to translate by (v.fX, v.fY). 548 549 @param v vector containing horizontal and vertical translation 550 */ setTranslate(const SkVector & v)551 void setTranslate(const SkVector& v) { this->setTranslate(v.fX, v.fY); } 552 553 /** Sets SkMatrix to scale by sx and sy, about a pivot point at (px, py). 554 The pivot point is unchanged when mapped with SkMatrix. 555 556 @param sx horizontal scale factor 557 @param sy vertical scale factor 558 @param px pivot on x-axis 559 @param py pivot on y-axis 560 */ 561 void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py); 562 563 /** Sets SkMatrix to scale by sx and sy about at pivot point at (0, 0). 564 565 @param sx horizontal scale factor 566 @param sy vertical scale factor 567 */ 568 void setScale(SkScalar sx, SkScalar sy); 569 570 /** Sets SkMatrix to rotate by degrees about a pivot point at (px, py). 571 The pivot point is unchanged when mapped with SkMatrix. 572 573 Positive degrees rotates clockwise. 574 575 @param degrees angle of axes relative to upright axes 576 @param px pivot on x-axis 577 @param py pivot on y-axis 578 */ 579 void setRotate(SkScalar degrees, SkScalar px, SkScalar py); 580 581 /** Sets SkMatrix to rotate by degrees about a pivot point at (0, 0). 582 Positive degrees rotates clockwise. 583 584 @param degrees angle of axes relative to upright axes 585 */ 586 void setRotate(SkScalar degrees); 587 588 /** Sets SkMatrix to rotate by sinValue and cosValue, about a pivot point at (px, py). 589 The pivot point is unchanged when mapped with SkMatrix. 590 591 Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). 592 Vector length specifies scale. 593 594 @param sinValue rotation vector x-axis component 595 @param cosValue rotation vector y-axis component 596 @param px pivot on x-axis 597 @param py pivot on y-axis 598 */ 599 void setSinCos(SkScalar sinValue, SkScalar cosValue, 600 SkScalar px, SkScalar py); 601 602 /** Sets SkMatrix to rotate by sinValue and cosValue, about a pivot point at (0, 0). 603 604 Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1). 605 Vector length specifies scale. 606 607 @param sinValue rotation vector x-axis component 608 @param cosValue rotation vector y-axis component 609 */ 610 void setSinCos(SkScalar sinValue, SkScalar cosValue); 611 612 /** Sets SkMatrix to rotate, scale, and translate using a compressed matrix form. 613 614 Vector (rsxForm.fSSin, rsxForm.fSCos) describes the angle of rotation relative 615 to (0, 1). Vector length specifies scale. Mapped point is rotated and scaled 616 by vector, then translated by (rsxForm.fTx, rsxForm.fTy). 617 618 @param rsxForm compressed SkRSXform matrix 619 @return reference to SkMatrix 620 */ 621 SkMatrix& setRSXform(const SkRSXform& rsxForm); 622 623 /** Sets SkMatrix to skew by kx and ky, about a pivot point at (px, py). 624 The pivot point is unchanged when mapped with SkMatrix. 625 626 @param kx horizontal skew factor 627 @param ky vertical skew factor 628 @param px pivot on x-axis 629 @param py pivot on y-axis 630 */ 631 void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py); 632 633 /** Sets SkMatrix to skew by kx and ky, about a pivot point at (0, 0). 634 635 @param kx horizontal skew factor 636 @param ky vertical skew factor 637 */ 638 void setSkew(SkScalar kx, SkScalar ky); 639 640 /** Sets SkMatrix to SkMatrix a multiplied by SkMatrix b. Either a or b may be this. 641 642 Given: 643 644 | A B C | | J K L | 645 a = | D E F |, b = | M N O | 646 | G H I | | P Q R | 647 648 sets SkMatrix to: 649 650 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 651 a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 652 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 653 654 @param a SkMatrix on left side of multiply expression 655 @param b SkMatrix on right side of multiply expression 656 */ 657 void setConcat(const SkMatrix& a, const SkMatrix& b); 658 659 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from translation (dx, dy). 660 This can be thought of as moving the point to be mapped before applying SkMatrix. 661 662 Given: 663 664 | A B C | | 1 0 dx | 665 Matrix = | D E F |, T(dx, dy) = | 0 1 dy | 666 | G H I | | 0 0 1 | 667 668 sets SkMatrix to: 669 670 | A B C | | 1 0 dx | | A B A*dx+B*dy+C | 671 Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F | 672 | G H I | | 0 0 1 | | G H G*dx+H*dy+I | 673 674 @param dx x-axis translation before applying SkMatrix 675 @param dy y-axis translation before applying SkMatrix 676 */ 677 void preTranslate(SkScalar dx, SkScalar dy); 678 679 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from scaling by (sx, sy) 680 about pivot point (px, py). 681 This can be thought of as scaling about a pivot point before applying SkMatrix. 682 683 Given: 684 685 | A B C | | sx 0 dx | 686 Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy | 687 | G H I | | 0 0 1 | 688 689 where 690 691 dx = px - sx * px 692 dy = py - sy * py 693 694 sets SkMatrix to: 695 696 | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C | 697 Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F | 698 | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I | 699 700 @param sx horizontal scale factor 701 @param sy vertical scale factor 702 @param px pivot on x-axis 703 @param py pivot on y-axis 704 */ 705 void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py); 706 707 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from scaling by (sx, sy) 708 about pivot point (0, 0). 709 This can be thought of as scaling about the origin before applying SkMatrix. 710 711 Given: 712 713 | A B C | | sx 0 0 | 714 Matrix = | D E F |, S(sx, sy) = | 0 sy 0 | 715 | G H I | | 0 0 1 | 716 717 sets SkMatrix to: 718 719 | A B C | | sx 0 0 | | A*sx B*sy C | 720 Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F | 721 | G H I | | 0 0 1 | | G*sx H*sy I | 722 723 @param sx horizontal scale factor 724 @param sy vertical scale factor 725 */ 726 void preScale(SkScalar sx, SkScalar sy); 727 728 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from rotating by degrees 729 about pivot point (px, py). 730 This can be thought of as rotating about a pivot point before applying SkMatrix. 731 732 Positive degrees rotates clockwise. 733 734 Given: 735 736 | A B C | | c -s dx | 737 Matrix = | D E F |, R(degrees, px, py) = | s c dy | 738 | G H I | | 0 0 1 | 739 740 where 741 742 c = cos(degrees) 743 s = sin(degrees) 744 dx = s * py + (1 - c) * px 745 dy = -s * px + (1 - c) * py 746 747 sets SkMatrix to: 748 749 | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C | 750 Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F | 751 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I | 752 753 @param degrees angle of axes relative to upright axes 754 @param px pivot on x-axis 755 @param py pivot on y-axis 756 */ 757 void preRotate(SkScalar degrees, SkScalar px, SkScalar py); 758 759 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from rotating by degrees 760 about pivot point (0, 0). 761 This can be thought of as rotating about the origin before applying SkMatrix. 762 763 Positive degrees rotates clockwise. 764 765 Given: 766 767 | A B C | | c -s 0 | 768 Matrix = | D E F |, R(degrees, px, py) = | s c 0 | 769 | G H I | | 0 0 1 | 770 771 where 772 773 c = cos(degrees) 774 s = sin(degrees) 775 776 sets SkMatrix to: 777 778 | A B C | | c -s 0 | | Ac+Bs -As+Bc C | 779 Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F | 780 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I | 781 782 @param degrees angle of axes relative to upright axes 783 */ 784 void preRotate(SkScalar degrees); 785 786 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from skewing by (kx, ky) 787 about pivot point (px, py). 788 This can be thought of as skewing about a pivot point before applying SkMatrix. 789 790 Given: 791 792 | A B C | | 1 kx dx | 793 Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy | 794 | G H I | | 0 0 1 | 795 796 where 797 798 dx = -kx * py 799 dy = -ky * px 800 801 sets SkMatrix to: 802 803 | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C | 804 Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F | 805 | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I | 806 807 @param kx horizontal skew factor 808 @param ky vertical skew factor 809 @param px pivot on x-axis 810 @param py pivot on y-axis 811 */ 812 void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py); 813 814 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix constructed from skewing by (kx, ky) 815 about pivot point (0, 0). 816 This can be thought of as skewing about the origin before applying SkMatrix. 817 818 Given: 819 820 | A B C | | 1 kx 0 | 821 Matrix = | D E F |, K(kx, ky) = | ky 1 0 | 822 | G H I | | 0 0 1 | 823 824 sets SkMatrix to: 825 826 | A B C | | 1 kx 0 | | A+B*ky A*kx+B C | 827 Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F | 828 | G H I | | 0 0 1 | | G+H*ky G*kx+H I | 829 830 @param kx horizontal skew factor 831 @param ky vertical skew factor 832 */ 833 void preSkew(SkScalar kx, SkScalar ky); 834 835 /** Sets SkMatrix to SkMatrix multiplied by SkMatrix other. 836 This can be thought of mapping by other before applying SkMatrix. 837 838 Given: 839 840 | A B C | | J K L | 841 Matrix = | D E F |, other = | M N O | 842 | G H I | | P Q R | 843 844 sets SkMatrix to: 845 846 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 847 Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 848 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 849 850 @param other SkMatrix on right side of multiply expression 851 */ 852 void preConcat(const SkMatrix& other); 853 854 /** Sets SkMatrix to SkMatrix constructed from translation (dx, dy) multiplied by SkMatrix. 855 This can be thought of as moving the point to be mapped after applying SkMatrix. 856 857 Given: 858 859 | J K L | | 1 0 dx | 860 Matrix = | M N O |, T(dx, dy) = | 0 1 dy | 861 | P Q R | | 0 0 1 | 862 863 sets SkMatrix to: 864 865 | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R | 866 T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R | 867 | 0 0 1 | | P Q R | | P Q R | 868 869 @param dx x-axis translation after applying SkMatrix 870 @param dy y-axis translation after applying SkMatrix 871 */ 872 void postTranslate(SkScalar dx, SkScalar dy); 873 874 /** Sets SkMatrix to SkMatrix constructed from scaling by (sx, sy) about pivot point 875 (px, py), multiplied by SkMatrix. 876 This can be thought of as scaling about a pivot point after applying SkMatrix. 877 878 Given: 879 880 | J K L | | sx 0 dx | 881 Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy | 882 | P Q R | | 0 0 1 | 883 884 where 885 886 dx = px - sx * px 887 dy = py - sy * py 888 889 sets SkMatrix to: 890 891 | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R | 892 S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R | 893 | 0 0 1 | | P Q R | | P Q R | 894 895 @param sx horizontal scale factor 896 @param sy vertical scale factor 897 @param px pivot on x-axis 898 @param py pivot on y-axis 899 */ 900 void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py); 901 902 /** Sets SkMatrix to SkMatrix constructed from scaling by (sx, sy) about pivot point 903 (0, 0), multiplied by SkMatrix. 904 This can be thought of as scaling about the origin after applying SkMatrix. 905 906 Given: 907 908 | J K L | | sx 0 0 | 909 Matrix = | M N O |, S(sx, sy) = | 0 sy 0 | 910 | P Q R | | 0 0 1 | 911 912 sets SkMatrix to: 913 914 | sx 0 0 | | J K L | | sx*J sx*K sx*L | 915 S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | 916 | 0 0 1 | | P Q R | | P Q R | 917 918 @param sx horizontal scale factor 919 @param sy vertical scale factor 920 */ 921 void postScale(SkScalar sx, SkScalar sy); 922 923 /** Sets SkMatrix to SkMatrix constructed from scaling by (1/divx, 1/divy), 924 about pivot point (px, py), multiplied by SkMatrix. 925 926 Returns false if either divx or divy is zero. 927 928 Given: 929 930 | J K L | | sx 0 0 | 931 Matrix = | M N O |, I(divx, divy) = | 0 sy 0 | 932 | P Q R | | 0 0 1 | 933 934 where 935 936 sx = 1 / divx 937 sy = 1 / divy 938 939 sets SkMatrix to: 940 941 | sx 0 0 | | J K L | | sx*J sx*K sx*L | 942 I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O | 943 | 0 0 1 | | P Q R | | P Q R | 944 945 @param divx integer divisor for inverse scale in x 946 @param divy integer divisor for inverse scale in y 947 @return true on successful scale 948 */ 949 bool postIDiv(int divx, int divy); 950 951 /** Sets SkMatrix to SkMatrix constructed from rotating by degrees about pivot point 952 (px, py), multiplied by SkMatrix. 953 This can be thought of as rotating about a pivot point after applying SkMatrix. 954 955 Positive degrees rotates clockwise. 956 957 Given: 958 959 | J K L | | c -s dx | 960 Matrix = | M N O |, R(degrees, px, py) = | s c dy | 961 | P Q R | | 0 0 1 | 962 963 where 964 965 c = cos(degrees) 966 s = sin(degrees) 967 dx = s * py + (1 - c) * px 968 dy = -s * px + (1 - c) * py 969 970 sets SkMatrix to: 971 972 |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R| 973 R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R| 974 |0 0 1| |P Q R| | P Q R| 975 976 @param degrees angle of axes relative to upright axes 977 @param px pivot on x-axis 978 @param py pivot on y-axis 979 */ 980 void postRotate(SkScalar degrees, SkScalar px, SkScalar py); 981 982 /** Sets SkMatrix to SkMatrix constructed from rotating by degrees about pivot point 983 (0, 0), multiplied by SkMatrix. 984 This can be thought of as rotating about the origin after applying SkMatrix. 985 986 Positive degrees rotates clockwise. 987 988 Given: 989 990 | J K L | | c -s 0 | 991 Matrix = | M N O |, R(degrees, px, py) = | s c 0 | 992 | P Q R | | 0 0 1 | 993 994 where 995 996 c = cos(degrees) 997 s = sin(degrees) 998 999 sets SkMatrix to: 1000 1001 | c -s dx | | J K L | | cJ-sM cK-sN cL-sO | 1002 R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO | 1003 | 0 0 1 | | P Q R | | P Q R | 1004 1005 @param degrees angle of axes relative to upright axes 1006 */ 1007 void postRotate(SkScalar degrees); 1008 1009 /** Sets SkMatrix to SkMatrix constructed from skewing by (kx, ky) about pivot point 1010 (px, py), multiplied by SkMatrix. 1011 This can be thought of as skewing about a pivot point after applying SkMatrix. 1012 1013 Given: 1014 1015 | J K L | | 1 kx dx | 1016 Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy | 1017 | P Q R | | 0 0 1 | 1018 1019 where 1020 1021 dx = -kx * py 1022 dy = -ky * px 1023 1024 sets SkMatrix to: 1025 1026 | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R| 1027 K(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| 1028 | 0 0 1| |P Q R| | P Q R| 1029 1030 @param kx horizontal skew factor 1031 @param ky vertical skew factor 1032 @param px pivot on x-axis 1033 @param py pivot on y-axis 1034 */ 1035 void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py); 1036 1037 /** Sets SkMatrix to SkMatrix constructed from skewing by (kx, ky) about pivot point 1038 (0, 0), multiplied by SkMatrix. 1039 This can be thought of as skewing about the origin after applying SkMatrix. 1040 1041 Given: 1042 1043 | J K L | | 1 kx 0 | 1044 Matrix = | M N O |, K(kx, ky) = | ky 1 0 | 1045 | P Q R | | 0 0 1 | 1046 1047 sets SkMatrix to: 1048 1049 | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O | 1050 K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O | 1051 | 0 0 1 | | P Q R | | P Q R | 1052 1053 @param kx horizontal skew factor 1054 @param ky vertical skew factor 1055 */ 1056 void postSkew(SkScalar kx, SkScalar ky); 1057 1058 /** Sets SkMatrix to SkMatrix other multiplied by SkMatrix. 1059 This can be thought of mapping by other after applying SkMatrix. 1060 1061 Given: 1062 1063 | J K L | | A B C | 1064 Matrix = | M N O |, other = | D E F | 1065 | P Q R | | G H I | 1066 1067 sets SkMatrix to: 1068 1069 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 1070 other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 1071 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 1072 1073 @param other SkMatrix on left side of multiply expression 1074 */ 1075 void postConcat(const SkMatrix& other); 1076 1077 /** \enum SkMatrix::ScaleToFit 1078 ScaleToFit describes how SkMatrix is constructed to map one SkRect to another. 1079 ScaleToFit may allow SkMatrix to have unequal horizontal and vertical scaling, 1080 or may restrict SkMatrix to square scaling. If restricted, ScaleToFit specifies 1081 how SkMatrix maps to the side or center of the destination SkRect. 1082 */ 1083 enum ScaleToFit { 1084 kFill_ScaleToFit, //!< scales in x and y to fill destination SkRect 1085 kStart_ScaleToFit, //!< scales and aligns to left and top 1086 kCenter_ScaleToFit, //!< scales and aligns to center 1087 kEnd_ScaleToFit, //!< scales and aligns to right and bottom 1088 }; 1089 1090 /** Sets SkMatrix to scale and translate src SkRect to dst SkRect. stf selects whether 1091 mapping completely fills dst or preserves the aspect ratio, and how to align 1092 src within dst. Returns false if src is empty, and sets SkMatrix to identity. 1093 Returns true if dst is empty, and sets SkMatrix to: 1094 1095 | 0 0 0 | 1096 | 0 0 0 | 1097 | 0 0 1 | 1098 1099 @param src SkRect to map from 1100 @param dst SkRect to map to 1101 @param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, 1102 kCenter_ScaleToFit, kEnd_ScaleToFit 1103 @return true if SkMatrix can represent SkRect mapping 1104 */ 1105 bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf); 1106 1107 /** Returns SkMatrix set to scale and translate src SkRect to dst SkRect. stf selects 1108 whether mapping completely fills dst or preserves the aspect ratio, and how to 1109 align src within dst. Returns the identity SkMatrix if src is empty. If dst is 1110 empty, returns SkMatrix set to: 1111 1112 | 0 0 0 | 1113 | 0 0 0 | 1114 | 0 0 1 | 1115 1116 @param src SkRect to map from 1117 @param dst SkRect to map to 1118 @param stf one of: kFill_ScaleToFit, kStart_ScaleToFit, 1119 kCenter_ScaleToFit, kEnd_ScaleToFit 1120 @return SkMatrix mapping src to dst 1121 */ MakeRectToRect(const SkRect & src,const SkRect & dst,ScaleToFit stf)1122 static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) { 1123 SkMatrix m; 1124 m.setRectToRect(src, dst, stf); 1125 return m; 1126 } 1127 1128 /** Sets SkMatrix to map src to dst. count must be zero or greater, and four or less. 1129 1130 If count is zero, sets SkMatrix to identity and returns true. 1131 If count is one, sets SkMatrix to translate and returns true. 1132 If count is two or more, sets SkMatrix to map SkPoint if possible; returns false 1133 if SkMatrix cannot be constructed. If count is four, SkMatrix may include 1134 perspective. 1135 1136 @param src SkPoint to map from 1137 @param dst SkPoint to map to 1138 @param count number of SkPoint in src and dst 1139 @return true if SkMatrix was constructed successfully 1140 */ 1141 bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count); 1142 1143 /** Sets inverse to reciprocal matrix, returning true if SkMatrix can be inverted. 1144 Geometrically, if SkMatrix maps from source to destination, inverse SkMatrix 1145 maps from destination to source. If SkMatrix can not be inverted, inverse is 1146 unchanged. 1147 1148 @param inverse storage for inverted SkMatrix; may be nullptr 1149 @return true if SkMatrix can be inverted 1150 */ invert(SkMatrix * inverse)1151 bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const { 1152 // Allow the trivial case to be inlined. 1153 if (this->isIdentity()) { 1154 if (inverse) { 1155 inverse->reset(); 1156 } 1157 return true; 1158 } 1159 return this->invertNonIdentity(inverse); 1160 } 1161 1162 /** Fills affine with identity values in column major order. 1163 Sets affine to: 1164 1165 | 1 0 0 | 1166 | 0 1 0 | 1167 1168 Affine 3 by 2 matrices in column major order are used by OpenGL and XPS. 1169 1170 @param affine storage for 3 by 2 affine matrix 1171 */ 1172 static void SetAffineIdentity(SkScalar affine[6]); 1173 1174 /** Fills affine in column major order. Sets affine to: 1175 1176 | scale-x skew-x translate-x | 1177 | skew-y scale-y translate-y | 1178 1179 If SkMatrix contains perspective, returns false and leaves affine unchanged. 1180 1181 @param affine storage for 3 by 2 affine matrix; may be nullptr 1182 @return true if SkMatrix does not contain perspective 1183 */ 1184 bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const; 1185 1186 /** Sets SkMatrix to affine values, passed in column major order. Given affine, 1187 column, then row, as: 1188 1189 | scale-x skew-x translate-x | 1190 | skew-y scale-y translate-y | 1191 1192 SkMatrix is set, row, then column, to: 1193 1194 | scale-x skew-x translate-x | 1195 | skew-y scale-y translate-y | 1196 | 0 0 1 | 1197 1198 @param affine 3 by 2 affine matrix 1199 */ 1200 void setAffine(const SkScalar affine[6]); 1201 1202 /** Maps src SkPoint array of length count to dst SkPoint array of equal or greater 1203 length. SkPoint are mapped by multiplying each SkPoint by SkMatrix. Given: 1204 1205 | A B C | | x | 1206 Matrix = | D E F |, pt = | y | 1207 | G H I | | 1 | 1208 1209 where 1210 1211 for (i = 0; i < count; ++i) { 1212 x = src[i].fX 1213 y = src[i].fY 1214 } 1215 1216 each dst SkPoint is computed as: 1217 1218 |A B C| |x| Ax+By+C Dx+Ey+F 1219 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1220 |G H I| |1| Gx+Hy+I Gx+Hy+I 1221 1222 src and dst may point to the same storage. 1223 1224 @param dst storage for mapped SkPoint 1225 @param src SkPoint to transform 1226 @param count number of SkPoint to transform 1227 */ 1228 void mapPoints(SkPoint dst[], const SkPoint src[], int count) const; 1229 1230 /** Maps pts SkPoint array of length count in place. SkPoint are mapped by multiplying 1231 each SkPoint by SkMatrix. Given: 1232 1233 | A B C | | x | 1234 Matrix = | D E F |, pt = | y | 1235 | G H I | | 1 | 1236 1237 where 1238 1239 for (i = 0; i < count; ++i) { 1240 x = pts[i].fX 1241 y = pts[i].fY 1242 } 1243 1244 each resulting pts SkPoint is computed as: 1245 1246 |A B C| |x| Ax+By+C Dx+Ey+F 1247 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1248 |G H I| |1| Gx+Hy+I Gx+Hy+I 1249 1250 @param pts storage for mapped SkPoint 1251 @param count number of SkPoint to transform 1252 */ mapPoints(SkPoint pts[],int count)1253 void mapPoints(SkPoint pts[], int count) const { 1254 this->mapPoints(pts, pts, count); 1255 } 1256 1257 /** Maps src SkPoint3 array of length count to dst SkPoint3 array, which must of length count or 1258 greater. SkPoint3 array is mapped by multiplying each SkPoint3 by SkMatrix. Given: 1259 1260 | A B C | | x | 1261 Matrix = | D E F |, src = | y | 1262 | G H I | | z | 1263 1264 each resulting dst SkPoint is computed as: 1265 1266 |A B C| |x| 1267 Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz| 1268 |G H I| |z| 1269 1270 @param dst storage for mapped SkPoint3 array 1271 @param src SkPoint3 array to transform 1272 @param count items in SkPoint3 array to transform 1273 */ 1274 void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const; 1275 1276 /** Maps SkPoint (x, y) to result. SkPoint is mapped by multiplying by SkMatrix. Given: 1277 1278 | A B C | | x | 1279 Matrix = | D E F |, pt = | y | 1280 | G H I | | 1 | 1281 1282 result is computed as: 1283 1284 |A B C| |x| Ax+By+C Dx+Ey+F 1285 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1286 |G H I| |1| Gx+Hy+I Gx+Hy+I 1287 1288 @param x x-axis value of SkPoint to map 1289 @param y y-axis value of SkPoint to map 1290 @param result storage for mapped SkPoint 1291 */ 1292 void mapXY(SkScalar x, SkScalar y, SkPoint* result) const; 1293 1294 /** Returns SkPoint (x, y) multiplied by SkMatrix. Given: 1295 1296 | A B C | | x | 1297 Matrix = | D E F |, pt = | y | 1298 | G H I | | 1 | 1299 1300 result is computed as: 1301 1302 |A B C| |x| Ax+By+C Dx+Ey+F 1303 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1304 |G H I| |1| Gx+Hy+I Gx+Hy+I 1305 1306 @param x x-axis value of SkPoint to map 1307 @param y y-axis value of SkPoint to map 1308 @return mapped SkPoint 1309 */ mapXY(SkScalar x,SkScalar y)1310 SkPoint mapXY(SkScalar x, SkScalar y) const { 1311 SkPoint result; 1312 this->mapXY(x,y, &result); 1313 return result; 1314 } 1315 1316 /** Maps src vector array of length count to vector SkPoint array of equal or greater 1317 length. Vectors are mapped by multiplying each vector by SkMatrix, treating 1318 SkMatrix translation as zero. Given: 1319 1320 | A B 0 | | x | 1321 Matrix = | D E 0 |, src = | y | 1322 | G H I | | 1 | 1323 1324 where 1325 1326 for (i = 0; i < count; ++i) { 1327 x = src[i].fX 1328 y = src[i].fY 1329 } 1330 1331 each dst vector is computed as: 1332 1333 |A B 0| |x| Ax+By Dx+Ey 1334 Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , ------- 1335 |G H I| |1| Gx+Hy+I Gx+Hy+I 1336 1337 src and dst may point to the same storage. 1338 1339 @param dst storage for mapped vectors 1340 @param src vectors to transform 1341 @param count number of vectors to transform 1342 */ 1343 void mapVectors(SkVector dst[], const SkVector src[], int count) const; 1344 1345 /** Maps vecs vector array of length count in place, multiplying each vector by 1346 SkMatrix, treating SkMatrix translation as zero. Given: 1347 1348 | A B 0 | | x | 1349 Matrix = | D E 0 |, vec = | y | 1350 | G H I | | 1 | 1351 1352 where 1353 1354 for (i = 0; i < count; ++i) { 1355 x = vecs[i].fX 1356 y = vecs[i].fY 1357 } 1358 1359 each result vector is computed as: 1360 1361 |A B 0| |x| Ax+By Dx+Ey 1362 Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , ------- 1363 |G H I| |1| Gx+Hy+I Gx+Hy+I 1364 1365 @param vecs vectors to transform, and storage for mapped vectors 1366 @param count number of vectors to transform 1367 */ mapVectors(SkVector vecs[],int count)1368 void mapVectors(SkVector vecs[], int count) const { 1369 this->mapVectors(vecs, vecs, count); 1370 } 1371 1372 /** Maps vector (dx, dy) to result. Vector is mapped by multiplying by SkMatrix, 1373 treating SkMatrix translation as zero. Given: 1374 1375 | A B 0 | | dx | 1376 Matrix = | D E 0 |, vec = | dy | 1377 | G H I | | 1 | 1378 1379 each result vector is computed as: 1380 1381 |A B 0| |dx| A*dx+B*dy D*dx+E*dy 1382 Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , ----------- 1383 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I 1384 1385 @param dx x-axis value of vector to map 1386 @param dy y-axis value of vector to map 1387 @param result storage for mapped vector 1388 */ mapVector(SkScalar dx,SkScalar dy,SkVector * result)1389 void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const { 1390 SkVector vec = { dx, dy }; 1391 this->mapVectors(result, &vec, 1); 1392 } 1393 1394 /** Returns vector (dx, dy) multiplied by SkMatrix, treating SkMatrix translation as zero. 1395 Given: 1396 1397 | A B 0 | | dx | 1398 Matrix = | D E 0 |, vec = | dy | 1399 | G H I | | 1 | 1400 1401 each result vector is computed as: 1402 1403 |A B 0| |dx| A*dx+B*dy D*dx+E*dy 1404 Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , ----------- 1405 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I 1406 1407 @param dx x-axis value of vector to map 1408 @param dy y-axis value of vector to map 1409 @return mapped vector 1410 */ mapVector(SkScalar dx,SkScalar dy)1411 SkVector mapVector(SkScalar dx, SkScalar dy) const { 1412 SkVector vec = { dx, dy }; 1413 this->mapVectors(&vec, &vec, 1); 1414 return vec; 1415 } 1416 1417 /** Sets dst to bounds of src corners mapped by SkMatrix. 1418 Returns true if mapped corners are dst corners. 1419 1420 Returned value is the same as calling rectStaysRect(). 1421 1422 @param dst storage for bounds of mapped SkPoint 1423 @param src SkRect to map 1424 @return true if dst is equivalent to mapped src 1425 */ 1426 bool mapRect(SkRect* dst, const SkRect& src) const; 1427 1428 /** Sets rect to bounds of rect corners mapped by SkMatrix. 1429 Returns true if mapped corners are computed rect corners. 1430 1431 Returned value is the same as calling rectStaysRect(). 1432 1433 @param rect rectangle to map, and storage for bounds of mapped corners 1434 @return true if result is equivalent to mapped rect 1435 */ mapRect(SkRect * rect)1436 bool mapRect(SkRect* rect) const { 1437 return this->mapRect(rect, *rect); 1438 } 1439 1440 /** Returns bounds of src corners mapped by SkMatrix. 1441 1442 @param src rectangle to map 1443 @return mapped bounds 1444 */ mapRect(const SkRect & src)1445 SkRect mapRect(const SkRect& src) const { 1446 SkRect dst; 1447 (void)this->mapRect(&dst, src); 1448 return dst; 1449 } 1450 1451 /** Maps four corners of rect to dst. SkPoint are mapped by multiplying each 1452 rect corner by SkMatrix. rect corner is processed in this order: 1453 (rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), 1454 (rect.fLeft, rect.fBottom). 1455 1456 rect may be empty: rect.fLeft may be greater than or equal to rect.fRight; 1457 rect.fTop may be greater than or equal to rect.fBottom. 1458 1459 Given: 1460 1461 | A B C | | x | 1462 Matrix = | D E F |, pt = | y | 1463 | G H I | | 1 | 1464 1465 where pt is initialized from each of (rect.fLeft, rect.fTop), 1466 (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom), 1467 each dst SkPoint is computed as: 1468 1469 |A B C| |x| Ax+By+C Dx+Ey+F 1470 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1471 |G H I| |1| Gx+Hy+I Gx+Hy+I 1472 1473 @param dst storage for mapped corner SkPoint 1474 @param rect SkRect to map 1475 */ mapRectToQuad(SkPoint dst[4],const SkRect & rect)1476 void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const { 1477 // This could potentially be faster if we only transformed each x and y of the rect once. 1478 rect.toQuad(dst); 1479 this->mapPoints(dst, 4); 1480 } 1481 1482 /** Sets dst to bounds of src corners mapped by SkMatrix. If matrix contains 1483 elements other than scale or translate: asserts if SK_DEBUG is defined; 1484 otherwise, results are undefined. 1485 1486 @param dst storage for bounds of mapped SkPoint 1487 @param src SkRect to map 1488 */ 1489 void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const; 1490 1491 /** Returns geometric mean radius of ellipse formed by constructing circle of 1492 size radius, and mapping constructed circle with SkMatrix. The result squared is 1493 equal to the major axis length times the minor axis length. 1494 Result is not meaningful if SkMatrix contains perspective elements. 1495 1496 @param radius circle size to map 1497 @return average mapped radius 1498 */ 1499 SkScalar mapRadius(SkScalar radius) const; 1500 1501 /** Returns true if a unit step on x-axis at some y-axis value mapped through SkMatrix 1502 can be represented by a constant vector. Returns true if getType() returns 1503 kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask. 1504 1505 May return true if getType() returns kPerspective_Mask, but only when SkMatrix 1506 does not include rotation or skewing along the y-axis. 1507 1508 @return true if SkMatrix does not have complex perspective 1509 */ 1510 bool isFixedStepInX() const; 1511 1512 /** Returns vector representing a unit step on x-axis at y mapped through SkMatrix. 1513 If isFixedStepInX() is false, returned value is undefined. 1514 1515 @param y position of line parallel to x-axis 1516 @return vector advance of mapped unit step on x-axis 1517 */ 1518 SkVector fixedStepInX(SkScalar y) const; 1519 1520 /** Returns true if SkMatrix equals m, using an efficient comparison. 1521 1522 Returns false when the sign of zero values is the different; when one 1523 matrix has positive zero value and the other has negative zero value. 1524 1525 Returns true even when both SkMatrix contain NaN. 1526 1527 NaN never equals any value, including itself. To improve performance, NaN values 1528 are treated as bit patterns that are equal if their bit patterns are equal. 1529 1530 @param m SkMatrix to compare 1531 @return true if m and SkMatrix are represented by identical bit patterns 1532 */ cheapEqualTo(const SkMatrix & m)1533 bool cheapEqualTo(const SkMatrix& m) const { 1534 return 0 == memcmp(fMat, m.fMat, sizeof(fMat)); 1535 } 1536 1537 /** Compares a and b; returns true if a and b are numerically equal. Returns true 1538 even if sign of zero values are different. Returns false if either SkMatrix 1539 contains NaN, even if the other SkMatrix also contains NaN. 1540 1541 @param a SkMatrix to compare 1542 @param b SkMatrix to compare 1543 @return true if SkMatrix a and SkMatrix b are numerically equal 1544 */ 1545 friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b); 1546 1547 /** Compares a and b; returns true if a and b are not numerically equal. Returns false 1548 even if sign of zero values are different. Returns true if either SkMatrix 1549 contains NaN, even if the other SkMatrix also contains NaN. 1550 1551 @param a SkMatrix to compare 1552 @param b SkMatrix to compare 1553 @return true if SkMatrix a and SkMatrix b are numerically not equal 1554 */ 1555 friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) { 1556 return !(a == b); 1557 } 1558 1559 /** Writes text representation of SkMatrix to standard output. Floating point values 1560 are written with limited precision; it may not be possible to reconstruct 1561 original SkMatrix from output. 1562 */ 1563 void dump() const; 1564 1565 /** Returns the minimum scaling factor of SkMatrix by decomposing the scaling and 1566 skewing elements. 1567 Returns -1 if scale factor overflows or SkMatrix contains perspective. 1568 1569 @return minimum scale factor 1570 */ 1571 SkScalar getMinScale() const; 1572 1573 /** Returns the maximum scaling factor of SkMatrix by decomposing the scaling and 1574 skewing elements. 1575 Returns -1 if scale factor overflows or SkMatrix contains perspective. 1576 1577 @return maximum scale factor 1578 */ 1579 SkScalar getMaxScale() const; 1580 1581 /** Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the 1582 maximum scaling factor. Scaling factors are computed by decomposing 1583 the SkMatrix scaling and skewing elements. 1584 1585 Returns true if scaleFactors are found; otherwise, returns false and sets 1586 scaleFactors to undefined values. 1587 1588 @param scaleFactors storage for minimum and maximum scale factors 1589 @return true if scale factors were computed correctly 1590 */ 1591 bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const; 1592 1593 /** Decomposes SkMatrix into scale components and whatever remains. Returns false if 1594 SkMatrix could not be decomposed. 1595 1596 Sets scale to portion of SkMatrix that scale axes. Sets remaining to SkMatrix 1597 with scaling factored out. remaining may be passed as nullptr 1598 to determine if SkMatrix can be decomposed without computing remainder. 1599 1600 Returns true if scale components are found. scale and remaining are 1601 unchanged if SkMatrix contains perspective; scale factors are not finite, or 1602 are nearly zero. 1603 1604 On success: Matrix = scale * Remaining. 1605 1606 @param scale axes scaling factors; may be nullptr 1607 @param remaining SkMatrix without scaling; may be nullptr 1608 @return true if scale can be computed 1609 */ 1610 bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const; 1611 1612 /** Returns reference to const identity SkMatrix. Returned SkMatrix is set to: 1613 1614 | 1 0 0 | 1615 | 0 1 0 | 1616 | 0 0 1 | 1617 1618 @return const identity SkMatrix 1619 */ 1620 static const SkMatrix& I(); 1621 1622 /** Returns reference to a const SkMatrix with invalid values. Returned SkMatrix is set 1623 to: 1624 1625 | SK_ScalarMax SK_ScalarMax SK_ScalarMax | 1626 | SK_ScalarMax SK_ScalarMax SK_ScalarMax | 1627 | SK_ScalarMax SK_ScalarMax SK_ScalarMax | 1628 1629 @return const invalid SkMatrix 1630 */ 1631 static const SkMatrix& InvalidMatrix(); 1632 1633 /** Returns SkMatrix a multiplied by SkMatrix b. 1634 1635 Given: 1636 1637 | A B C | | J K L | 1638 a = | D E F |, b = | M N O | 1639 | G H I | | P Q R | 1640 1641 sets SkMatrix to: 1642 1643 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 1644 a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 1645 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 1646 1647 @param a SkMatrix on left side of multiply expression 1648 @param b SkMatrix on right side of multiply expression 1649 @return SkMatrix computed from a times b 1650 */ Concat(const SkMatrix & a,const SkMatrix & b)1651 static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) { 1652 SkMatrix result; 1653 result.setConcat(a, b); 1654 return result; 1655 } 1656 1657 /** Sets internal cache to unknown state. Use to force update after repeated 1658 modifications to SkMatrix element reference returned by operator[](int index). 1659 */ dirtyMatrixTypeCache()1660 void dirtyMatrixTypeCache() { 1661 this->setTypeMask(kUnknown_Mask); 1662 } 1663 1664 /** Initializes SkMatrix with scale and translate elements. 1665 1666 | sx 0 tx | 1667 | 0 sy ty | 1668 | 0 0 1 | 1669 1670 @param sx horizontal scale factor to store 1671 @param sy vertical scale factor to store 1672 @param tx horizontal translation to store 1673 @param ty vertical translation to store 1674 */ setScaleTranslate(SkScalar sx,SkScalar sy,SkScalar tx,SkScalar ty)1675 void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) { 1676 fMat[kMScaleX] = sx; 1677 fMat[kMSkewX] = 0; 1678 fMat[kMTransX] = tx; 1679 1680 fMat[kMSkewY] = 0; 1681 fMat[kMScaleY] = sy; 1682 fMat[kMTransY] = ty; 1683 1684 fMat[kMPersp0] = 0; 1685 fMat[kMPersp1] = 0; 1686 fMat[kMPersp2] = 1; 1687 1688 unsigned mask = 0; 1689 if (sx != 1 || sy != 1) { 1690 mask |= kScale_Mask; 1691 } 1692 if (tx || ty) { 1693 mask |= kTranslate_Mask; 1694 } 1695 this->setTypeMask(mask | kRectStaysRect_Mask); 1696 } 1697 1698 /** Returns true if all elements of the matrix are finite. Returns false if any 1699 element is infinity, or NaN. 1700 1701 @return true if matrix has only finite elements 1702 */ isFinite()1703 bool isFinite() const { return SkScalarsAreFinite(fMat, 9); } 1704 1705 private: 1706 /** Set if the matrix will map a rectangle to another rectangle. This 1707 can be true if the matrix is scale-only, or rotates a multiple of 1708 90 degrees. 1709 1710 This bit will be set on identity matrices 1711 */ 1712 static constexpr int kRectStaysRect_Mask = 0x10; 1713 1714 /** Set if the perspective bit is valid even though the rest of 1715 the matrix is Unknown. 1716 */ 1717 static constexpr int kOnlyPerspectiveValid_Mask = 0x40; 1718 1719 static constexpr int kUnknown_Mask = 0x80; 1720 1721 static constexpr int kORableMasks = kTranslate_Mask | 1722 kScale_Mask | 1723 kAffine_Mask | 1724 kPerspective_Mask; 1725 1726 static constexpr int kAllMasks = kTranslate_Mask | 1727 kScale_Mask | 1728 kAffine_Mask | 1729 kPerspective_Mask | 1730 kRectStaysRect_Mask; 1731 1732 SkScalar fMat[9]; 1733 mutable uint32_t fTypeMask; 1734 1735 static void ComputeInv(SkScalar dst[9], const SkScalar src[9], double invDet, bool isPersp); 1736 1737 uint8_t computeTypeMask() const; 1738 uint8_t computePerspectiveTypeMask() const; 1739 setTypeMask(int mask)1740 void setTypeMask(int mask) { 1741 // allow kUnknown or a valid mask 1742 SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask || 1743 ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask) 1744 == (kUnknown_Mask | kOnlyPerspectiveValid_Mask)); 1745 fTypeMask = SkToU8(mask); 1746 } 1747 orTypeMask(int mask)1748 void orTypeMask(int mask) { 1749 SkASSERT((mask & kORableMasks) == mask); 1750 fTypeMask = SkToU8(fTypeMask | mask); 1751 } 1752 clearTypeMask(int mask)1753 void clearTypeMask(int mask) { 1754 // only allow a valid mask 1755 SkASSERT((mask & kAllMasks) == mask); 1756 fTypeMask = fTypeMask & ~mask; 1757 } 1758 getPerspectiveTypeMaskOnly()1759 TypeMask getPerspectiveTypeMaskOnly() const { 1760 if ((fTypeMask & kUnknown_Mask) && 1761 !(fTypeMask & kOnlyPerspectiveValid_Mask)) { 1762 fTypeMask = this->computePerspectiveTypeMask(); 1763 } 1764 return (TypeMask)(fTypeMask & 0xF); 1765 } 1766 1767 /** Returns true if we already know that the matrix is identity; 1768 false otherwise. 1769 */ isTriviallyIdentity()1770 bool isTriviallyIdentity() const { 1771 if (fTypeMask & kUnknown_Mask) { 1772 return false; 1773 } 1774 return ((fTypeMask & 0xF) == 0); 1775 } 1776 updateTranslateMask()1777 inline void updateTranslateMask() { 1778 if ((fMat[kMTransX] != 0) | (fMat[kMTransY] != 0)) { 1779 fTypeMask |= kTranslate_Mask; 1780 } else { 1781 fTypeMask &= ~kTranslate_Mask; 1782 } 1783 } 1784 1785 typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y, 1786 SkPoint* result); 1787 GetMapXYProc(TypeMask mask)1788 static MapXYProc GetMapXYProc(TypeMask mask) { 1789 SkASSERT((mask & ~kAllMasks) == 0); 1790 return gMapXYProcs[mask & kAllMasks]; 1791 } 1792 getMapXYProc()1793 MapXYProc getMapXYProc() const { 1794 return GetMapXYProc(this->getType()); 1795 } 1796 1797 typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[], 1798 const SkPoint src[], int count); 1799 GetMapPtsProc(TypeMask mask)1800 static MapPtsProc GetMapPtsProc(TypeMask mask) { 1801 SkASSERT((mask & ~kAllMasks) == 0); 1802 return gMapPtsProcs[mask & kAllMasks]; 1803 } 1804 getMapPtsProc()1805 MapPtsProc getMapPtsProc() const { 1806 return GetMapPtsProc(this->getType()); 1807 } 1808 1809 bool SK_WARN_UNUSED_RESULT invertNonIdentity(SkMatrix* inverse) const; 1810 1811 static bool Poly2Proc(const SkPoint[], SkMatrix*); 1812 static bool Poly3Proc(const SkPoint[], SkMatrix*); 1813 static bool Poly4Proc(const SkPoint[], SkMatrix*); 1814 1815 static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1816 static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1817 static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1818 static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1819 static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1820 static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1821 static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1822 1823 static const MapXYProc gMapXYProcs[]; 1824 1825 static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int); 1826 static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1827 static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1828 static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], 1829 int count); 1830 static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1831 1832 static void Affine_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1833 1834 static const MapPtsProc gMapPtsProcs[]; 1835 1836 // return the number of bytes written, whether or not buffer is null 1837 size_t writeToMemory(void* buffer) const; 1838 /** 1839 * Reads data from the buffer parameter 1840 * 1841 * @param buffer Memory to read from 1842 * @param length Amount of memory available in the buffer 1843 * @return number of bytes read (must be a multiple of 4) or 1844 * 0 if there was not enough memory available 1845 */ 1846 size_t readFromMemory(const void* buffer, size_t length); 1847 1848 friend class SkPerspIter; 1849 friend class SkMatrixPriv; 1850 friend class SkReader32; 1851 friend class SerializationTest; 1852 }; 1853 SK_END_REQUIRE_DENSE 1854 1855 #endif 1856