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 */ mapPoints(SkPoint dst[],const SkPoint src[],int count)1228 void mapPoints(SkPoint dst[], const SkPoint src[], int count) const { 1229 SkASSERT((dst && src && count > 0) || 0 == count); 1230 // no partial overlap 1231 SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]); 1232 this->getMapPtsProc()(*this, dst, src, count); 1233 } 1234 1235 /** Maps pts SkPoint array of length count in place. SkPoint are mapped by multiplying 1236 each SkPoint by SkMatrix. Given: 1237 1238 | A B C | | x | 1239 Matrix = | D E F |, pt = | y | 1240 | G H I | | 1 | 1241 1242 where 1243 1244 for (i = 0; i < count; ++i) { 1245 x = pts[i].fX 1246 y = pts[i].fY 1247 } 1248 1249 each resulting pts SkPoint is computed as: 1250 1251 |A B C| |x| Ax+By+C Dx+Ey+F 1252 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1253 |G H I| |1| Gx+Hy+I Gx+Hy+I 1254 1255 @param pts storage for mapped SkPoint 1256 @param count number of SkPoint to transform 1257 */ mapPoints(SkPoint pts[],int count)1258 void mapPoints(SkPoint pts[], int count) const { 1259 this->mapPoints(pts, pts, count); 1260 } 1261 1262 /** Maps src SkPoint3 array of length count to dst SkPoint3 array, which must of length count or 1263 greater. SkPoint3 array is mapped by multiplying each SkPoint3 by SkMatrix. Given: 1264 1265 | A B C | | x | 1266 Matrix = | D E F |, src = | y | 1267 | G H I | | z | 1268 1269 each resulting dst SkPoint is computed as: 1270 1271 |A B C| |x| 1272 Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz| 1273 |G H I| |z| 1274 1275 @param dst storage for mapped SkPoint3 array 1276 @param src SkPoint3 array to transform 1277 @param count items in SkPoint3 array to transform 1278 */ 1279 void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const; 1280 1281 /** Maps SkPoint (x, y) to result. SkPoint is mapped by multiplying by SkMatrix. Given: 1282 1283 | A B C | | x | 1284 Matrix = | D E F |, pt = | y | 1285 | G H I | | 1 | 1286 1287 result is computed as: 1288 1289 |A B C| |x| Ax+By+C Dx+Ey+F 1290 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1291 |G H I| |1| Gx+Hy+I Gx+Hy+I 1292 1293 @param x x-axis value of SkPoint to map 1294 @param y y-axis value of SkPoint to map 1295 @param result storage for mapped SkPoint 1296 */ mapXY(SkScalar x,SkScalar y,SkPoint * result)1297 void mapXY(SkScalar x, SkScalar y, SkPoint* result) const { 1298 SkASSERT(result); 1299 this->getMapXYProc()(*this, x, y, result); 1300 } 1301 1302 /** Returns SkPoint (x, y) multiplied by SkMatrix. Given: 1303 1304 | A B C | | x | 1305 Matrix = | D E F |, pt = | y | 1306 | G H I | | 1 | 1307 1308 result is computed as: 1309 1310 |A B C| |x| Ax+By+C Dx+Ey+F 1311 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1312 |G H I| |1| Gx+Hy+I Gx+Hy+I 1313 1314 @param x x-axis value of SkPoint to map 1315 @param y y-axis value of SkPoint to map 1316 @return mapped SkPoint 1317 */ mapXY(SkScalar x,SkScalar y)1318 SkPoint mapXY(SkScalar x, SkScalar y) const { 1319 SkPoint result; 1320 this->getMapXYProc()(*this, x, y, &result); 1321 return result; 1322 } 1323 1324 /** Maps src vector array of length count to vector SkPoint array of equal or greater 1325 length. Vectors are mapped by multiplying each vector by SkMatrix, treating 1326 SkMatrix translation as zero. Given: 1327 1328 | A B 0 | | x | 1329 Matrix = | D E 0 |, src = | y | 1330 | G H I | | 1 | 1331 1332 where 1333 1334 for (i = 0; i < count; ++i) { 1335 x = src[i].fX 1336 y = src[i].fY 1337 } 1338 1339 each dst vector is computed as: 1340 1341 |A B 0| |x| Ax+By Dx+Ey 1342 Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , ------- 1343 |G H I| |1| Gx+Hy+I Gx+Hy+I 1344 1345 src and dst may point to the same storage. 1346 1347 @param dst storage for mapped vectors 1348 @param src vectors to transform 1349 @param count number of vectors to transform 1350 */ 1351 void mapVectors(SkVector dst[], const SkVector src[], int count) const; 1352 1353 /** Maps vecs vector array of length count in place, multiplying each vector by 1354 SkMatrix, treating SkMatrix translation as zero. Given: 1355 1356 | A B 0 | | x | 1357 Matrix = | D E 0 |, vec = | y | 1358 | G H I | | 1 | 1359 1360 where 1361 1362 for (i = 0; i < count; ++i) { 1363 x = vecs[i].fX 1364 y = vecs[i].fY 1365 } 1366 1367 each result vector is computed as: 1368 1369 |A B 0| |x| Ax+By Dx+Ey 1370 Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , ------- 1371 |G H I| |1| Gx+Hy+I Gx+Hy+I 1372 1373 @param vecs vectors to transform, and storage for mapped vectors 1374 @param count number of vectors to transform 1375 */ mapVectors(SkVector vecs[],int count)1376 void mapVectors(SkVector vecs[], int count) const { 1377 this->mapVectors(vecs, vecs, count); 1378 } 1379 1380 /** Maps vector (dx, dy) to result. Vector is mapped by multiplying by SkMatrix, 1381 treating SkMatrix translation as zero. Given: 1382 1383 | A B 0 | | dx | 1384 Matrix = | D E 0 |, vec = | dy | 1385 | G H I | | 1 | 1386 1387 each result vector is computed as: 1388 1389 |A B 0| |dx| A*dx+B*dy D*dx+E*dy 1390 Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , ----------- 1391 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I 1392 1393 @param dx x-axis value of vector to map 1394 @param dy y-axis value of vector to map 1395 @param result storage for mapped vector 1396 */ mapVector(SkScalar dx,SkScalar dy,SkVector * result)1397 void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const { 1398 SkVector vec = { dx, dy }; 1399 this->mapVectors(result, &vec, 1); 1400 } 1401 1402 /** Returns vector (dx, dy) multiplied by SkMatrix, treating SkMatrix translation as zero. 1403 Given: 1404 1405 | A B 0 | | dx | 1406 Matrix = | D E 0 |, vec = | dy | 1407 | G H I | | 1 | 1408 1409 each result vector is computed as: 1410 1411 |A B 0| |dx| A*dx+B*dy D*dx+E*dy 1412 Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , ----------- 1413 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I 1414 1415 @param dx x-axis value of vector to map 1416 @param dy y-axis value of vector to map 1417 @return mapped vector 1418 */ mapVector(SkScalar dx,SkScalar dy)1419 SkVector mapVector(SkScalar dx, SkScalar dy) const { 1420 SkVector vec = { dx, dy }; 1421 this->mapVectors(&vec, &vec, 1); 1422 return vec; 1423 } 1424 1425 /** Sets dst to bounds of src corners mapped by SkMatrix. 1426 Returns true if mapped corners are dst corners. 1427 1428 Returned value is the same as calling rectStaysRect(). 1429 1430 @param dst storage for bounds of mapped SkPoint 1431 @param src SkRect to map 1432 @return true if dst is equivalent to mapped src 1433 */ 1434 bool mapRect(SkRect* dst, const SkRect& src) const; 1435 1436 /** Sets rect to bounds of rect corners mapped by SkMatrix. 1437 Returns true if mapped corners are computed rect corners. 1438 1439 Returned value is the same as calling rectStaysRect(). 1440 1441 @param rect rectangle to map, and storage for bounds of mapped corners 1442 @return true if result is equivalent to mapped rect 1443 */ mapRect(SkRect * rect)1444 bool mapRect(SkRect* rect) const { 1445 return this->mapRect(rect, *rect); 1446 } 1447 1448 /** Returns bounds of src corners mapped by SkMatrix. 1449 1450 @param src rectangle to map 1451 @return mapped bounds 1452 */ mapRect(const SkRect & src)1453 SkRect mapRect(const SkRect& src) const { 1454 SkRect dst; 1455 (void)this->mapRect(&dst, src); 1456 return dst; 1457 } 1458 1459 /** Maps four corners of rect to dst. SkPoint are mapped by multiplying each 1460 rect corner by SkMatrix. rect corner is processed in this order: 1461 (rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), 1462 (rect.fLeft, rect.fBottom). 1463 1464 rect may be empty: rect.fLeft may be greater than or equal to rect.fRight; 1465 rect.fTop may be greater than or equal to rect.fBottom. 1466 1467 Given: 1468 1469 | A B C | | x | 1470 Matrix = | D E F |, pt = | y | 1471 | G H I | | 1 | 1472 1473 where pt is initialized from each of (rect.fLeft, rect.fTop), 1474 (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom), 1475 each dst SkPoint is computed as: 1476 1477 |A B C| |x| Ax+By+C Dx+Ey+F 1478 Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , ------- 1479 |G H I| |1| Gx+Hy+I Gx+Hy+I 1480 1481 @param dst storage for mapped corner SkPoint 1482 @param rect SkRect to map 1483 */ mapRectToQuad(SkPoint dst[4],const SkRect & rect)1484 void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const { 1485 // This could potentially be faster if we only transformed each x and y of the rect once. 1486 rect.toQuad(dst); 1487 this->mapPoints(dst, 4); 1488 } 1489 1490 /** Sets dst to bounds of src corners mapped by SkMatrix. If matrix contains 1491 elements other than scale or translate: asserts if SK_DEBUG is defined; 1492 otherwise, results are undefined. 1493 1494 @param dst storage for bounds of mapped SkPoint 1495 @param src SkRect to map 1496 */ 1497 void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const; 1498 1499 /** Returns geometric mean radius of ellipse formed by constructing circle of 1500 size radius, and mapping constructed circle with SkMatrix. The result squared is 1501 equal to the major axis length times the minor axis length. 1502 Result is not meaningful if SkMatrix contains perspective elements. 1503 1504 @param radius circle size to map 1505 @return average mapped radius 1506 */ 1507 SkScalar mapRadius(SkScalar radius) const; 1508 1509 /** Returns true if a unit step on x-axis at some y-axis value mapped through SkMatrix 1510 can be represented by a constant vector. Returns true if getType() returns 1511 kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask. 1512 1513 May return true if getType() returns kPerspective_Mask, but only when SkMatrix 1514 does not include rotation or skewing along the y-axis. 1515 1516 @return true if SkMatrix does not have complex perspective 1517 */ 1518 bool isFixedStepInX() const; 1519 1520 /** Returns vector representing a unit step on x-axis at y mapped through SkMatrix. 1521 If isFixedStepInX() is false, returned value is undefined. 1522 1523 @param y position of line parallel to x-axis 1524 @return vector advance of mapped unit step on x-axis 1525 */ 1526 SkVector fixedStepInX(SkScalar y) const; 1527 1528 /** Returns true if SkMatrix equals m, using an efficient comparison. 1529 1530 Returns false when the sign of zero values is the different; when one 1531 matrix has positive zero value and the other has negative zero value. 1532 1533 Returns true even when both SkMatrix contain NaN. 1534 1535 NaN never equals any value, including itself. To improve performance, NaN values 1536 are treated as bit patterns that are equal if their bit patterns are equal. 1537 1538 @param m SkMatrix to compare 1539 @return true if m and SkMatrix are represented by identical bit patterns 1540 */ cheapEqualTo(const SkMatrix & m)1541 bool cheapEqualTo(const SkMatrix& m) const { 1542 return 0 == memcmp(fMat, m.fMat, sizeof(fMat)); 1543 } 1544 1545 /** Compares a and b; returns true if a and b are numerically equal. Returns true 1546 even if sign of zero values are different. Returns false if either SkMatrix 1547 contains NaN, even if the other SkMatrix also contains NaN. 1548 1549 @param a SkMatrix to compare 1550 @param b SkMatrix to compare 1551 @return true if SkMatrix a and SkMatrix b are numerically equal 1552 */ 1553 friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b); 1554 1555 /** Compares a and b; returns true if a and b are not numerically equal. Returns false 1556 even if sign of zero values are different. Returns true if either SkMatrix 1557 contains NaN, even if the other SkMatrix also contains NaN. 1558 1559 @param a SkMatrix to compare 1560 @param b SkMatrix to compare 1561 @return true if SkMatrix a and SkMatrix b are numerically not equal 1562 */ 1563 friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) { 1564 return !(a == b); 1565 } 1566 1567 /** Writes text representation of SkMatrix to standard output. Floating point values 1568 are written with limited precision; it may not be possible to reconstruct 1569 original SkMatrix from output. 1570 */ 1571 void dump() const; 1572 1573 /** Returns the minimum 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 minimum scale factor 1578 */ 1579 SkScalar getMinScale() const; 1580 1581 /** Returns the maximum scaling factor of SkMatrix by decomposing the scaling and 1582 skewing elements. 1583 Returns -1 if scale factor overflows or SkMatrix contains perspective. 1584 1585 @return maximum scale factor 1586 */ 1587 SkScalar getMaxScale() const; 1588 1589 /** Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the 1590 maximum scaling factor. Scaling factors are computed by decomposing 1591 the SkMatrix scaling and skewing elements. 1592 1593 Returns true if scaleFactors are found; otherwise, returns false and sets 1594 scaleFactors to undefined values. 1595 1596 @param scaleFactors storage for minimum and maximum scale factors 1597 @return true if scale factors were computed correctly 1598 */ 1599 bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const; 1600 1601 /** Decomposes SkMatrix into scale components and whatever remains. Returns false if 1602 SkMatrix could not be decomposed. 1603 1604 Sets scale to portion of SkMatrix that scale axes. Sets remaining to SkMatrix 1605 with scaling factored out. remaining may be passed as nullptr 1606 to determine if SkMatrix can be decomposed without computing remainder. 1607 1608 Returns true if scale components are found. scale and remaining are 1609 unchanged if SkMatrix contains perspective; scale factors are not finite, or 1610 are nearly zero. 1611 1612 On success: Matrix = scale * Remaining. 1613 1614 @param scale axes scaling factors; may be nullptr 1615 @param remaining SkMatrix without scaling; may be nullptr 1616 @return true if scale can be computed 1617 */ 1618 bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const; 1619 1620 /** Returns reference to const identity SkMatrix. Returned SkMatrix is set to: 1621 1622 | 1 0 0 | 1623 | 0 1 0 | 1624 | 0 0 1 | 1625 1626 @return const identity SkMatrix 1627 */ 1628 static const SkMatrix& I(); 1629 1630 /** Returns reference to a const SkMatrix with invalid values. Returned SkMatrix is set 1631 to: 1632 1633 | SK_ScalarMax SK_ScalarMax SK_ScalarMax | 1634 | SK_ScalarMax SK_ScalarMax SK_ScalarMax | 1635 | SK_ScalarMax SK_ScalarMax SK_ScalarMax | 1636 1637 @return const invalid SkMatrix 1638 */ 1639 static const SkMatrix& InvalidMatrix(); 1640 1641 /** Returns SkMatrix a multiplied by SkMatrix b. 1642 1643 Given: 1644 1645 | A B C | | J K L | 1646 a = | D E F |, b = | M N O | 1647 | G H I | | P Q R | 1648 1649 sets SkMatrix to: 1650 1651 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR | 1652 a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR | 1653 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR | 1654 1655 @param a SkMatrix on left side of multiply expression 1656 @param b SkMatrix on right side of multiply expression 1657 @return SkMatrix computed from a times b 1658 */ Concat(const SkMatrix & a,const SkMatrix & b)1659 static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) { 1660 SkMatrix result; 1661 result.setConcat(a, b); 1662 return result; 1663 } 1664 1665 /** Sets internal cache to unknown state. Use to force update after repeated 1666 modifications to SkMatrix element reference returned by operator[](int index). 1667 */ dirtyMatrixTypeCache()1668 void dirtyMatrixTypeCache() { 1669 this->setTypeMask(kUnknown_Mask); 1670 } 1671 1672 /** Initializes SkMatrix with scale and translate elements. 1673 1674 | sx 0 tx | 1675 | 0 sy ty | 1676 | 0 0 1 | 1677 1678 @param sx horizontal scale factor to store 1679 @param sy vertical scale factor to store 1680 @param tx horizontal translation to store 1681 @param ty vertical translation to store 1682 */ setScaleTranslate(SkScalar sx,SkScalar sy,SkScalar tx,SkScalar ty)1683 void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) { 1684 fMat[kMScaleX] = sx; 1685 fMat[kMSkewX] = 0; 1686 fMat[kMTransX] = tx; 1687 1688 fMat[kMSkewY] = 0; 1689 fMat[kMScaleY] = sy; 1690 fMat[kMTransY] = ty; 1691 1692 fMat[kMPersp0] = 0; 1693 fMat[kMPersp1] = 0; 1694 fMat[kMPersp2] = 1; 1695 1696 unsigned mask = 0; 1697 if (sx != 1 || sy != 1) { 1698 mask |= kScale_Mask; 1699 } 1700 if (tx || ty) { 1701 mask |= kTranslate_Mask; 1702 } 1703 this->setTypeMask(mask | kRectStaysRect_Mask); 1704 } 1705 1706 /** Returns true if all elements of the matrix are finite. Returns false if any 1707 element is infinity, or NaN. 1708 1709 @return true if matrix has only finite elements 1710 */ isFinite()1711 bool isFinite() const { return SkScalarsAreFinite(fMat, 9); } 1712 1713 private: 1714 /** Set if the matrix will map a rectangle to another rectangle. This 1715 can be true if the matrix is scale-only, or rotates a multiple of 1716 90 degrees. 1717 1718 This bit will be set on identity matrices 1719 */ 1720 static constexpr int kRectStaysRect_Mask = 0x10; 1721 1722 /** Set if the perspective bit is valid even though the rest of 1723 the matrix is Unknown. 1724 */ 1725 static constexpr int kOnlyPerspectiveValid_Mask = 0x40; 1726 1727 static constexpr int kUnknown_Mask = 0x80; 1728 1729 static constexpr int kORableMasks = kTranslate_Mask | 1730 kScale_Mask | 1731 kAffine_Mask | 1732 kPerspective_Mask; 1733 1734 static constexpr int kAllMasks = kTranslate_Mask | 1735 kScale_Mask | 1736 kAffine_Mask | 1737 kPerspective_Mask | 1738 kRectStaysRect_Mask; 1739 1740 SkScalar fMat[9]; 1741 mutable uint32_t fTypeMask; 1742 1743 static void ComputeInv(SkScalar dst[9], const SkScalar src[9], double invDet, bool isPersp); 1744 1745 uint8_t computeTypeMask() const; 1746 uint8_t computePerspectiveTypeMask() const; 1747 setTypeMask(int mask)1748 void setTypeMask(int mask) { 1749 // allow kUnknown or a valid mask 1750 SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask || 1751 ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask) 1752 == (kUnknown_Mask | kOnlyPerspectiveValid_Mask)); 1753 fTypeMask = SkToU8(mask); 1754 } 1755 orTypeMask(int mask)1756 void orTypeMask(int mask) { 1757 SkASSERT((mask & kORableMasks) == mask); 1758 fTypeMask = SkToU8(fTypeMask | mask); 1759 } 1760 clearTypeMask(int mask)1761 void clearTypeMask(int mask) { 1762 // only allow a valid mask 1763 SkASSERT((mask & kAllMasks) == mask); 1764 fTypeMask = fTypeMask & ~mask; 1765 } 1766 getPerspectiveTypeMaskOnly()1767 TypeMask getPerspectiveTypeMaskOnly() const { 1768 if ((fTypeMask & kUnknown_Mask) && 1769 !(fTypeMask & kOnlyPerspectiveValid_Mask)) { 1770 fTypeMask = this->computePerspectiveTypeMask(); 1771 } 1772 return (TypeMask)(fTypeMask & 0xF); 1773 } 1774 1775 /** Returns true if we already know that the matrix is identity; 1776 false otherwise. 1777 */ isTriviallyIdentity()1778 bool isTriviallyIdentity() const { 1779 if (fTypeMask & kUnknown_Mask) { 1780 return false; 1781 } 1782 return ((fTypeMask & 0xF) == 0); 1783 } 1784 updateTranslateMask()1785 inline void updateTranslateMask() { 1786 if ((fMat[kMTransX] != 0) | (fMat[kMTransY] != 0)) { 1787 fTypeMask |= kTranslate_Mask; 1788 } else { 1789 fTypeMask &= ~kTranslate_Mask; 1790 } 1791 } 1792 1793 typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y, 1794 SkPoint* result); 1795 GetMapXYProc(TypeMask mask)1796 static MapXYProc GetMapXYProc(TypeMask mask) { 1797 SkASSERT((mask & ~kAllMasks) == 0); 1798 return gMapXYProcs[mask & kAllMasks]; 1799 } 1800 getMapXYProc()1801 MapXYProc getMapXYProc() const { 1802 return GetMapXYProc(this->getType()); 1803 } 1804 1805 typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[], 1806 const SkPoint src[], int count); 1807 GetMapPtsProc(TypeMask mask)1808 static MapPtsProc GetMapPtsProc(TypeMask mask) { 1809 SkASSERT((mask & ~kAllMasks) == 0); 1810 return gMapPtsProcs[mask & kAllMasks]; 1811 } 1812 getMapPtsProc()1813 MapPtsProc getMapPtsProc() const { 1814 return GetMapPtsProc(this->getType()); 1815 } 1816 1817 bool SK_WARN_UNUSED_RESULT invertNonIdentity(SkMatrix* inverse) const; 1818 1819 static bool Poly2Proc(const SkPoint[], SkMatrix*); 1820 static bool Poly3Proc(const SkPoint[], SkMatrix*); 1821 static bool Poly4Proc(const SkPoint[], SkMatrix*); 1822 1823 static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1824 static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1825 static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1826 static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1827 static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1828 static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1829 static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*); 1830 1831 static const MapXYProc gMapXYProcs[]; 1832 1833 static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int); 1834 static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1835 static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1836 static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], 1837 int count); 1838 static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1839 1840 static void Affine_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); 1841 1842 static const MapPtsProc gMapPtsProcs[]; 1843 1844 // return the number of bytes written, whether or not buffer is null 1845 size_t writeToMemory(void* buffer) const; 1846 /** 1847 * Reads data from the buffer parameter 1848 * 1849 * @param buffer Memory to read from 1850 * @param length Amount of memory available in the buffer 1851 * @return number of bytes read (must be a multiple of 4) or 1852 * 0 if there was not enough memory available 1853 */ 1854 size_t readFromMemory(const void* buffer, size_t length); 1855 1856 friend class SkPerspIter; 1857 friend class SkMatrixPriv; 1858 friend class SkReader32; 1859 friend class SerializationTest; 1860 }; 1861 SK_END_REQUIRE_DENSE 1862 1863 #endif 1864