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