blob: 107457c5a63d6e705a2ed8ea92efc6d6bb059fa1 [file] [log] [blame]
Cary Clarkbc5697d2017-10-04 14:31:33 -04001#Topic Matrix
Cary Clark154beea2017-10-26 07:58:48 -04002#Alias Matrices
Cary Clarkbc5697d2017-10-04 14:31:33 -04003#Alias Matrix_Reference
4
5#Class SkMatrix
6
Cary Clark154beea2017-10-26 07:58:48 -04007Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping
8Points and Vectors with translation, scaling, skewing, rotation, and
9perspective.
Cary Clark884dd7d2017-10-11 10:37:52 -040010
Cary Clark154beea2017-10-26 07:58:48 -040011Matrix elements are in row major order. Matrix does not have a constructor,
12so it must be explicitly initialized. setIdentity initializes Matrix
13so it has no effect. setTranslate, setScale, setSkew, setRotate, set9 and setAll
14initializes all Matrix elements with the corresponding mapping.
Cary Clark884dd7d2017-10-11 10:37:52 -040015
Cary Clark154beea2017-10-26 07:58:48 -040016Matrix includes a hidden variable that classifies the type of matrix to
17improve performance. Matrix is not thread safe unless getType is called first.
Cary Clarkbc5697d2017-10-04 14:31:33 -040018
19#Topic Overview
20
21#Subtopic Subtopics
22#ToDo manually add subtopics ##
23#Table
24#Legend
25# topics # description ##
26#Legend ##
27#Table ##
28##
29
30#Subtopic Operators
31#Table
32#Legend
Cary Clark154beea2017-10-26 07:58:48 -040033# function # description ##
Cary Clarkbc5697d2017-10-04 14:31:33 -040034#Legend ##
Cary Clark154beea2017-10-26 07:58:48 -040035# operator!=(const SkMatrix& a, const SkMatrix& b) # Returns true if members are unequal. ##
36# operator==(const SkMatrix& a, const SkMatrix& b) # Returns true if members are equal. ##
37# operator[](int index) const # Returns Matrix value. ##
38# operator[](int index) # Returns writable reference to Matrix value. ##
Cary Clarkbc5697d2017-10-04 14:31:33 -040039#Table ##
40#Subtopic ##
41
42#Subtopic Member_Functions
43#Table
44#Legend
Cary Clark154beea2017-10-26 07:58:48 -040045# function # description ##
Cary Clarkbc5697d2017-10-04 14:31:33 -040046#Legend ##
Cary Clark884dd7d2017-10-11 10:37:52 -040047# Concat # Returns the concatenation of Matrix pair. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040048# I # Returns a reference to a const identity Matrix. ##
49# InvalidMatrix # Returns a reference to a const invalid Matrix. ##
Cary Clarkbef063a2017-10-31 15:44:45 -040050# MakeAll # Constructs all nine values. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040051# MakeRectToRect # Constructs from source Rect to destination Rect. ##
52# MakeScale # Constructs from scale in x and y. ##
53# MakeTrans # Constructs from translate in x and y. ##
Cary Clark154beea2017-10-26 07:58:48 -040054# SetAffineIdentity # Sets 3x2 array to identity. ##
55# asAffine # Copies to 3x2 array. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040056# cheapEqualTo # Compares Matrix pair using memcmp(). ##
57# decomposeScale # Separates scale if possible. ##
Cary Clark154beea2017-10-26 07:58:48 -040058# dirtyMatrixTypeCache # Sets internal cache to unknown state. ##
59# dump() # Sends text representation using floats to standard output. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040060# fixedStepInX # Returns step in x for a position in y. ##
Cary Clark154beea2017-10-26 07:58:48 -040061# get() # Returns one of nine Matrix values. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040062# get9 # Returns all nine Matrix values. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040063# getMaxScale # Returns maximum scaling, if possible. ##
64# getMinMaxScales # Returns minimum and maximum scaling, if possible. ##
65# getMinScale # Returns minimum scaling, if possible. ##
Cary Clark154beea2017-10-26 07:58:48 -040066# getPerspX # Returns input x perspective factor. ##
67# getPerspY # Returns input y perspective factor. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040068# getScaleX # Returns horizontal scale factor. ##
Cary Clark154beea2017-10-26 07:58:48 -040069# getScaleY # Returns vertical scale factor. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040070# getSkewX # Returns horizontal skew factor. ##
71# getSkewY # Returns vertical skew factor. ##
Cary Clark154beea2017-10-26 07:58:48 -040072# getTranslateX # Returns horizontal translation. ##
73# getTranslateY # Returns vertical translation. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040074# getType # Returns transform complexity. ##
75# hasPerspective # Returns if transform includes perspective. ##
Cary Clark154beea2017-10-26 07:58:48 -040076# invert() # Returns inverse, if possible. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040077# isFinite # Returns if all Matrix values are not infinity, NaN. ##
78# isFixedStepInX # Returns if transformation supports fixed step in x. ##
79# isIdentity # Returns if matrix equals the identity Matrix .##
80# isScaleTranslate # Returns if transform is limited to scale and translate. ##
81# isSimilarity # Returns if transform is limited to square scale and rotation. ##
82# isTranslate # Returns if transform is limited to translate. ##
Cary Clark154beea2017-10-26 07:58:48 -040083# mapHomogeneousPoints # Maps Point3 array. ##
84# mapPoints # Maps Point array. ##
85# mapPointsWithStride # Maps Point array with padding. ##
86# mapRadius # Returns mean radius of mapped Circle. ##
87# mapRect # Returns bounds of mapped Rect. ##
88# mapRectScaleTranslate # Returns bounds of mapped Rect. ##
89# mapRectToQuad # Maps Rect to Point array. ##
90# mapVector # Maps Vector. ##
91# mapVectors # Maps Vector array. ##
92# mapXY # Maps Point. ##
93# postConcat # Post-multiplies Matrix by Matrix parameter. ##
94# postIDiv # Post-multiplies Matrix by inverse scale. ##
95# postRotate # Post-multiplies Matrix by rotation. ##
96# postScale # Post-multiplies Matrix by scale. ##
97# postSkew # Post-multiplies Matrix by skew. ##
98# postTranslate # Post-multiplies Matrix by translation. ##
99# preConcat # Pre-multiplies Matrix by Matrix parameter.##
100# preRotate # Pre-multiplies Matrix by rotation. ##
101# preScale # Pre-multiplies Matrix by scale. ##
102# preSkew # Pre-multiplies Matrix by skew. ##
103# preTranslate # Pre-multiplies Matrix by translation. ##
104# preservesAxisAlignment # Returns if mapping restricts to 90 degree multiples and mirroring. ##
105# preservesRightAngles # Returns if mapped 90 angle remains 90 degrees. ##
106# rectStaysRect # Returns if mapped Rect can be represented by another Rect. ##
107# reset() # Sets Matrix to identity. ##
108# set() # Sets one value. ##
109# set9 # Sets all values from Scalar array. ##
110# setAffine # Sets left two columns. ##
111# setAll # Sets all values from parameters. ##
112# setConcat # Sets to Matrix parameter multiplied by Matrix parameter. ##
113# setIdentity # Sets Matrix to identity. ##
114# setPerspX # Sets input x perspective factor. ##
115# setPerspY # Sets input y perspective factor. ##
116# setPolyToPoly # Sets to map one to four points to an equal array of points. ##
117# setRSXform # Sets to rotate, scale, and translate. ##
118# setRectToRect # Sets to map one Rect to another. ##
119# setRotate # Sets to rotate about a point. ##
120# setScale # Sets to scale about a point. ##
121# setScaleTranslate # Sets to scale and translate. ##
122# setScaleX # Sets horizontal scale factor. ##
123# setScaleY # Sets vertical scale factor ##
124# setSinCos # Sets to rotate and scale about a point. ##
125# setSkew # Sets to skew about a point. ##
126# setSkewX # Sets horizontal skew factor. ##
127# setSkewY # Sets vertical skew factor. ##
128# setTranslate # Sets to translate in x and y. ##
129# setTranslateX # Sets horizontal translation. ##
130# setTranslateY # Sets vertical translation. ##
131# toString # Converts Matrix to machine readable form. ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400132#Table ##
133#Subtopic ##
134
135#Topic ##
136
137# ------------------------------------------------------------------------------
138
139#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy)
140
Cary Clark154beea2017-10-26 07:58:48 -0400141Sets Matrix to scale by (sx, sy). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400142
Cary Clark154beea2017-10-26 07:58:48 -0400143#Code
144#Literal
145| sx 0 0 |
146| 0 sy 0 |
147| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400148##
149
Cary Clark154beea2017-10-26 07:58:48 -0400150#Param sx horizontal scale factor ##
151#Param sy vertical scale factor ##
152
153#Return Matrix with scale ##
154
155#Example
156#Image 4
157canvas->concat(SkMatrix::MakeScale(4, 3));
158canvas->drawBitmap(source, 0, 0);
159##
160
161#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400162
163##
164
165# ------------------------------------------------------------------------------
166
167#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale)
168
Cary Clark154beea2017-10-26 07:58:48 -0400169Sets Matrix to scale by (scale, scale). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400170
Cary Clark154beea2017-10-26 07:58:48 -0400171#Code
172#Literal
173| scale 0 0 |
174| 0 scale 0 |
175| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400176##
177
Cary Clark154beea2017-10-26 07:58:48 -0400178#Param scale horizontal and vertical scale factor ##
179
180#Return Matrix with scale ##
181
182#Example
183#Image 4
184canvas->concat(SkMatrix::MakeScale(4));
185canvas->drawBitmap(source, 0, 0);
186##
187
188#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400189
190##
191
192# ------------------------------------------------------------------------------
193
194#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy)
195
Cary Clark154beea2017-10-26 07:58:48 -0400196Sets Matrix to translate by (dx, dy). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400197
Cary Clark154beea2017-10-26 07:58:48 -0400198#Code
199#Literal
Cary Clarkcfee6ec2017-10-26 10:34:05 -0400200| 1 0 dx |
201| 0 1 dy |
202| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400203##
204
Cary Clark154beea2017-10-26 07:58:48 -0400205#Param dx horizontal translation ##
206#Param dy vertical translation ##
207
208#Return Matrix with translation ##
209
210#Example
211#Image 4
212SkMatrix matrix = SkMatrix::MakeTrans(64, 48);
213for (int i = 0; i < 4; ++i) {
214 canvas->drawBitmap(source, 0, 0);
215 canvas->concat(matrix);
216}
217##
218
219#SeeAlso setTranslate postTranslate preTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400220
221##
222
223# ------------------------------------------------------------------------------
224
Cary Clarkbef063a2017-10-31 15:44:45 -0400225#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
226 SkScalar skewY, SkScalar scaleY, SkScalar transY,
227 SkScalar pers0, SkScalar pers1, SkScalar pers2)
228
229
230Sets Matrix to:
231
232#Code
233#Literal
234| scaleX skewX transX |
235| skewY scaleY transY |
236| pers0 pers1 pers2 |
237##
238
239#Param scaleX horizontal scale factor ##
240#Param skewX horizontal skew factor ##
241#Param transX horizontal translation ##
242#Param skewY vertical skew factor ##
243#Param scaleY vertical scale factor ##
244#Param transY vertical translation ##
245#Param pers0 input x perspective factor ##
246#Param pers1 input y perspective factor ##
247#Param pers2 perspective scale factor ##
248
249#Return Matrix constructed from parameters ##
250
251#Example
252 SkPaint p;
253 p.setAntiAlias(true);
254 p.setTextSize(64);
255 for (SkScalar sx : { -1, 1 } ) {
256 for (SkScalar sy : { -1, 1 } ) {
257 SkAutoCanvasRestore autoRestore(canvas, true);
258 SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1);
259 canvas->concat(m);
260 canvas->drawString("K", 0, 0, p);
261 }
262 }
263##
264
265#SeeAlso setAll set9 postConcat preConcat
266
267##
268
269
270# ------------------------------------------------------------------------------
271
Cary Clarkbc5697d2017-10-04 14:31:33 -0400272#Enum TypeMask
273
274#Code
275 enum TypeMask {
276 kIdentity_Mask = 0,
277 kTranslate_Mask = 0x01,
278 kScale_Mask = 0x02,
279 kAffine_Mask = 0x04,
280 kPerspective_Mask = 0x08,
281 };
282##
283
Cary Clark154beea2017-10-26 07:58:48 -0400284Enum of bit fields for mask returned by getType.
285Used to identify the complexity of Matrix, to optimize performance.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400286
Cary Clark154beea2017-10-26 07:58:48 -0400287#Const kIdentity_Mask 0
288all bits clear if Matrix is identity
Cary Clarkbc5697d2017-10-04 14:31:33 -0400289##
Cary Clark154beea2017-10-26 07:58:48 -0400290#Const kTranslate_Mask 1
291set if Matrix has translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400292##
Cary Clark154beea2017-10-26 07:58:48 -0400293#Const kScale_Mask 2
294set if Matrix has x or y scale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400295##
Cary Clark154beea2017-10-26 07:58:48 -0400296#Const kAffine_Mask 4
297set if Matrix skews or rotates
Cary Clarkbc5697d2017-10-04 14:31:33 -0400298##
Cary Clark154beea2017-10-26 07:58:48 -0400299#Const kPerspective_Mask 8
300set if Matrix has perspective
Cary Clarkbc5697d2017-10-04 14:31:33 -0400301##
302
303#Example
Cary Clark154beea2017-10-26 07:58:48 -0400304 auto debugster = [](const char* prefix, const SkMatrix& matrix) -> void {
305 SkString typeMask;
306 typeMask += SkMatrix::kIdentity_Mask == matrix.getType() ? "kIdentity_Mask " : "";
307 typeMask += SkMatrix::kTranslate_Mask & matrix.getType() ? "kTranslate_Mask " : "";
308 typeMask += SkMatrix::kScale_Mask & matrix.getType() ? "kScale_Mask " : "";
309 typeMask += SkMatrix::kAffine_Mask & matrix.getType() ? "kAffine_Mask " : "";
310 typeMask += SkMatrix::kPerspective_Mask & matrix.getType() ? "kPerspective_Mask" : "";
311 SkDebugf("after %s: %s\n", prefix, typeMask.c_str());
312 };
313SkMatrix matrix;
314matrix.reset();
315debugster("reset", matrix);
316matrix.postTranslate(1, 0);
317debugster("postTranslate", matrix);
318matrix.postScale(2, 1);
319debugster("postScale", matrix);
320matrix.postRotate(45);
321debugster("postScale", matrix);
322SkPoint polys[][4] = {{{0, 0}, {0, 1}, {1, 1}, {1, 0}}, {{0, 0}, {0, 1}, {2, 1}, {1, 0}}};
323matrix.setPolyToPoly(polys[0], polys[1], 4);
324debugster("setPolyToPoly", matrix);
325#StdOut
326after reset: kIdentity_Mask
327after postTranslate: kTranslate_Mask
328after postScale: kTranslate_Mask kScale_Mask
329after postScale: kTranslate_Mask kScale_Mask kAffine_Mask
330after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask
331##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400332##
333
Cary Clark154beea2017-10-26 07:58:48 -0400334#SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400335
336##
337
338# ------------------------------------------------------------------------------
339
340#Method TypeMask getType() const
341
342Returns a bit field describing the transformations the matrix may
343perform. The bit field is computed conservatively, so it may include
Cary Clark154beea2017-10-26 07:58:48 -0400344false positives. For example, when kPerspective_Mask is set, all
345other bits are set.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400346
Cary Clark154beea2017-10-26 07:58:48 -0400347#Return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask,
348 kAffine_Mask, kPerspective_Mask
Cary Clarkbc5697d2017-10-04 14:31:33 -0400349##
350
Cary Clark154beea2017-10-26 07:58:48 -0400351#Example
352SkMatrix matrix;
353matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
354SkDebugf("identity flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
355matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, .5f);
356SkDebugf("set all flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
357#StdOut
358identity flags hex: 0 decimal: 0
359set all flags hex: f decimal: 15
360##
361##
362
363#SeeAlso TypeMask
Cary Clarkbc5697d2017-10-04 14:31:33 -0400364
365##
366
367# ------------------------------------------------------------------------------
368
369#Method bool isIdentity() const
370
Cary Clark154beea2017-10-26 07:58:48 -0400371Returns true if Matrix is identity. Identity matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400372
Cary Clark154beea2017-10-26 07:58:48 -0400373#Code
374#Literal
375| 1 0 0 |
376| 0 1 0 |
377| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400378##
379
Cary Clark154beea2017-10-26 07:58:48 -0400380#Return true if Matrix has no effect ##
381
382#Example
383SkMatrix matrix;
384matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
385SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
386matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 2);
387SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
388#StdOut
389is identity: true
390is identity: false
391##
392##
393
394#SeeAlso reset() setIdentity getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400395
396##
397
398# ------------------------------------------------------------------------------
399
400#Method bool isScaleTranslate() const
401
Cary Clark154beea2017-10-26 07:58:48 -0400402Returns true if Matrix at most scales and translates. Matrix may be identity,
403contain only scale elements, only translate elements, or both. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400404
Cary Clark154beea2017-10-26 07:58:48 -0400405#Code
406#Literal
407| scale-x 0 translate-x |
408| 0 scale-y translate-y |
409| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400410##
411
Cary Clark154beea2017-10-26 07:58:48 -0400412#Return true if Matrix is identity; or scales, translates, or both ##
413
414#Example
415SkMatrix matrix;
416for (SkScalar scaleX : { 1, 2 } ) {
417 for (SkScalar translateX : { 0, 20 } ) {
418 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
419 SkDebugf("is scale-translate: %s\n", matrix.isScaleTranslate() ? "true" : "false");
420 }
421}
422#StdOut
423is scale-translate: true
424is scale-translate: true
425is scale-translate: true
426is scale-translate: true
427##
428##
429
430#SeeAlso setScale isTranslate setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400431
432##
433
434# ------------------------------------------------------------------------------
435
436#Method bool isTranslate() const
437
Cary Clark154beea2017-10-26 07:58:48 -0400438Returns true if Matrix is identity, or translates. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400439
Cary Clark154beea2017-10-26 07:58:48 -0400440#Code
441#Literal
442| 1 0 translate-x |
443| 0 1 translate-y |
444| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400445##
446
Cary Clark154beea2017-10-26 07:58:48 -0400447#Return true if Matrix is identity, or translates ##
448
449#Example
450SkMatrix matrix;
451for (SkScalar scaleX : { 1, 2 } ) {
452 for (SkScalar translateX : { 0, 20 } ) {
453 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
454 SkDebugf("is translate: %s\n", matrix.isTranslate() ? "true" : "false");
455 }
456}
457#StdOut
458is translate: true
459is translate: true
460is translate: false
461is translate: false
462##
463##
464
465#SeeAlso setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400466
467##
468
469# ------------------------------------------------------------------------------
470
471#Method bool rectStaysRect() const
472
Cary Clark154beea2017-10-26 07:58:48 -0400473Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
474or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
475cases, Matrix may also have translation. Matrix form is either:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400476
Cary Clark154beea2017-10-26 07:58:48 -0400477#Code
478#Literal
479| scale-x 0 translate-x |
480| 0 scale-y translate-y |
481| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400482##
483
Cary Clark154beea2017-10-26 07:58:48 -0400484or
485
486#Code
487#Literal
488| 0 rotate-x translate-x |
489| rotate-y 0 translate-y |
490| 0 0 1 |
491##
492
493for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
494
495Also called preservesAxisAlignment; use the one that provides better inline
496documentation.
497
498#Return true if Matrix maps one Rect into another ##
499
500#Example
501SkMatrix matrix;
502for (SkScalar angle: { 0, 90, 180, 270 } ) {
503 matrix.setRotate(angle);
504 SkDebugf("rectStaysRect: %s\n", matrix.rectStaysRect() ? "true" : "false");
505}
506#StdOut
507rectStaysRect: true
508rectStaysRect: true
509rectStaysRect: true
510rectStaysRect: true
511##
512##
513
514#SeeAlso preservesAxisAlignment preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400515
516##
517
518# ------------------------------------------------------------------------------
519
520#Method bool preservesAxisAlignment() const
521
Cary Clarkbc5697d2017-10-04 14:31:33 -0400522
Cary Clark154beea2017-10-26 07:58:48 -0400523Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
524or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
525cases, Matrix may also have translation. Matrix form is either:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400526
Cary Clark154beea2017-10-26 07:58:48 -0400527#Code
528#Literal
529| scale-x 0 translate-x |
530| 0 scale-y translate-y |
531| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400532##
533
Cary Clark154beea2017-10-26 07:58:48 -0400534or
535
536#Code
537#Literal
538| 0 rotate-x translate-x |
539| rotate-y 0 translate-y |
540| 0 0 1 |
541##
542
543for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
544
545Also called rectStaysRect; use the one that provides better inline
546documentation.
547
548#Return true if Matrix maps one Rect into another ##
549
550#Example
551SkMatrix matrix;
552for (SkScalar angle: { 0, 90, 180, 270 } ) {
553 matrix.setRotate(angle);
554 SkDebugf("preservesAxisAlignment: %s\n", matrix.preservesAxisAlignment() ? "true" : "false");
555}
556#StdOut
557preservesAxisAlignment: true
558preservesAxisAlignment: true
559preservesAxisAlignment: true
560preservesAxisAlignment: true
561##
562##
563
564#SeeAlso rectStaysRect preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400565
566##
567
568# ------------------------------------------------------------------------------
569
570#Method bool hasPerspective() const
571
Cary Clark154beea2017-10-26 07:58:48 -0400572Returns true if the matrix contains perspective elements. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400573
Cary Clark154beea2017-10-26 07:58:48 -0400574#Code
575#Literal
576| -- -- -- |
577| -- -- -- |
578| perspective-x perspective-y perspective-scale |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400579##
580
Cary Clark154beea2017-10-26 07:58:48 -0400581where perspective-x or perspective-y is non-zero, or perspective-scale is
582not one. All other elements may have any value.
583
584#Return true if Matrix is in most general form ##
585
586#Example
587#Image 4
588SkMatrix matrix;
589SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
590SkRect::Make(source.bounds()).toQuad(bitmapBounds);
591matrix.setPolyToPoly(bitmapBounds, perspect, 4);
592canvas->concat(matrix);
593SkString string;
594string.printf("hasPerspective %s", matrix.hasPerspective() ? "true" : "false");
595canvas->drawBitmap(source, 0, 0);
596SkPaint paint;
597paint.setAntiAlias(true);
598paint.setTextSize(48);
599canvas->drawString(string, 0, source.bounds().height() + 48, paint);
600##
601
Cary Clarkbef063a2017-10-31 15:44:45 -0400602#SeeAlso setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -0400603
604##
605
606# ------------------------------------------------------------------------------
607
608#Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const
609
Cary Clark154beea2017-10-26 07:58:48 -0400610Returns true if Matrix contains only translation, rotation, reflection, and
611uniform scale.
612Returns false if Matrix contains different scales, skewing, perspective, or
613degenerate forms that collapse to a line or point.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400614
Cary Clark154beea2017-10-26 07:58:48 -0400615Describes that the Matrix makes rendering with and without the matrix are
616visually alike; a transformed circle remains a circle. Mathematically, this is
617referred to as similarity of a Euclidean space, or a similarity transformation.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400618
Cary Clark154beea2017-10-26 07:58:48 -0400619Preserves right angles, keeping the arms of the angle equal lengths.
620
621#Param tol to be deprecated ##
622
623#Return true if Matrix only rotates, uniformly scales, translates ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400624
625#Example
Cary Clark154beea2017-10-26 07:58:48 -0400626#Description
627String is drawn four times through but only two are visible. Drawing the pair
628with isSimilarity false reveals the pair not visible through the matrix.
629##
630 SkPaint p;
631 p.setAntiAlias(true);
632 SkMatrix m;
633 int below = 175;
634 for (SkScalar sx : { -1, 1 } ) {
635 for (SkScalar sy : { -1, 1 } ) {
636 m.setAll(sx, 1, 128, 1, sy, 32, 0, 0, 1);
637 bool isSimilarity = m.isSimilarity();
638 SkString str;
639 str.printf("sx: %g sy: %g sim: %s", sx, sy, isSimilarity ? "true" : "false");
640 {
641 SkAutoCanvasRestore autoRestore(canvas, true);
642 canvas->concat(m);
643 canvas->drawString(str, 0, 0, p);
644 }
645 if (!isSimilarity) {
646 canvas->drawString(str, 40, below, p);
647 below += 20;
648 }
649 }
650 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400651##
652
Cary Clark154beea2017-10-26 07:58:48 -0400653#SeeAlso isScaleTranslate preservesRightAngles rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400654
655##
656
657# ------------------------------------------------------------------------------
658
659#Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const
660
Cary Clark154beea2017-10-26 07:58:48 -0400661Returns true if Matrix contains only translation, rotation, reflection, and
662scale. Scale may differ along rotated axes.
663Returns false if Matrix skewing, perspective, or degenerate forms that collapse
664to a line or point.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400665
Cary Clark154beea2017-10-26 07:58:48 -0400666Preserves right angles, but not requiring that the arms of the angle
667retain equal lengths.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400668
Cary Clark154beea2017-10-26 07:58:48 -0400669#Param tol to be deprecated ##
670
671#Return true if Matrix only rotates, scales, translates ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400672
673#Example
Cary Clark154beea2017-10-26 07:58:48 -0400674#Height 128
675#Description
676Equal scale is both similar and preserves right angles.
677Unequal scale is not similar but preserves right angles.
678Skews are not similar and do not preserve right angles.
679##
680SkPaint p;
681p.setAntiAlias(true);
682SkMatrix m;
683int pos = 0;
684for (SkScalar sx : { 1, 2 } ) {
685 for (SkScalar kx : { 0, 1 } ) {
686 m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1);
687 bool isSimilarity = m.isSimilarity();
688 bool preservesRightAngles = m.preservesRightAngles();
689 SkString str;
690 str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "",
691 preservesRightAngles ? "right" : "");
692 SkAutoCanvasRestore autoRestore(canvas, true);
693 canvas->concat(m);
694 canvas->drawString(str, 0, pos, p);
695 pos += 20;
696 }
697}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400698##
699
Cary Clark154beea2017-10-26 07:58:48 -0400700#SeeAlso isScaleTranslate isSimilarity rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400701
702##
703
704# ------------------------------------------------------------------------------
705
Cary Clark154beea2017-10-26 07:58:48 -0400706#Enum
Cary Clarkbc5697d2017-10-04 14:31:33 -0400707
708#Code
709 enum {
710 kMScaleX,
711 kMSkewX,
712 kMTransX,
713 kMSkewY,
714 kMScaleY,
715 kMTransY,
716 kMPersp0,
717 kMPersp1,
718 kMPersp2,
719 };
720##
721
Cary Clark154beea2017-10-26 07:58:48 -0400722Matrix organizes its values in row order. These members correspond to
723each value in Matrix.
724
Cary Clarkbc5697d2017-10-04 14:31:33 -0400725#Const kMScaleX 0
Cary Clark154beea2017-10-26 07:58:48 -0400726horizontal scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400727##
728#Const kMSkewX 1
Cary Clark154beea2017-10-26 07:58:48 -0400729horizontal skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400730##
731#Const kMTransX 2
Cary Clark154beea2017-10-26 07:58:48 -0400732horizontal translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400733##
734#Const kMSkewY 3
Cary Clark154beea2017-10-26 07:58:48 -0400735vertical skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400736##
737#Const kMScaleY 4
Cary Clark154beea2017-10-26 07:58:48 -0400738vertical scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400739##
740#Const kMTransY 5
Cary Clark154beea2017-10-26 07:58:48 -0400741vertical translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400742##
743#Const kMPersp0 6
Cary Clark154beea2017-10-26 07:58:48 -0400744input x perspective factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400745##
746#Const kMPersp1 7
Cary Clark154beea2017-10-26 07:58:48 -0400747input y perspective factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400748##
749#Const kMPersp2 8
Cary Clark154beea2017-10-26 07:58:48 -0400750perspective bias
Cary Clarkbc5697d2017-10-04 14:31:33 -0400751##
752
753#Example
Cary Clark154beea2017-10-26 07:58:48 -0400754SkPaint black;
755black.setAntiAlias(true);
756black.setTextSize(48);
757SkPaint gray = black;
758gray.setColor(0xFF9f9f9f);
759SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 };
760for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX,
761 SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY,
762 SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) {
763 SkMatrix m;
764 m.setIdentity();
765 m.set(i, offset[i]);
766 SkAutoCanvasRestore autoRestore(canvas, true);
767 canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88);
768 canvas->drawString("&", 0, 0, gray);
769 canvas->concat(m);
770 canvas->drawString("&", 0, 0, black);
771}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400772##
773
Cary Clark154beea2017-10-26 07:58:48 -0400774#SeeAlso get() set()
Cary Clarkbc5697d2017-10-04 14:31:33 -0400775
776##
777
778# ------------------------------------------------------------------------------
779
Cary Clark154beea2017-10-26 07:58:48 -0400780#Enum
Cary Clarkbc5697d2017-10-04 14:31:33 -0400781
782#Code
783 enum {
784 kAScaleX,
785 kASkewY,
786 kASkewX,
787 kAScaleY,
788 kATransX,
789 kATransY,
790 };
791##
792
Cary Clark154beea2017-10-26 07:58:48 -0400793Affine arrays are in column major order to match the matrix used by
794PDF and XPS.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400795
796#Const kAScaleX 0
Cary Clark154beea2017-10-26 07:58:48 -0400797horizontal scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400798##
799#Const kASkewY 1
Cary Clark154beea2017-10-26 07:58:48 -0400800vertical skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400801##
802#Const kASkewX 2
Cary Clark154beea2017-10-26 07:58:48 -0400803horizontal skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400804##
805#Const kAScaleY 3
Cary Clark154beea2017-10-26 07:58:48 -0400806vertical scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400807##
808#Const kATransX 4
Cary Clark154beea2017-10-26 07:58:48 -0400809horizontal translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400810##
811#Const kATransY 5
Cary Clark154beea2017-10-26 07:58:48 -0400812vertical translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400813##
814
Cary Clark154beea2017-10-26 07:58:48 -0400815#NoExample
Cary Clarkbc5697d2017-10-04 14:31:33 -0400816##
817
Cary Clark154beea2017-10-26 07:58:48 -0400818#SeeAlso SetAffineIdentity asAffine setAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -0400819
820##
821
822# ------------------------------------------------------------------------------
823
824#Method SkScalar operator[](int index) const
825
Cary Clark154beea2017-10-26 07:58:48 -0400826Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
827defined.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400828
Cary Clark154beea2017-10-26 07:58:48 -0400829#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
830 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -0400831##
832
Cary Clark154beea2017-10-26 07:58:48 -0400833#Return value corresponding to index ##
834
835#Example
836SkMatrix matrix;
837matrix.setScale(42, 24);
838SkDebugf("matrix[SkMatrix::kMScaleX] %c= 42\n", matrix[SkMatrix::kMScaleX] == 42 ? '=' : '!');
839SkDebugf("matrix[SkMatrix::kMScaleY] %c= 24\n", matrix[SkMatrix::kMScaleY] == 24 ? '=' : '!');
840#StdOut
841matrix[SkMatrix::kMScaleX] == 42
842matrix[SkMatrix::kMScaleY] == 24
843##
844##
845
846#SeeAlso get set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400847
848##
849
850# ------------------------------------------------------------------------------
851
852#Method SkScalar get(int index) const
853
Cary Clark154beea2017-10-26 07:58:48 -0400854Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
855defined.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400856
Cary Clark154beea2017-10-26 07:58:48 -0400857#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
858 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -0400859##
860
Cary Clark154beea2017-10-26 07:58:48 -0400861#Return value corresponding to index ##
862
863#Example
864SkMatrix matrix;
865matrix.setSkew(42, 24);
866SkDebugf("matrix.get(SkMatrix::kMSkewX) %c= 42\n",
867 matrix.get(SkMatrix::kMSkewX) == 42 ? '=' : '!');
868SkDebugf("matrix.get(SkMatrix::kMSkewY) %c= 24\n",
869 matrix.get(SkMatrix::kMSkewY) == 24 ? '=' : '!');
870#StdOut
871matrix.get(SkMatrix::kMSkewX) == 42
872matrix.get(SkMatrix::kMSkewY) == 24
873##
874##
875
876#SeeAlso operator[](int index) set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400877
878##
879
880# ------------------------------------------------------------------------------
881
882#Method SkScalar getScaleX() const
883
Cary Clark154beea2017-10-26 07:58:48 -0400884Returns scale factor multiplied by x input, contributing to x output.
885With mapPoints, scales Points along the x-axis.
886
887#Return horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400888
889#Example
Cary Clark154beea2017-10-26 07:58:48 -0400890SkMatrix matrix;
891matrix.setScale(42, 24);
892SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!');
893#StdOut
894matrix.getScaleX() == 42
895##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400896##
897
Cary Clark154beea2017-10-26 07:58:48 -0400898#SeeAlso get getScaleY setScaleX setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400899
900##
901
902# ------------------------------------------------------------------------------
903
904#Method SkScalar getScaleY() const
905
Cary Clark154beea2017-10-26 07:58:48 -0400906Returns scale factor multiplied by y input, contributing to y output.
907With mapPoints, scales Points along the y-axis.
908
909#Return vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400910
911#Example
Cary Clark154beea2017-10-26 07:58:48 -0400912SkMatrix matrix;
913matrix.setScale(42, 24);
914SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!');
915#StdOut
916matrix.getScaleY() == 24
917##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400918##
919
Cary Clark154beea2017-10-26 07:58:48 -0400920#SeeAlso get getScaleX setScaleY setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400921
922##
923
924# ------------------------------------------------------------------------------
925
926#Method SkScalar getSkewY() const
927
Cary Clark154beea2017-10-26 07:58:48 -0400928Returns scale factor multiplied by x input, contributing to y output.
929With mapPoints, skews Points along the y-axis.
930Skew x and y together can rotate Points.
931
932#Return vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400933
934#Example
Cary Clark154beea2017-10-26 07:58:48 -0400935SkMatrix matrix;
936matrix.setSkew(42, 24);
937SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!');
938#StdOut
939matrix.getSkewY() == 24
940##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400941##
942
Cary Clark154beea2017-10-26 07:58:48 -0400943#SeeAlso get getSkewX setSkewY setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400944
945##
946
947# ------------------------------------------------------------------------------
948
949#Method SkScalar getSkewX() const
950
Cary Clark154beea2017-10-26 07:58:48 -0400951Returns scale factor multiplied by y input, contributing to x output.
952With mapPoints, skews Points along the x-axis.
953Skew x and y together can rotate Points.
954
955#Return horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400956
957#Example
Cary Clark154beea2017-10-26 07:58:48 -0400958SkMatrix matrix;
959matrix.setSkew(42, 24);
960SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!');
961#StdOut
962matrix.getSkewX() == 42
963##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400964##
965
Cary Clark154beea2017-10-26 07:58:48 -0400966#SeeAlso get getSkewY setSkewX setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400967
968##
969
970# ------------------------------------------------------------------------------
971
972#Method SkScalar getTranslateX() const
973
Cary Clark154beea2017-10-26 07:58:48 -0400974Returns translation contributing to x output.
975With mapPoints, moves Points along the x-axis.
976
977#Return horizontal translation factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400978
979#Example
Cary Clark154beea2017-10-26 07:58:48 -0400980SkMatrix matrix;
981matrix.setTranslate(42, 24);
982SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!');
983#StdOut
984matrix.getTranslateX() == 42
985##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400986##
987
Cary Clark154beea2017-10-26 07:58:48 -0400988#SeeAlso get getTranslateY setTranslateX setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400989
990##
991
992# ------------------------------------------------------------------------------
993
994#Method SkScalar getTranslateY() const
995
Cary Clark154beea2017-10-26 07:58:48 -0400996Returns translation contributing to y output.
997With mapPoints, moves Points along the y-axis.
998
999#Return vertical translation factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001000
1001#Example
Cary Clark154beea2017-10-26 07:58:48 -04001002SkMatrix matrix;
1003matrix.setTranslate(42, 24);
1004SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!');
1005#StdOut
1006matrix.getTranslateY() == 24
1007##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001008##
1009
Cary Clark154beea2017-10-26 07:58:48 -04001010#SeeAlso get getTranslateX setTranslateY setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001011
1012##
1013
1014# ------------------------------------------------------------------------------
1015
1016#Method SkScalar getPerspX() const
1017
Cary Clark154beea2017-10-26 07:58:48 -04001018Returns factor scaling input x relative to input y.
1019
1020#Return input x perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001021
1022#Example
Cary Clark154beea2017-10-26 07:58:48 -04001023 SkMatrix m;
1024 m.setIdentity();
1025 m.set(SkMatrix::kMPersp0, -0.004f);
1026 SkAutoCanvasRestore autoRestore(canvas, true);
1027 canvas->translate(22, 144);
1028 SkPaint black;
1029 black.setAntiAlias(true);
1030 black.setTextSize(24);
1031 SkPaint gray = black;
1032 gray.setColor(0xFF9f9f9f);
1033 SkString string;
1034 string.appendScalar(m.getPerspX());
1035 canvas->drawString(string, 0, -72, gray);
1036 canvas->concat(m);
1037 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001038##
1039
Cary Clark154beea2017-10-26 07:58:48 -04001040#SeeAlso kMPersp0 getPerspY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001041
1042##
1043
1044# ------------------------------------------------------------------------------
1045
1046#Method SkScalar getPerspY() const
1047
Cary Clark154beea2017-10-26 07:58:48 -04001048
1049Returns factor scaling input y relative to input x.
1050
1051#Return input y perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001052
1053#Example
Cary Clark154beea2017-10-26 07:58:48 -04001054 SkMatrix m;
1055 m.setIdentity();
1056 m.set(SkMatrix::kMPersp1, -0.004f);
1057 SkAutoCanvasRestore autoRestore(canvas, true);
1058 canvas->translate(22, 144);
1059 SkPaint black;
1060 black.setAntiAlias(true);
1061 black.setTextSize(24);
1062 SkPaint gray = black;
1063 gray.setColor(0xFF9f9f9f);
1064 SkString string;
1065 string.appendScalar(m.getPerspY());
1066 canvas->drawString(string, 0, -72, gray);
1067 canvas->concat(m);
1068 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001069##
1070
Cary Clark154beea2017-10-26 07:58:48 -04001071#SeeAlso kMPersp1 getPerspX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001072
1073##
1074
1075# ------------------------------------------------------------------------------
1076
Cary Clark154beea2017-10-26 07:58:48 -04001077#Method SkScalar& operator[](int index)
Cary Clarkbc5697d2017-10-04 14:31:33 -04001078
Cary Clark154beea2017-10-26 07:58:48 -04001079Returns writable Matrix value. Asserts if index is out of range and SK_DEBUG is
1080defined. Clears internal cache anticipating that caller will change Matrix value.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001081
Cary Clark154beea2017-10-26 07:58:48 -04001082Next call to read Matrix state may recompute cache; subsequent writes to Matrix
1083value must be followed by dirtyMatrixTypeCache.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001084
Cary Clark154beea2017-10-26 07:58:48 -04001085#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1086 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -04001087##
1088
Cary Clark154beea2017-10-26 07:58:48 -04001089#Return writable value corresponding to index ##
1090
1091#Example
1092SkMatrix matrix;
1093matrix.setIdentity();
1094SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
1095SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
1096skewRef = 0;
1097SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1098skewRef = 1;
1099SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1100matrix.dirtyMatrixTypeCache();
1101SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
1102#StdOut
1103with identity matrix: x = 24
1104after skew x mod: x = 24
1105after 2nd skew x mod: x = 24
1106after dirty cache: x = 66
1107##
1108##
1109
1110#SeeAlso get dirtyMatrixTypeCache set
Cary Clarkbc5697d2017-10-04 14:31:33 -04001111
1112##
1113
1114# ------------------------------------------------------------------------------
1115
1116#Method void set(int index, SkScalar value)
1117
Cary Clark154beea2017-10-26 07:58:48 -04001118Sets Matrix value. Asserts if index is out of range and SK_DEBUG is
1119defined. Safer than operator[]; internal cache is always maintained.
1120
1121#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1122 kMPersp0, kMPersp1, kMPersp2
1123##
1124#Param value Scalar to store in Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001125
1126#Example
Cary Clark154beea2017-10-26 07:58:48 -04001127SkMatrix matrix;
1128matrix.setIdentity();
1129SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
1130matrix.set(SkMatrix::kMSkewX, 0);
1131SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1132matrix.set(SkMatrix::kMSkewX, 1);
1133SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1134#StdOut
1135with identity matrix: x = 24
1136after skew x mod: x = 24
1137after 2nd skew x mod: x = 66
1138##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001139##
1140
Cary Clark154beea2017-10-26 07:58:48 -04001141#SeeAlso operator[] get
Cary Clarkbc5697d2017-10-04 14:31:33 -04001142
Cary Clark154beea2017-10-26 07:58:48 -04001143#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001144
1145# ------------------------------------------------------------------------------
1146
1147#Method void setScaleX(SkScalar v)
1148
Cary Clark154beea2017-10-26 07:58:48 -04001149Sets horizontal scale factor.
1150
1151#Param v horizontal scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001152
1153#Example
Cary Clark154beea2017-10-26 07:58:48 -04001154#Height 64
1155SkPaint paint;
1156paint.setAntiAlias(true);
1157paint.setTextSize(24);
1158canvas->drawString("normal", 12, 24, paint);
1159SkMatrix matrix;
1160matrix.setIdentity();
1161matrix.setScaleX(3);
1162canvas->concat(matrix);
1163canvas->drawString("x scale", 0, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001164##
1165
Cary Clark154beea2017-10-26 07:58:48 -04001166#SeeAlso set setScale setScaleY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001167
Cary Clark154beea2017-10-26 07:58:48 -04001168#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001169
1170# ------------------------------------------------------------------------------
1171
1172#Method void setScaleY(SkScalar v)
1173
Cary Clark154beea2017-10-26 07:58:48 -04001174Sets vertical scale factor.
1175
1176#Param v vertical scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001177
1178#Example
Cary Clark154beea2017-10-26 07:58:48 -04001179#Height 192
1180SkPaint paint;
1181paint.setAntiAlias(true);
1182paint.setTextSize(24);
1183canvas->drawString("normal", 12, 24, paint);
1184SkMatrix matrix;
1185matrix.setIdentity();
1186matrix.setScaleY(3);
1187canvas->concat(matrix);
1188canvas->drawString("y scale", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001189##
1190
Cary Clark154beea2017-10-26 07:58:48 -04001191#SeeAlso set setScale setScaleX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001192
Cary Clark154beea2017-10-26 07:58:48 -04001193#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001194
1195# ------------------------------------------------------------------------------
1196
1197#Method void setSkewY(SkScalar v)
1198
Cary Clark154beea2017-10-26 07:58:48 -04001199Sets vertical skew factor.
1200
1201#Param v vertical skew factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001202
1203#Example
Cary Clark154beea2017-10-26 07:58:48 -04001204#Height 96
1205SkPaint paint;
1206paint.setAntiAlias(true);
1207paint.setTextSize(24);
1208canvas->drawString("normal", 12, 24, paint);
1209SkMatrix matrix;
1210matrix.setIdentity();
1211matrix.setSkewY(.3f);
1212canvas->concat(matrix);
1213canvas->drawString("y skew", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001214##
1215
Cary Clark154beea2017-10-26 07:58:48 -04001216#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001217
Cary Clark154beea2017-10-26 07:58:48 -04001218#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001219
1220# ------------------------------------------------------------------------------
1221
1222#Method void setSkewX(SkScalar v)
1223
Cary Clark154beea2017-10-26 07:58:48 -04001224Sets horizontal skew factor.
1225
1226#Param v horizontal skew factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001227
1228#Example
Cary Clark154beea2017-10-26 07:58:48 -04001229#Height 64
1230SkPaint paint;
1231paint.setAntiAlias(true);
1232paint.setTextSize(24);
1233canvas->drawString("normal", 12, 24, paint);
1234SkMatrix matrix;
1235matrix.setIdentity();
1236matrix.setSkewX(-.7f);
1237canvas->concat(matrix);
1238canvas->drawString("x skew", 36, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001239##
1240
Cary Clark154beea2017-10-26 07:58:48 -04001241#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001242
Cary Clark154beea2017-10-26 07:58:48 -04001243#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001244
1245# ------------------------------------------------------------------------------
1246
1247#Method void setTranslateX(SkScalar v)
1248
Cary Clark154beea2017-10-26 07:58:48 -04001249Sets horizontal translation.
1250
1251#Param v horizontal translation to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001252
1253#Example
Cary Clark154beea2017-10-26 07:58:48 -04001254#Height 48
1255SkPaint paint;
1256paint.setAntiAlias(true);
1257paint.setTextSize(24);
1258canvas->drawString("normal", 8, 24, paint);
1259SkMatrix matrix;
1260matrix.setIdentity();
1261matrix.setTranslateX(96);
1262canvas->concat(matrix);
1263canvas->drawString("x translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001264##
1265
Cary Clark154beea2017-10-26 07:58:48 -04001266#SeeAlso set setTranslate setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001267
Cary Clark154beea2017-10-26 07:58:48 -04001268#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001269
1270# ------------------------------------------------------------------------------
1271
1272#Method void setTranslateY(SkScalar v)
1273
Cary Clark154beea2017-10-26 07:58:48 -04001274Sets vertical translation.
1275
1276#Param v vertical translation to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001277
1278#Example
Cary Clark154beea2017-10-26 07:58:48 -04001279#Height 64
1280SkPaint paint;
1281paint.setAntiAlias(true);
1282paint.setTextSize(24);
1283canvas->drawString("normal", 8, 24, paint);
1284SkMatrix matrix;
1285matrix.setIdentity();
1286matrix.setTranslateY(24);
1287canvas->concat(matrix);
1288canvas->drawString("y translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001289##
1290
Cary Clark154beea2017-10-26 07:58:48 -04001291#SeeAlso set setTranslate setTranslateX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001292
Cary Clark154beea2017-10-26 07:58:48 -04001293#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001294
1295# ------------------------------------------------------------------------------
1296
1297#Method void setPerspX(SkScalar v)
1298
Cary Clark154beea2017-10-26 07:58:48 -04001299Sets input x perspective factor, which causes mapXY to vary input x inversely
1300proportional to input y.
1301
1302#Param v perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001303
1304#Example
Cary Clark154beea2017-10-26 07:58:48 -04001305#Image 4
1306for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
1307 SkMatrix matrix;
1308 matrix.setIdentity();
1309 matrix.setPerspX(perspX);
1310 canvas->save();
1311 canvas->concat(matrix);
1312 canvas->drawBitmap(source, 0, 0);
1313 canvas->restore();
1314 canvas->translate(64, 64);
1315}
Cary Clarkbc5697d2017-10-04 14:31:33 -04001316##
1317
Cary Clarkbef063a2017-10-31 15:44:45 -04001318#SeeAlso getPerspX set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001319
Cary Clark154beea2017-10-26 07:58:48 -04001320#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001321
1322# ------------------------------------------------------------------------------
1323
1324#Method void setPerspY(SkScalar v)
1325
Cary Clark154beea2017-10-26 07:58:48 -04001326Sets input y perspective factor, which causes mapXY to vary input y inversely
1327proportional to input x.
1328
1329#Param v perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001330
1331#Example
Cary Clark154beea2017-10-26 07:58:48 -04001332#Image 4
1333for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
1334 SkMatrix matrix;
1335 matrix.setIdentity();
1336 matrix.setPerspY(perspX);
1337 canvas->save();
1338 canvas->concat(matrix);
1339 canvas->drawBitmap(source, 0, 0);
1340 canvas->restore();
1341 canvas->translate(64, 64);
1342}
Cary Clarkbc5697d2017-10-04 14:31:33 -04001343##
1344
Cary Clarkbef063a2017-10-31 15:44:45 -04001345#SeeAlso getPerspY set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001346
Cary Clark154beea2017-10-26 07:58:48 -04001347#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001348
1349# ------------------------------------------------------------------------------
1350
1351#Method void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
1352 SkScalar skewY, SkScalar scaleY, SkScalar transY,
1353 SkScalar persp0, SkScalar persp1, SkScalar persp2)
1354
Cary Clark154beea2017-10-26 07:58:48 -04001355Sets all values from parameters. Sets matrix to:
1356
1357#Code
1358#Literal
1359| scaleX skewX transX |
1360| skewY scaleY transY |
1361| persp0 persp1 persp2 |
1362##
1363
1364#Param scaleX horizontal scale factor to store ##
1365#Param skewX horizontal skew factor to store ##
1366#Param transX horizontal translation to store ##
1367#Param skewY vertical skew factor to store ##
1368#Param scaleY vertical scale factor to store ##
1369#Param transY vertical translation to store ##
1370#Param persp0 input x perspective factor to store ##
1371#Param persp1 input y perspective factor to store ##
1372#Param persp2 perspective scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001373
1374#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001375#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001376 SkPaint p;
1377 p.setAntiAlias(true);
1378 p.setTextSize(64);
1379 SkMatrix m;
1380 for (SkScalar sx : { -1, 1 } ) {
1381 for (SkScalar sy : { -1, 1 } ) {
1382 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001383 m.setAll(sx, 1, 128, 0, sy, 64, 0, 0, 1);
Cary Clark154beea2017-10-26 07:58:48 -04001384 canvas->concat(m);
1385 canvas->drawString("K", 0, 0, p);
1386 }
1387 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001388##
1389
Cary Clarkbef063a2017-10-31 15:44:45 -04001390#SeeAlso set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001391
Cary Clark154beea2017-10-26 07:58:48 -04001392#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001393
1394# ------------------------------------------------------------------------------
1395
1396#Method void get9(SkScalar buffer[9]) const
1397
Cary Clark154beea2017-10-26 07:58:48 -04001398Copies nine Scalar values contained by Matrix into buffer, in member value
1399ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1400kMPersp0, kMPersp1, kMPersp2.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001401
Cary Clark154beea2017-10-26 07:58:48 -04001402#Param buffer storage for nine Scalar values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001403
1404#Example
Cary Clark154beea2017-10-26 07:58:48 -04001405SkMatrix matrix = SkMatrix::MakeRectToRect({0, 0, 1, 1}, {3, 4, 7, 9},
1406 SkMatrix::kFill_ScaleToFit);
1407SkScalar b[9];
1408matrix.get9(b);
1409SkDebugf("{%g, %g, %g},\n{%g, %g, %g},\n{%g, %g, %g}\n", b[0], b[1], b[2],
1410 b[3], b[4], b[5], b[6], b[7], b[8]);
1411#StdOut
1412{4, 0, 3},
1413{0, 5, 4},
1414{0, 0, 1}
1415##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001416##
1417
Cary Clark154beea2017-10-26 07:58:48 -04001418#SeeAlso set9
Cary Clarkbc5697d2017-10-04 14:31:33 -04001419
Cary Clark154beea2017-10-26 07:58:48 -04001420#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001421
1422# ------------------------------------------------------------------------------
1423
1424#Method void set9(const SkScalar buffer[9])
1425
Cary Clark154beea2017-10-26 07:58:48 -04001426Sets Matrix to nine Scalar values in buffer, in member value ascending order:
1427kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1,
1428kMPersp2.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001429
Cary Clark154beea2017-10-26 07:58:48 -04001430Sets matrix to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04001431
Cary Clark154beea2017-10-26 07:58:48 -04001432#Code
1433#Literal
1434| buffer[0] buffer[1] buffer[2] |
1435| buffer[3] buffer[4] buffer[5] |
1436| buffer[6] buffer[7] buffer[8] |
1437##
1438
1439In the future, set9 followed by get9 may not return the same values. Since Matrix
1440maps non-homogeneous coordinates, scaling all nine values produces an equivalent
1441transformation, possibly improving precision.
1442
1443#Param buffer nine Scalar values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001444
1445#Example
Cary Clark154beea2017-10-26 07:58:48 -04001446#Image 4
1447SkMatrix m;
1448SkScalar buffer[9] = {4, 0, 3, 0, 5, 4, 0, 0, 1};
1449m.set9(buffer);
1450canvas->concat(m);
1451canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001452##
1453
Cary Clarkbef063a2017-10-31 15:44:45 -04001454#SeeAlso setAll get9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001455
Cary Clark154beea2017-10-26 07:58:48 -04001456#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001457
1458# ------------------------------------------------------------------------------
1459
1460#Method void reset()
1461
Cary Clark154beea2017-10-26 07:58:48 -04001462Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
1463
1464#Code
1465#Literal
1466| 1 0 0 |
1467| 0 1 0 |
1468| 0 0 1 |
1469##
1470
1471Also called setIdentity(); use the one that provides better inline
1472documentation.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001473
1474#Example
Cary Clark154beea2017-10-26 07:58:48 -04001475SkMatrix m;
1476m.reset();
1477SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1478#StdOut
1479m.isIdentity(): true
1480##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001481##
1482
Cary Clark154beea2017-10-26 07:58:48 -04001483#SeeAlso isIdentity setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04001484
Cary Clark154beea2017-10-26 07:58:48 -04001485#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001486
1487# ------------------------------------------------------------------------------
1488
1489#Method void setIdentity()
1490
Cary Clark154beea2017-10-26 07:58:48 -04001491Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
1492
1493#Code
1494#Literal
1495| 1 0 0 |
1496| 0 1 0 |
1497| 0 0 1 |
1498##
1499
1500Also called reset(); use the one that provides better inline
1501documentation.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001502
1503#Example
Cary Clark154beea2017-10-26 07:58:48 -04001504SkMatrix m;
1505m.setIdentity();
1506SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1507#StdOut
1508m.isIdentity(): true
1509##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001510##
1511
Cary Clark154beea2017-10-26 07:58:48 -04001512#SeeAlso isIdentity reset
Cary Clarkbc5697d2017-10-04 14:31:33 -04001513
Cary Clark154beea2017-10-26 07:58:48 -04001514#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001515
1516# ------------------------------------------------------------------------------
1517
1518#Method void setTranslate(SkScalar dx, SkScalar dy)
1519
Cary Clark154beea2017-10-26 07:58:48 -04001520Sets Matrix to translate by (dx, dy).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001521
Cary Clark154beea2017-10-26 07:58:48 -04001522#Param dx horizontal translation ##
1523#Param dy vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001524
1525#Example
Cary Clark154beea2017-10-26 07:58:48 -04001526#Height 64
1527SkPaint paint;
1528paint.setAntiAlias(true);
1529paint.setTextSize(24);
1530canvas->drawString("normal", 8, 24, paint);
1531SkMatrix matrix;
1532matrix.setTranslate(96, 24);
1533canvas->concat(matrix);
1534canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001535##
1536
Cary Clark154beea2017-10-26 07:58:48 -04001537#SeeAlso setTranslateX setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001538
Cary Clark154beea2017-10-26 07:58:48 -04001539#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001540
1541# ------------------------------------------------------------------------------
1542
1543#Method void setTranslate(const SkVector& v)
1544
Cary Clark154beea2017-10-26 07:58:48 -04001545Sets Matrix to translate by (v.fX, v.fY).
1546
1547#Param v Vector containing horizontal and vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001548
1549#Example
Cary Clark154beea2017-10-26 07:58:48 -04001550#Height 64
1551SkPaint paint;
1552paint.setAntiAlias(true);
1553paint.setTextSize(24);
1554canvas->drawString("normal", 8, 24, paint);
1555SkMatrix matrix;
1556matrix.setTranslate({96, 24});
1557canvas->concat(matrix);
1558canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001559##
1560
Cary Clark154beea2017-10-26 07:58:48 -04001561#SeeAlso setTranslateX setTranslateY MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001562
Cary Clark154beea2017-10-26 07:58:48 -04001563#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001564
1565# ------------------------------------------------------------------------------
1566
1567#Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
1568
Cary Clark154beea2017-10-26 07:58:48 -04001569Sets Matrix to scale by sx and sy, about a pivot point at (px, py).
1570The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001571
Cary Clark154beea2017-10-26 07:58:48 -04001572#Param sx horizontal scale factor ##
1573#Param sy vertical scale factor ##
1574#Param px pivot x ##
1575#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001576
1577#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001578#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001579 SkPaint p;
1580 p.setAntiAlias(true);
1581 p.setTextSize(64);
1582 SkMatrix m;
1583 for (SkScalar sx : { -1, 1 } ) {
1584 for (SkScalar sy : { -1, 1 } ) {
1585 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001586 m.setScale(sx, sy, 128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001587 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001588 canvas->drawString("%", 128, 64, p);
Cary Clark154beea2017-10-26 07:58:48 -04001589 }
1590 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001591##
1592
Cary Clark154beea2017-10-26 07:58:48 -04001593#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001594
Cary Clark154beea2017-10-26 07:58:48 -04001595#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001596
1597# ------------------------------------------------------------------------------
1598
1599#Method void setScale(SkScalar sx, SkScalar sy)
1600
Cary Clark154beea2017-10-26 07:58:48 -04001601Sets Matrix to scale by sx and sy about at pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001602
Cary Clark154beea2017-10-26 07:58:48 -04001603#Param sx horizontal scale factor ##
1604#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001605
1606#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001607#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001608 SkPaint p;
1609 p.setAntiAlias(true);
1610 p.setTextSize(64);
1611 SkMatrix m;
1612 for (SkScalar sx : { -1, 1 } ) {
1613 for (SkScalar sy : { -1, 1 } ) {
1614 SkAutoCanvasRestore autoRestore(canvas, true);
1615 m.setScale(sx, sy);
Cary Clark2ade9972017-11-02 17:49:34 -04001616 m.postTranslate(128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001617 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001618 canvas->drawString("@", 0, 0, p);
Cary Clark154beea2017-10-26 07:58:48 -04001619 }
1620 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001621##
1622
Cary Clark154beea2017-10-26 07:58:48 -04001623#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001624
Cary Clark154beea2017-10-26 07:58:48 -04001625#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001626
1627# ------------------------------------------------------------------------------
1628
1629#Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py)
1630
Cary Clark154beea2017-10-26 07:58:48 -04001631Sets Matrix to rotate by degrees about a pivot point at (px, py).
1632The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001633
Cary Clark154beea2017-10-26 07:58:48 -04001634Positive degrees rotates clockwise.
1635
1636#Param degrees angle of axes relative to upright axes ##
1637#Param px pivot x ##
1638#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001639
1640#Example
Cary Clark154beea2017-10-26 07:58:48 -04001641#Height 128
1642 SkPaint paint;
1643 paint.setColor(SK_ColorGRAY);
1644 paint.setAntiAlias(true);
1645 SkRect rect = {20, 20, 100, 100};
1646 canvas->drawRect(rect, paint);
1647 paint.setColor(SK_ColorRED);
1648 SkMatrix matrix;
1649 matrix.setRotate(25, rect.centerX(), rect.centerY());
1650 canvas->concat(matrix);
1651 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001652##
1653
Cary Clark154beea2017-10-26 07:58:48 -04001654#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001655
Cary Clark154beea2017-10-26 07:58:48 -04001656#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001657
1658# ------------------------------------------------------------------------------
1659
1660#Method void setRotate(SkScalar degrees)
1661
Cary Clark154beea2017-10-26 07:58:48 -04001662Sets Matrix to rotate by degrees about a pivot point at (0, 0).
1663Positive degrees rotates clockwise.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001664
Cary Clark154beea2017-10-26 07:58:48 -04001665#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001666
1667#Example
Cary Clark154beea2017-10-26 07:58:48 -04001668#Height 128
1669 SkPaint paint;
1670 paint.setColor(SK_ColorGRAY);
1671 paint.setAntiAlias(true);
1672 SkRect rect = {20, 20, 100, 100};
1673 canvas->drawRect(rect, paint);
1674 paint.setColor(SK_ColorRED);
1675 SkMatrix matrix;
1676 matrix.setRotate(25);
1677 canvas->translate(rect.centerX(), rect.centerY());
1678 canvas->concat(matrix);
1679 canvas->translate(-rect.centerX(), -rect.centerY());
1680 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001681##
1682
Cary Clark154beea2017-10-26 07:58:48 -04001683#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001684
Cary Clark154beea2017-10-26 07:58:48 -04001685#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001686
1687# ------------------------------------------------------------------------------
1688
1689#Method void setSinCos(SkScalar sinValue, SkScalar cosValue,
1690 SkScalar px, SkScalar py)
1691
Cary Clark154beea2017-10-26 07:58:48 -04001692Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (px, py).
1693The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001694
Cary Clark154beea2017-10-26 07:58:48 -04001695Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
1696Vector length specifies scale.
1697
1698#Param sinValue rotation vector x component ##
1699#Param cosValue rotation vector y component ##
1700#Param px pivot x ##
1701#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001702
1703#Example
Cary Clark154beea2017-10-26 07:58:48 -04001704#Height 128
1705 SkPaint paint;
1706 paint.setColor(SK_ColorGRAY);
1707 paint.setAntiAlias(true);
1708 SkRect rect = {20, 20, 100, 100};
1709 canvas->drawRect(rect, paint);
1710 paint.setColor(SK_ColorRED);
1711 SkMatrix matrix;
1712 matrix.setSinCos(.25f, .85f, rect.centerX(), rect.centerY());
1713 canvas->concat(matrix);
1714 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001715##
1716
Cary Clark154beea2017-10-26 07:58:48 -04001717#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001718
Cary Clark154beea2017-10-26 07:58:48 -04001719#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001720
1721# ------------------------------------------------------------------------------
1722
1723#Method void setSinCos(SkScalar sinValue, SkScalar cosValue)
1724
Cary Clark154beea2017-10-26 07:58:48 -04001725Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001726
Cary Clark154beea2017-10-26 07:58:48 -04001727Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
1728Vector length specifies scale.
1729
1730#Param sinValue rotation vector x component ##
1731#Param cosValue rotation vector y component ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001732
1733#Example
Cary Clark154beea2017-10-26 07:58:48 -04001734#Description
1735Canvas needs offset after applying Matrix to pivot about Rect center.
1736##
1737#Height 128
1738 SkPaint paint;
1739 paint.setColor(SK_ColorGRAY);
1740 paint.setAntiAlias(true);
1741 SkRect rect = {20, 20, 100, 100};
1742 canvas->drawRect(rect, paint);
1743 paint.setColor(SK_ColorRED);
1744 SkMatrix matrix;
1745 matrix.setSinCos(.25f, .85f);
1746 matrix.postTranslate(rect.centerX(), rect.centerY());
1747 canvas->concat(matrix);
1748 canvas->translate(-rect.centerX(), -rect.centerY());
1749 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001750##
1751
Cary Clark154beea2017-10-26 07:58:48 -04001752#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001753
Cary Clark154beea2017-10-26 07:58:48 -04001754#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001755
1756# ------------------------------------------------------------------------------
1757
1758#Method SkMatrix& setRSXform(const SkRSXform& rsxForm)
1759
Cary Clark154beea2017-10-26 07:58:48 -04001760Sets Matrix to rotate, scale, and translate using a compressed matrix form.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001761
Cary Clark154beea2017-10-26 07:58:48 -04001762Vector (rsxForm.fSSin, rsxForm.fSCos) describes the angle of rotation relative
1763to (0, 1). Vector length specifies scale. Mapped point is rotated and scaled
1764by Vector, then translated by (rsxForm.fTx, rsxForm.fTy).
1765
1766#Param rsxForm compressed RSXform matrix ##
1767
1768#Return reference to Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001769
1770#Example
Cary Clark154beea2017-10-26 07:58:48 -04001771#Description
1772Canvas needs offset after applying Matrix to pivot about Rect center.
1773##
1774#Height 128
1775 SkPaint paint;
1776 paint.setColor(SK_ColorGRAY);
1777 paint.setAntiAlias(true);
1778 SkRect rect = {20, 20, 100, 100};
1779 canvas->drawRect(rect, paint);
1780 paint.setColor(SK_ColorRED);
1781 SkMatrix matrix;
1782 matrix.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY()));
1783 canvas->concat(matrix);
1784 canvas->translate(-rect.centerX(), -rect.centerY());
1785 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001786##
1787
Cary Clark154beea2017-10-26 07:58:48 -04001788#SeeAlso setSinCos setScale setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001789
Cary Clark154beea2017-10-26 07:58:48 -04001790#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001791
1792# ------------------------------------------------------------------------------
1793
1794#Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
1795
Cary Clark154beea2017-10-26 07:58:48 -04001796Sets Matrix to skew by kx and ky, about a pivot point at (px, py).
1797The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001798
Cary Clark154beea2017-10-26 07:58:48 -04001799#Param kx horizontal skew factor ##
1800#Param ky vertical skew factor ##
1801#Param px pivot x ##
1802#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001803
1804#Example
Cary Clark154beea2017-10-26 07:58:48 -04001805 SkPaint p;
1806 p.setAntiAlias(true);
1807 p.setTextSize(48);
1808 SkMatrix m;
1809 for (SkScalar sx : { -1, 0, 1 } ) {
1810 for (SkScalar sy : { -1, 0, 1 } ) {
1811 SkAutoCanvasRestore autoRestore(canvas, true);
1812 m.setSkew(sx, sy, 96 + 64 * sx, 128 + 48 * sy);
1813 canvas->concat(m);
1814 canvas->drawString("K", 96 + 64 * sx, 128 + 48 * sy, p);
1815 }
1816 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001817##
1818
Cary Clark154beea2017-10-26 07:58:48 -04001819#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001820
Cary Clark154beea2017-10-26 07:58:48 -04001821#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001822
1823# ------------------------------------------------------------------------------
1824
1825#Method void setSkew(SkScalar kx, SkScalar ky)
1826
Cary Clark154beea2017-10-26 07:58:48 -04001827Sets Matrix to skew by kx and ky, about a pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001828
Cary Clark154beea2017-10-26 07:58:48 -04001829#Param kx horizontal skew factor ##
1830#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001831
1832#Example
Cary Clark154beea2017-10-26 07:58:48 -04001833 SkPaint p;
1834 p.setAntiAlias(true);
1835 p.setTextSize(48);
1836 SkMatrix m;
1837 for (SkScalar sx : { -1, 0, 1 } ) {
1838 for (SkScalar sy : { -1, 0, 1 } ) {
1839 SkAutoCanvasRestore autoRestore(canvas, true);
1840 m.setSkew(sx, sy);
1841 m.postTranslate(96 + 64 * sx, 128 + 48 * sy);
1842 canvas->concat(m);
1843 canvas->drawString("K", 0, 0, p);
1844 }
1845 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001846##
1847
Cary Clark154beea2017-10-26 07:58:48 -04001848#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001849
Cary Clark154beea2017-10-26 07:58:48 -04001850#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001851
1852# ------------------------------------------------------------------------------
1853
1854#Method void setConcat(const SkMatrix& a, const SkMatrix& b)
1855
Cary Clark154beea2017-10-26 07:58:48 -04001856Sets Matrix to Matrix a multiplied by Matrix b. Either a or b may be this.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001857
Cary Clark154beea2017-10-26 07:58:48 -04001858Given:
1859
1860#Code
1861#Literal
1862 | A B C | | J K L |
1863a = | D E F |, b = | M N O |
1864 | G H I | | P Q R |
1865##
1866
1867sets Matrix to:
1868
1869#Code
1870#Literal
1871 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
1872a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
1873 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
1874##
1875
1876#Param a Matrix on left side of multiply expression ##
1877#Param b Matrix on right side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001878
1879#Example
Cary Clark154beea2017-10-26 07:58:48 -04001880#Image 3
1881#Description
1882setPolyToPoly creates perspective matrices, one the inverse of the other.
1883Multiplying the matrix by its inverse turns into an identity matrix.
1884##
1885SkMatrix matrix, matrix2;
1886SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1887SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1888matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1889matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
1890matrix.setConcat(matrix, matrix2);
1891canvas->concat(matrix);
1892canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001893##
1894
Cary Clark154beea2017-10-26 07:58:48 -04001895#SeeAlso Concat preConcat postConcat SkCanvas::concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04001896
Cary Clark154beea2017-10-26 07:58:48 -04001897#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001898
1899# ------------------------------------------------------------------------------
1900
1901#Method void preTranslate(SkScalar dx, SkScalar dy)
1902
Cary Clark154beea2017-10-26 07:58:48 -04001903Sets Matrix to Matrix multiplied by Matrix constructed from translation (dx, dy).
1904This can be thought of as moving the point to be mapped before applying Matrix.
1905
1906Given:
1907
1908#Code
1909#Literal
1910 | A B C | | 1 0 dx |
1911Matrix = | D E F |, T(dx, dy) = | 0 1 dy |
1912 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001913##
1914
Cary Clark154beea2017-10-26 07:58:48 -04001915sets Matrix to:
1916
1917#Code
1918#Literal
1919 | A B C | | 1 0 dx | | A B A*dx+B*dy+C |
1920Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F |
1921 | G H I | | 0 0 1 | | G H G*dx+H*dy+I |
1922##
1923
1924#Param dx x translation before applying Matrix ##
1925#Param dy y translation before applying Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001926
1927#Example
Cary Clark154beea2017-10-26 07:58:48 -04001928#Height 160
1929 SkPaint paint;
1930 paint.setAntiAlias(true);
1931 SkRect rect = {20, 20, 100, 100};
1932 for (int i = 0; i < 2; ++i ) {
1933 SkMatrix matrix;
1934 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
1935 {
1936 SkAutoCanvasRestore acr(canvas, true);
1937 canvas->concat(matrix);
1938 paint.setColor(SK_ColorGRAY);
1939 canvas->drawRect(rect, paint);
1940 }
1941 paint.setColor(SK_ColorRED);
1942 for (int j = 0; j < 2; ++j ) {
1943 SkAutoCanvasRestore acr(canvas, true);
1944 matrix.preTranslate(40, 40);
1945 canvas->concat(matrix);
1946 canvas->drawCircle(0, 0, 3, paint);
1947 }
1948 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001949##
1950
Cary Clark154beea2017-10-26 07:58:48 -04001951#SeeAlso postTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001952
Cary Clark154beea2017-10-26 07:58:48 -04001953#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001954
1955# ------------------------------------------------------------------------------
1956
1957#Method void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
1958
Cary Clark154beea2017-10-26 07:58:48 -04001959Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
1960about pivot point (px, py).
1961This can be thought of as scaling about a pivot point before applying Matrix.
1962
1963Given:
1964
1965#Code
1966#Literal
1967 | A B C | | sx 0 dx |
1968Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy |
1969 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001970##
1971
Cary Clark154beea2017-10-26 07:58:48 -04001972where
1973
1974#Code
1975#Literal
1976dx = px - sx * px
1977dy = py - sy * py
1978##
1979
1980sets Matrix to:
1981
1982#Code
1983#Literal
1984 | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C |
1985Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F |
1986 | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I |
1987##
1988
1989#Param sx horizontal scale factor ##
1990#Param sy vertical scale factor ##
1991#Param px pivot x ##
1992#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001993
1994#Example
Cary Clark154beea2017-10-26 07:58:48 -04001995#Image 3
1996SkMatrix matrix;
1997SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1998SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1999matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2000matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
2001canvas->concat(matrix);
2002canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002003##
2004
Cary Clark154beea2017-10-26 07:58:48 -04002005#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002006
Cary Clark154beea2017-10-26 07:58:48 -04002007#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002008
2009# ------------------------------------------------------------------------------
2010
2011#Method void preScale(SkScalar sx, SkScalar sy)
2012
Cary Clark154beea2017-10-26 07:58:48 -04002013Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
2014about pivot point (0, 0).
2015This can be thought of as scaling about the origin before applying Matrix.
2016
2017Given:
2018
2019#Code
2020#Literal
2021 | A B C | | sx 0 0 |
2022Matrix = | D E F |, S(sx, sy) = | 0 sy 0 |
2023 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002024##
2025
Cary Clark154beea2017-10-26 07:58:48 -04002026sets Matrix to:
2027
2028#Code
2029#Literal
2030 | A B C | | sx 0 0 | | A*sx B*sy C |
2031Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F |
2032 | G H I | | 0 0 1 | | G*sx H*sy I |
2033##
2034
2035#Param sx horizontal scale factor ##
2036#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002037
2038#Example
Cary Clark154beea2017-10-26 07:58:48 -04002039#Image 3
2040SkMatrix matrix;
2041SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2042SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2043matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2044matrix.preScale(.75f, 1.5f);
2045canvas->concat(matrix);
2046canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002047##
2048
Cary Clark154beea2017-10-26 07:58:48 -04002049#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002050
Cary Clark154beea2017-10-26 07:58:48 -04002051#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002052
2053# ------------------------------------------------------------------------------
2054
2055#Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py)
2056
Cary Clark154beea2017-10-26 07:58:48 -04002057Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
2058about pivot point (px, py).
2059This can be thought of as rotating about a pivot point before applying Matrix.
2060
2061Positive degrees rotates clockwise.
2062
2063Given:
2064
2065#Code
2066#Literal
2067 | A B C | | c -s dx |
2068Matrix = | D E F |, R(degrees, px, py) = | s c dy |
2069 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002070##
2071
Cary Clark154beea2017-10-26 07:58:48 -04002072where
2073
2074#Code
2075#Literal
2076c = cos(degrees)
2077s = sin(degrees)
2078dx = s * py + (1 - c) * px
2079dy = -s * px + (1 - c) * py
2080##
2081
2082sets Matrix to:
2083
2084#Code
2085#Literal
2086 | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C |
2087Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F |
2088 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I |
2089##
2090
2091#Param degrees angle of axes relative to upright axes ##
2092#Param px pivot x ##
2093#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002094
2095#Example
Cary Clark154beea2017-10-26 07:58:48 -04002096#Image 3
2097SkMatrix matrix;
2098SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2099SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2100matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2101matrix.preRotate(45, source.width() / 2, source.height() / 2);
2102canvas->concat(matrix);
2103canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002104##
2105
Cary Clark154beea2017-10-26 07:58:48 -04002106#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002107
Cary Clark154beea2017-10-26 07:58:48 -04002108#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002109
2110# ------------------------------------------------------------------------------
2111
2112#Method void preRotate(SkScalar degrees)
2113
Cary Clark154beea2017-10-26 07:58:48 -04002114Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
2115about pivot point (0, 0).
2116This can be thought of as rotating about the origin before applying Matrix.
2117
2118Positive degrees rotates clockwise.
2119
2120Given:
2121
2122#Code
2123#Literal
2124 | A B C | | c -s 0 |
2125Matrix = | D E F |, R(degrees, px, py) = | s c 0 |
2126 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002127##
2128
Cary Clark154beea2017-10-26 07:58:48 -04002129where
2130
2131#Code
2132#Literal
2133c = cos(degrees)
2134s = sin(degrees)
2135##
2136
2137sets Matrix to:
2138
2139#Code
2140#Literal
2141 | A B C | | c -s 0 | | Ac+Bs -As+Bc C |
2142Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F |
2143 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I |
2144##
2145
2146#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002147
2148#Example
Cary Clark154beea2017-10-26 07:58:48 -04002149#Image 3
2150SkMatrix matrix;
2151SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2152SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2153matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2154matrix.preRotate(45);
2155canvas->concat(matrix);
2156canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002157##
2158
Cary Clark154beea2017-10-26 07:58:48 -04002159#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002160
Cary Clark154beea2017-10-26 07:58:48 -04002161#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002162
2163# ------------------------------------------------------------------------------
2164
2165#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
2166
Cary Clark154beea2017-10-26 07:58:48 -04002167Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
2168about pivot point (px, py).
2169This can be thought of as skewing about a pivot point before applying Matrix.
2170
2171Given:
2172
2173#Code
2174#Literal
2175 | A B C | | 1 kx dx |
2176Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy |
2177 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002178##
2179
Cary Clark154beea2017-10-26 07:58:48 -04002180where
2181
2182#Code
2183#Literal
2184dx = -kx * py
2185dy = -ky * px
2186##
2187
2188sets Matrix to:
2189
2190#Code
2191#Literal
2192 | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C |
2193Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F |
2194 | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I |
2195##
2196
2197#Param kx horizontal skew factor ##
2198#Param ky vertical skew factor ##
2199#Param px pivot x ##
2200#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002201
2202#Example
Cary Clark154beea2017-10-26 07:58:48 -04002203#Image 3
2204SkMatrix matrix;
2205SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2206SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2207matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2208matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2);
2209canvas->concat(matrix);
2210canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002211##
2212
Cary Clark154beea2017-10-26 07:58:48 -04002213#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002214
Cary Clark154beea2017-10-26 07:58:48 -04002215#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002216
2217# ------------------------------------------------------------------------------
2218
2219#Method void preSkew(SkScalar kx, SkScalar ky)
2220
Cary Clark154beea2017-10-26 07:58:48 -04002221Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
2222about pivot point (0, 0).
2223This can be thought of as skewing about the origin before applying Matrix.
2224
2225Given:
2226
2227#Code
2228#Literal
2229 | A B C | | 1 kx 0 |
2230Matrix = | D E F |, K(kx, ky) = | ky 1 0 |
2231 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002232##
2233
Cary Clark154beea2017-10-26 07:58:48 -04002234sets Matrix to:
2235
2236#Code
2237#Literal
2238 | A B C | | 1 kx 0 | | A+B*ky A*kx+B C |
2239Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F |
2240 | G H I | | 0 0 1 | | G+H*ky G*kx+H I |
2241##
2242
2243#Param kx horizontal skew factor ##
2244#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002245
2246#Example
Cary Clark154beea2017-10-26 07:58:48 -04002247#Image 3
2248SkMatrix matrix;
2249SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2250SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2251matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2252matrix.preSkew(.5f, 0);
2253canvas->concat(matrix);
2254canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002255##
2256
Cary Clark154beea2017-10-26 07:58:48 -04002257#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002258
Cary Clark154beea2017-10-26 07:58:48 -04002259#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002260
2261# ------------------------------------------------------------------------------
2262
2263#Method void preConcat(const SkMatrix& other)
2264
Cary Clark154beea2017-10-26 07:58:48 -04002265Sets Matrix to Matrix multiplied by Matrix other.
2266This can be thought of mapping by other before applying Matrix.
2267
2268Given:
2269
2270#Code
2271#Literal
2272 | A B C | | J K L |
2273Matrix = | D E F |, other = | M N O |
2274 | G H I | | P Q R |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002275##
2276
Cary Clark154beea2017-10-26 07:58:48 -04002277sets Matrix to:
2278
2279#Code
2280#Literal
2281 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
2282Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
2283 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
2284##
2285
2286#Param other Matrix on right side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002287
2288#Example
Cary Clark154beea2017-10-26 07:58:48 -04002289#Image 3
2290#Description
2291setPolyToPoly creates perspective matrices, one the inverse of the other.
2292Multiplying the matrix by its inverse turns into an identity matrix.
2293##
2294SkMatrix matrix, matrix2;
2295SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2296SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2297matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2298matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
2299matrix.preConcat(matrix2);
2300canvas->concat(matrix);
2301canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002302##
2303
Cary Clark154beea2017-10-26 07:58:48 -04002304#SeeAlso postConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002305
Cary Clark154beea2017-10-26 07:58:48 -04002306#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002307
2308# ------------------------------------------------------------------------------
2309
2310#Method void postTranslate(SkScalar dx, SkScalar dy)
2311
Cary Clark154beea2017-10-26 07:58:48 -04002312Sets Matrix to Matrix constructed from translation (dx, dy) multiplied by Matrix.
2313This can be thought of as moving the point to be mapped after applying Matrix.
2314
2315Given:
2316
2317#Code
2318#Literal
2319 | J K L | | 1 0 dx |
2320Matrix = | M N O |, T(dx, dy) = | 0 1 dy |
2321 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002322##
2323
Cary Clark154beea2017-10-26 07:58:48 -04002324sets Matrix to:
2325
2326#Code
2327#Literal
2328 | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R |
2329T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R |
2330 | 0 0 1 | | P Q R | | P Q R |
2331##
2332
2333#Param dx x translation after applying Matrix ##
2334#Param dy y translation after applying Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002335
2336#Example
Cary Clark154beea2017-10-26 07:58:48 -04002337#Height 160
2338#Description
2339Compare with preTranslate example.
2340##
2341 SkPaint paint;
2342 paint.setAntiAlias(true);
2343 SkRect rect = {20, 20, 100, 100};
2344 for (int i = 0; i < 2; ++i ) {
2345 SkMatrix matrix;
2346 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
2347 {
2348 SkAutoCanvasRestore acr(canvas, true);
2349 canvas->concat(matrix);
2350 paint.setColor(SK_ColorGRAY);
2351 canvas->drawRect(rect, paint);
2352 }
2353 paint.setColor(SK_ColorRED);
2354 for (int j = 0; j < 2; ++j ) {
2355 SkAutoCanvasRestore acr(canvas, true);
2356 matrix.postTranslate(40, 40);
2357 canvas->concat(matrix);
2358 canvas->drawCircle(0, 0, 3, paint);
2359 }
2360 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002361##
2362
Cary Clark154beea2017-10-26 07:58:48 -04002363#SeeAlso preTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04002364
Cary Clark154beea2017-10-26 07:58:48 -04002365#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002366
2367# ------------------------------------------------------------------------------
2368
2369#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
2370
Cary Clark154beea2017-10-26 07:58:48 -04002371Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
2372(px, py), multiplied by Matrix.
2373This can be thought of as scaling about a pivot point after applying Matrix.
2374
2375Given:
2376
2377#Code
2378#Literal
2379 | J K L | | sx 0 dx |
2380Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy |
2381 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002382##
2383
Cary Clark154beea2017-10-26 07:58:48 -04002384where
2385
2386#Code
2387#Literal
2388dx = px - sx * px
2389dy = py - sy * py
2390##
2391
2392sets Matrix to:
2393
2394#Code
2395#Literal
2396 | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R |
2397S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R |
2398 | 0 0 1 | | P Q R | | P Q R |
2399##
2400
2401#Param sx horizontal scale factor ##
2402#Param sy vertical scale factor ##
2403#Param px pivot x ##
2404#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002405
2406#Example
Cary Clark154beea2017-10-26 07:58:48 -04002407#Image 3
2408SkMatrix matrix;
2409SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2410SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2411matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2412matrix.postScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
2413canvas->concat(matrix);
2414canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002415##
2416
Cary Clark154beea2017-10-26 07:58:48 -04002417#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002418
2419##
2420
2421# ------------------------------------------------------------------------------
2422
2423#Method void postScale(SkScalar sx, SkScalar sy)
2424
Cary Clark154beea2017-10-26 07:58:48 -04002425Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
2426(0, 0), multiplied by Matrix.
2427This can be thought of as scaling about the origin after applying Matrix.
2428
2429Given:
2430
2431#Code
2432#Literal
2433 | J K L | | sx 0 0 |
2434Matrix = | M N O |, S(sx, sy) = | 0 sy 0 |
2435 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002436##
2437
Cary Clark154beea2017-10-26 07:58:48 -04002438sets Matrix to:
2439
2440#Code
2441#Literal
2442 | sx 0 0 | | J K L | | sx*J sx*K sx*L |
2443S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
2444 | 0 0 1 | | P Q R | | P Q R |
2445##
2446
2447#Param sx horizontal scale factor ##
2448#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002449
2450#Example
Cary Clark154beea2017-10-26 07:58:48 -04002451#Image 3
2452SkMatrix matrix;
2453SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2454SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2455matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2456matrix.postScale(.75f, 1.5f);
2457canvas->concat(matrix);
2458canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002459##
2460
Cary Clark154beea2017-10-26 07:58:48 -04002461#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002462
2463##
2464
2465# ------------------------------------------------------------------------------
2466
2467#Method bool postIDiv(int divx, int divy)
2468
Cary Clark154beea2017-10-26 07:58:48 -04002469Sets Matrix to Matrix constructed from scaling by
Cary Clarkbc5697d2017-10-04 14:31:33 -04002470#Formula
Cary Clark154beea2017-10-26 07:58:48 -04002471(1/divx, 1/divy)
2472##
2473about pivot point (px, py), multiplied by Matrix.
2474
2475Returns false if either divx or divy is zero.
2476
2477Given:
2478
2479#Code
2480#Literal
2481 | J K L | | sx 0 0 |
2482Matrix = | M N O |, I(divx, divy) = | 0 sy 0 |
2483 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002484##
2485
Cary Clark154beea2017-10-26 07:58:48 -04002486where
Cary Clarkbc5697d2017-10-04 14:31:33 -04002487
Cary Clark154beea2017-10-26 07:58:48 -04002488#Code
2489#Literal
2490sx = 1 / divx
2491sy = 1 / divy
2492##
2493
2494sets Matrix to:
2495
2496#Code
2497#Literal
2498 | sx 0 0 | | J K L | | sx*J sx*K sx*L |
2499I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
2500 | 0 0 1 | | P Q R | | P Q R |
2501##
2502
2503#Param divx integer divisor for inverse scale in x ##
2504#Param divy integer divisor for inverse scale in y ##
2505
2506#Return true on successful scale ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002507
2508#Example
Cary Clark154beea2017-10-26 07:58:48 -04002509#Image 3
2510SkMatrix matrix, matrix2;
2511SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2512SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2513matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2514matrix.postIDiv(1, 2);
2515canvas->concat(matrix);
2516canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002517##
2518
Cary Clark154beea2017-10-26 07:58:48 -04002519#SeeAlso postScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002520
2521##
2522
2523# ------------------------------------------------------------------------------
2524
2525#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py)
2526
Cary Clark154beea2017-10-26 07:58:48 -04002527Sets Matrix to Matrix constructed from rotating by degrees about pivot point
2528(px, py), multiplied by Matrix.
2529This can be thought of as rotating about a pivot point after applying Matrix.
2530
2531Positive degrees rotates clockwise.
2532
2533Given:
2534
2535#Code
2536#Literal
2537 | J K L | | c -s dx |
2538Matrix = | M N O |, R(degrees, px, py) = | s c dy |
2539 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002540##
2541
Cary Clark154beea2017-10-26 07:58:48 -04002542where
2543
2544#Code
2545#Literal
2546c = cos(degrees)
2547s = sin(degrees)
2548dx = s * py + (1 - c) * px
2549dy = -s * px + (1 - c) * py
2550##
2551
2552sets Matrix to:
2553
2554#Code
2555#Literal
2556 |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R|
2557R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R|
2558 |0 0 1| |P Q R| | P Q R|
2559##
2560
2561#Param degrees angle of axes relative to upright axes ##
2562#Param px pivot x ##
2563#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002564
2565#Example
Cary Clark154beea2017-10-26 07:58:48 -04002566#Image 3
2567SkMatrix matrix;
2568SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2569SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2570matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2571matrix.postRotate(45, source.width() / 2, source.height() / 2);
2572canvas->concat(matrix);
2573canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002574##
2575
Cary Clark154beea2017-10-26 07:58:48 -04002576#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002577
2578##
2579
2580# ------------------------------------------------------------------------------
2581
2582#Method void postRotate(SkScalar degrees)
2583
Cary Clark154beea2017-10-26 07:58:48 -04002584Sets Matrix to Matrix constructed from rotating by degrees about pivot point
2585(0, 0), multiplied by Matrix.
2586This can be thought of as rotating about the origin after applying Matrix.
2587
2588Positive degrees rotates clockwise.
2589
2590Given:
2591
2592#Code
2593#Literal
2594 | J K L | | c -s 0 |
2595Matrix = | M N O |, R(degrees, px, py) = | s c 0 |
2596 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002597##
2598
Cary Clark154beea2017-10-26 07:58:48 -04002599where
2600
2601#Code
2602#Literal
2603c = cos(degrees)
2604s = sin(degrees)
2605##
2606
2607sets Matrix to:
2608
2609#Code
2610#Literal
2611 | c -s dx | | J K L | | cJ-sM cK-sN cL-sO |
2612R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO |
2613 | 0 0 1 | | P Q R | | P Q R |
2614##
2615
2616#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002617
2618#Example
Cary Clark154beea2017-10-26 07:58:48 -04002619#Image 3
2620SkMatrix matrix;
2621SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2622SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2623matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2624matrix.postRotate(45);
2625canvas->concat(matrix);
2626canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002627##
2628
Cary Clark154beea2017-10-26 07:58:48 -04002629#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002630
2631##
2632
2633# ------------------------------------------------------------------------------
2634
2635#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
2636
Cary Clark154beea2017-10-26 07:58:48 -04002637Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
2638(px, py), multiplied by Matrix.
2639This can be thought of as skewing about a pivot point after applying Matrix.
2640
2641Given:
2642
2643#Code
2644#Literal
2645 | J K L | | 1 kx dx |
2646Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy |
2647 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002648##
2649
Cary Clark154beea2017-10-26 07:58:48 -04002650where
2651
2652#Code
2653#Literal
2654dx = -kx * py
2655dy = -ky * px
2656##
2657
2658sets Matrix to:
2659
2660#Code
2661#Literal
2662 | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R|
2663K(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|
2664 | 0 0 1| |P Q R| | P Q R|
2665##
2666
2667#Param kx horizontal skew factor ##
2668#Param ky vertical skew factor ##
2669#Param px pivot x ##
2670#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002671
2672#Example
Cary Clark154beea2017-10-26 07:58:48 -04002673#Image 3
2674SkMatrix matrix;
2675SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2676SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2677matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2678matrix.postSkew(.5f, 0, source.width() / 2, source.height() / 2);
2679canvas->concat(matrix);
2680canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002681##
2682
Cary Clark154beea2017-10-26 07:58:48 -04002683#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002684
2685##
2686
2687# ------------------------------------------------------------------------------
2688
2689#Method void postSkew(SkScalar kx, SkScalar ky)
2690
Cary Clark154beea2017-10-26 07:58:48 -04002691Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
2692(0, 0), multiplied by Matrix.
2693This can be thought of as skewing about the origin after applying Matrix.
2694
2695Given:
2696
2697#Code
2698#Literal
2699 | J K L | | 1 kx 0 |
2700Matrix = | M N O |, K(kx, ky) = | ky 1 0 |
2701 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002702##
2703
Cary Clark154beea2017-10-26 07:58:48 -04002704sets Matrix to:
2705
2706#Code
2707#Literal
2708 | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O |
2709K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O |
2710 | 0 0 1 | | P Q R | | P Q R |
2711##
2712
2713#Param kx horizontal skew factor ##
2714#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002715
2716#Example
Cary Clark154beea2017-10-26 07:58:48 -04002717#Image 3
2718SkMatrix matrix;
2719SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2720SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2721matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2722matrix.postSkew(.5f, 0);
2723canvas->concat(matrix);
2724canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002725##
2726
Cary Clark154beea2017-10-26 07:58:48 -04002727#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002728
2729##
2730
2731# ------------------------------------------------------------------------------
2732
2733#Method void postConcat(const SkMatrix& other)
2734
Cary Clark154beea2017-10-26 07:58:48 -04002735Sets Matrix to Matrix other multiplied by Matrix.
2736This can be thought of mapping by other after applying Matrix.
2737
2738Given:
2739
2740#Code
2741#Literal
2742 | J K L | | A B C |
2743Matrix = | M N O |, other = | D E F |
2744 | P Q R | | G H I |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002745##
2746
Cary Clark154beea2017-10-26 07:58:48 -04002747sets Matrix to:
2748
2749#Code
2750#Literal
2751 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
2752other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
2753 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
2754##
2755
2756#Param other Matrix on left side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002757
2758#Example
Cary Clark154beea2017-10-26 07:58:48 -04002759#Image 3
2760#Height 64
2761SkMatrix matrix, matrix2;
2762SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2763SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2764matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2765matrix.postConcat(matrix);
2766canvas->concat(matrix);
2767canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002768##
2769
Cary Clark154beea2017-10-26 07:58:48 -04002770#SeeAlso preConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002771
2772##
2773
2774# ------------------------------------------------------------------------------
2775
2776#Enum ScaleToFit
2777
2778#Code
2779 enum ScaleToFit {
2780 kFill_ScaleToFit,
2781 kStart_ScaleToFit,
2782 kCenter_ScaleToFit,
2783 kEnd_ScaleToFit,
2784 };
2785##
2786
Cary Clark154beea2017-10-26 07:58:48 -04002787ScaleToFit describes how Matrix is constructed to map one Rect to another.
2788ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling,
2789or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies
2790how Matrix maps to the side or center of the destination Rect.
2791
2792#Const kFill_ScaleToFit 0
2793 Computes Matrix that scales in x and y independently, so that source Rect is
2794 mapped to completely fill destination Rect. The aspect ratio of source Rect
2795 may change.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002796##
Cary Clark154beea2017-10-26 07:58:48 -04002797#Const kStart_ScaleToFit 1
2798 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2799 width or height to destination Rect. Aligns mapping to left and top edges
2800 of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002801##
Cary Clark154beea2017-10-26 07:58:48 -04002802#Const kCenter_ScaleToFit 2
2803 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2804 width or height to destination Rect. Aligns mapping to center of destination
2805 Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002806##
Cary Clark154beea2017-10-26 07:58:48 -04002807#Const kEnd_ScaleToFit 3
2808 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2809 width or height to destination Rect. Aligns mapping to right and bottom
2810 edges of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002811##
2812
2813#Example
Cary Clark154beea2017-10-26 07:58:48 -04002814 const char* labels[] = { "Fill", "Start", "Center", "End" };
2815 SkRect rects[] = {{5, 5, 59, 59}, {5, 74, 59, 108}, {10, 123, 44, 172}, {10, 187, 54, 231}};
2816 SkRect bounds;
2817 source.getBounds(&bounds);
2818 SkPaint paint;
2819 paint.setAntiAlias(true);
2820 for (auto fit : { SkMatrix::kFill_ScaleToFit, SkMatrix::kStart_ScaleToFit,
2821 SkMatrix::kCenter_ScaleToFit, SkMatrix::kEnd_ScaleToFit } ) {
2822 for (auto rect : rects ) {
2823 canvas->drawRect(rect, paint);
2824 SkMatrix matrix;
2825 if (!matrix.setRectToRect(bounds, rect, fit)) {
2826 continue;
2827 }
2828 SkAutoCanvasRestore acr(canvas, true);
2829 canvas->concat(matrix);
2830 canvas->drawBitmap(source, 0, 0);
2831 }
2832 canvas->drawString(labels[fit], 10, 255, paint);
2833 canvas->translate(64, 0);
2834 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002835##
2836
Cary Clark154beea2017-10-26 07:58:48 -04002837#SeeAlso setRectToRect MakeRectToRect setPolyToPoly
Cary Clarkbc5697d2017-10-04 14:31:33 -04002838
2839##
2840
2841# ------------------------------------------------------------------------------
2842
2843#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
2844
Cary Clark154beea2017-10-26 07:58:48 -04002845Sets Matrix to scale and translate src Rect to dst Rect. stf selects whether
2846mapping completely fills dst or preserves the aspect ratio, and how to align
2847src within dst. Returns false if src is empty, and sets Matrix to identity.
2848Returns true if dst is empty, and sets Matrix to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04002849
Cary Clark154beea2017-10-26 07:58:48 -04002850#Code
2851#Literal
2852| 0 0 0 |
2853| 0 0 0 |
2854| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002855##
2856
Cary Clark154beea2017-10-26 07:58:48 -04002857#Param src Rect to map from ##
2858#Param dst Rect to map to ##
2859#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
2860 kCenter_ScaleToFit, kEnd_ScaleToFit
Cary Clarkbc5697d2017-10-04 14:31:33 -04002861##
2862
Cary Clark154beea2017-10-26 07:58:48 -04002863#Return true if Matrix can represent Rect mapping ##
2864
Cary Clarkbc5697d2017-10-04 14:31:33 -04002865#Example
Cary Clark154beea2017-10-26 07:58:48 -04002866 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
2867 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
2868 for (auto src : srcs) {
2869 for (auto dst : dsts) {
2870 SkMatrix matrix;
2871 matrix.setAll(-1, -1, -1, -1, -1, -1, -1, -1, -1);
2872 bool success = matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
2873 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g success: %s\n",
2874 src.fLeft, src.fTop, src.fRight, src.fBottom,
2875 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, success ? "true" : "false");
2876 matrix.dump();
2877 }
2878 }
2879#StdOut
2880src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false
2881[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2882src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false
2883[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2884src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true
2885[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2886src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true
2887[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
2888##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002889##
2890
Cary Clark154beea2017-10-26 07:58:48 -04002891#SeeAlso MakeRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04002892
2893##
2894
2895# ------------------------------------------------------------------------------
2896
2897#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
2898
Cary Clark154beea2017-10-26 07:58:48 -04002899Returns Matrix set to scale and translate src Rect to dst Rect. stf selects
2900whether mapping completely fills dst or preserves the aspect ratio, and how to
2901align src within dst. Returns the identity Matrix if src is empty. If dst is
2902empty, returns Matrix set to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04002903
Cary Clark154beea2017-10-26 07:58:48 -04002904#Code
2905#Literal
2906| 0 0 0 |
2907| 0 0 0 |
2908| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002909##
2910
Cary Clark154beea2017-10-26 07:58:48 -04002911#Param src Rect to map from ##
2912#Param dst Rect to map to ##
2913#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
2914 kCenter_ScaleToFit, kEnd_ScaleToFit
2915##
2916
2917#Return Matrix mapping src to dst ##
2918
2919#Example
2920 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
2921 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
2922 for (auto src : srcs) {
2923 for (auto dst : dsts) {
2924 SkMatrix matrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
2925 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g\n",
2926 src.fLeft, src.fTop, src.fRight, src.fBottom,
2927 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom);
2928 matrix.dump();
2929 }
2930 }
2931#StdOut
2932src: 0, 0, 0, 0 dst: 0, 0, 0, 0
2933[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2934src: 0, 0, 0, 0 dst: 5, 6, 8, 9
2935[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2936src: 1, 2, 3, 4 dst: 0, 0, 0, 0
2937[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2938src: 1, 2, 3, 4 dst: 5, 6, 8, 9
2939[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
2940##
2941##
2942
2943#SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04002944
2945##
2946
2947# ------------------------------------------------------------------------------
2948
2949#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
2950
Cary Clark154beea2017-10-26 07:58:48 -04002951Sets Matrix to map src to dst. count must be zero or greater, and four or less.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002952
Cary Clark154beea2017-10-26 07:58:48 -04002953If count is zero, sets Matrix to identity and returns true.
2954If count is one, sets Matrix to translate and returns true.
2955If count is two or more, sets Matrix to map Points if possible; returns false
2956if Matrix cannot be constructed. If count is four, Matrix may include
2957perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002958
Cary Clark154beea2017-10-26 07:58:48 -04002959#Param src Points to map from ##
2960#Param dst Points to map to ##
2961#Param count number of Points in src and dst ##
2962
2963#Return true if Matrix was constructed successfully
Cary Clarkbc5697d2017-10-04 14:31:33 -04002964##
2965
2966#Example
Cary Clark154beea2017-10-26 07:58:48 -04002967 const SkPoint src[] = { { 0, 0}, {30, 0}, {30, -30}, { 0, -30} };
2968 const SkPoint dst[] = { {50, 0}, {80, -10}, {90, -30}, {60, -40} };
2969 SkPaint blackPaint;
2970 blackPaint.setAntiAlias(true);
2971 blackPaint.setTextSize(42);
2972 SkPaint redPaint = blackPaint;
2973 redPaint.setColor(SK_ColorRED);
2974 for (int count : { 1, 2, 3, 4 } ) {
2975 canvas->translate(35, 55);
2976 for (int index = 0; index < count; ++index) {
2977 canvas->drawCircle(src[index], 3, blackPaint);
2978 canvas->drawCircle(dst[index], 3, blackPaint);
2979 if (index > 0) {
2980 canvas->drawLine(src[index], src[index - 1], blackPaint);
2981 canvas->drawLine(dst[index], dst[index - 1], blackPaint);
2982 }
2983 }
2984 SkMatrix matrix;
2985 matrix.setPolyToPoly(src, dst, count);
2986 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
2987 SkAutoCanvasRestore acr(canvas, true);
2988 canvas->concat(matrix);
2989 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
2990 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002991##
2992
Cary Clark154beea2017-10-26 07:58:48 -04002993#SeeAlso setRectToRect MakeRectToRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04002994
2995##
2996
2997# ------------------------------------------------------------------------------
2998
2999#Method bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const
3000
Cary Clark154beea2017-10-26 07:58:48 -04003001Sets inverse to reciprocal matrix, returning true if Matrix can be inverted.
3002Geometrically, if Matrix maps from source to destination, inverse Matrix
3003maps from destination to source. If Matrix can not be inverted, inverse is
3004unchanged.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003005
Cary Clark154beea2017-10-26 07:58:48 -04003006#Param inverse storage for inverted Matrix; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003007
Cary Clark154beea2017-10-26 07:58:48 -04003008#Return true if Matrix can be inverted ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003009
3010#Example
Cary Clark154beea2017-10-26 07:58:48 -04003011#Height 128
3012 const SkPoint src[] = { { 10, 120}, {120, 120}, {120, 10}, { 10, 10} };
3013 const SkPoint dst[] = { {150, 120}, {200, 100}, {240, 30}, { 130, 40} };
3014 SkPaint paint;
3015 paint.setAntiAlias(true);
3016 SkMatrix matrix;
3017 matrix.setPolyToPoly(src, dst, 4);
3018 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, src, paint);
3019 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, dst, paint);
3020 paint.setColor(SK_ColorBLUE);
3021 paint.setStrokeWidth(3);
3022 paint.setStrokeCap(SkPaint::kRound_Cap);
3023 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
3024 matrix.invert(&matrix);
3025 canvas->concat(matrix);
3026 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003027##
3028
Cary Clark154beea2017-10-26 07:58:48 -04003029#SeeAlso Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04003030
3031##
3032
3033# ------------------------------------------------------------------------------
3034
3035#Method static void SetAffineIdentity(SkScalar affine[6])
3036
Cary Clark154beea2017-10-26 07:58:48 -04003037Fills affine with identity values in column major order.
3038Sets affine to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003039
Cary Clark154beea2017-10-26 07:58:48 -04003040#Code
3041#Literal
3042| 1 0 0 |
3043| 0 1 0 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003044##
3045
Cary Clark154beea2017-10-26 07:58:48 -04003046Affine 3x2 matrices in column major order are used by OpenGL and XPS.
3047
3048#Param affine storage for 3x2 affine matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003049
3050#Example
Cary Clark154beea2017-10-26 07:58:48 -04003051 SkScalar affine[6];
3052 SkMatrix::SetAffineIdentity(affine);
3053 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3054 for (int i = 0; i < 6; ++i) {
3055 SkDebugf("%s: %g ", names[i], affine[i]);
3056 }
3057 SkDebugf("\n");
3058#StdOut
3059ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0
3060##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003061##
3062
Cary Clark154beea2017-10-26 07:58:48 -04003063#SeeAlso setAffine asAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -04003064
3065##
3066
3067# ------------------------------------------------------------------------------
3068
3069#Method bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const
3070
Cary Clark154beea2017-10-26 07:58:48 -04003071Fills affine in column major order. Sets affine to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003072
Cary Clark154beea2017-10-26 07:58:48 -04003073#Code
3074#Literal
3075| scale-x skew-x translate-x |
3076| skew-y scale-y translate-y |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003077##
3078
Cary Clark154beea2017-10-26 07:58:48 -04003079If Matrix contains perspective, returns false and leaves affine unchanged.
3080
3081#Param affine storage for 3x2 affine matrix; may be nullptr ##
3082
3083#Return true if Matrix does not contain perspective ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003084
3085#Example
Cary Clark154beea2017-10-26 07:58:48 -04003086SkMatrix matrix;
3087matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
3088SkScalar affine[6];
3089matrix.asAffine(affine);
3090const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3091for (int i = 0; i < 6; ++i) {
3092 SkDebugf("%s: %g ", names[i], affine[i]);
3093}
3094SkDebugf("\n");
3095#StdOut
3096ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
3097##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003098##
3099
Cary Clark154beea2017-10-26 07:58:48 -04003100#SeeAlso setAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04003101
3102##
3103
3104# ------------------------------------------------------------------------------
3105
3106#Method void setAffine(const SkScalar affine[6])
3107
Cary Clark154beea2017-10-26 07:58:48 -04003108Sets Matrix to affine values, passed in column major order. Given affine,
3109column, then row, as:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003110
Cary Clark154beea2017-10-26 07:58:48 -04003111#Code
3112#Literal
3113| scale-x skew-x translate-x |
3114| skew-y scale-y translate-y |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003115##
3116
Cary Clark154beea2017-10-26 07:58:48 -04003117Matrix is set, row, then column, to:
3118
3119#Code
3120#Literal
3121| scale-x skew-x translate-x |
3122| skew-y scale-y translate-y |
3123| 0 0 1 |
3124##
3125
3126#Param affine 3x2 affine matrix ##
3127
3128#Example
3129SkMatrix matrix;
3130matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
3131SkScalar affine[6];
3132matrix.asAffine(affine);
3133const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3134for (int i = 0; i < 6; ++i) {
3135 SkDebugf("%s: %g ", names[i], affine[i]);
3136}
3137SkDebugf("\n");
3138matrix.reset();
3139matrix.setAffine(affine);
3140matrix.dump();
3141#StdOut
3142ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
3143[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000]
3144##
3145##
3146
3147#SeeAlso asAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04003148
3149##
3150
3151# ------------------------------------------------------------------------------
3152
3153#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
3154
Cary Clark154beea2017-10-26 07:58:48 -04003155Maps src Point array of length count to dst Point array of equal or greater
3156length. Points are mapped by multiplying each Point by Matrix. Given:
3157
3158#Code
3159#Literal
3160 | A B C | | x |
3161Matrix = | D E F |, pt = | y |
3162 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003163##
3164
Cary Clark154beea2017-10-26 07:58:48 -04003165where
3166
3167#Code
3168#Literal
3169for (i = 0; i < count; ++i) {
3170 x = src[i].fX
3171 y = src[i].fY
3172}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003173##
Cary Clark154beea2017-10-26 07:58:48 -04003174
3175each dst Point is computed as:
3176
3177#Code
3178#Literal
3179 |A B C| |x| Ax+By+C Dx+Ey+F
3180Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3181 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003182##
Cary Clark154beea2017-10-26 07:58:48 -04003183
3184src and dst may point to the same storage.
3185
3186#Param dst storage for mapped Points ##
3187#Param src Points to transform ##
3188#Param count number of Points to transform ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003189
3190#Example
Cary Clark154beea2017-10-26 07:58:48 -04003191 SkMatrix matrix;
3192 matrix.reset();
3193 const int count = 4;
3194 SkPoint src[count];
3195 matrix.mapRectToQuad(src, {40, 70, 180, 220} );
3196 SkPaint paint;
3197 paint.setARGB(77, 23, 99, 154);
3198 for (int i = 0; i < 5; ++i) {
3199 SkPoint dst[count];
3200 matrix.mapPoints(dst, src, count);
3201 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, dst, paint);
3202 matrix.preRotate(35, 128, 128);
3203 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003204##
3205
Cary Clark154beea2017-10-26 07:58:48 -04003206#SeeAlso mapPointsWithStride mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003207
3208##
3209
3210# ------------------------------------------------------------------------------
3211
3212#Method void mapPoints(SkPoint pts[], int count) const
3213
Cary Clark154beea2017-10-26 07:58:48 -04003214Maps pts Point array of length count in place. Points are mapped by multiplying
3215each Point by Matrix. Given:
3216
3217#Code
3218#Literal
3219 | A B C | | x |
3220Matrix = | D E F |, pt = | y |
3221 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003222##
3223
Cary Clark154beea2017-10-26 07:58:48 -04003224where
3225
3226#Code
3227#Literal
3228for (i = 0; i < count; ++i) {
3229 x = pts[i].fX
3230 y = pts[i].fY
3231}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003232##
Cary Clark154beea2017-10-26 07:58:48 -04003233
3234each resulting pts Point is computed as:
3235
3236#Code
3237#Literal
3238 |A B C| |x| Ax+By+C Dx+Ey+F
3239Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3240 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003241##
3242
Cary Clark154beea2017-10-26 07:58:48 -04003243#Param pts storage for mapped Points ##
3244#Param count number of Points to transform ##
3245
Cary Clarkbc5697d2017-10-04 14:31:33 -04003246#Example
Cary Clark154beea2017-10-26 07:58:48 -04003247 SkMatrix matrix;
3248 matrix.setRotate(35, 128, 128);
3249 const int count = 4;
3250 SkPoint pts[count];
3251 matrix.mapRectToQuad(pts, {40, 70, 180, 220} );
3252 SkPaint paint;
3253 paint.setARGB(77, 23, 99, 154);
3254 for (int i = 0; i < 5; ++i) {
3255 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, pts, paint);
3256 matrix.mapPoints(pts, count);
3257 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003258##
3259
Cary Clark154beea2017-10-26 07:58:48 -04003260#SeeAlso mapPointsWithStride mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003261
3262##
3263
3264# ------------------------------------------------------------------------------
3265
3266#Method void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const
3267
Cary Clark154beea2017-10-26 07:58:48 -04003268Maps count pts, skipping stride bytes to advance from one Point to the next.
3269Points are mapped by multiplying each Point by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003270
Cary Clark154beea2017-10-26 07:58:48 -04003271#Code
3272#Literal
3273 | A B C | | x |
3274Matrix = | D E F |, pt = | y |
3275 | G H I | | 1 |
3276##
3277
3278each resulting pts Point is computed as:
3279
3280#Code
3281#Literal
3282 |A B C| |x| Ax+By+C Dx+Ey+F
3283Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3284 |G H I| |1| Gx+Hy+I Gx+Hy+I
3285##
3286
3287#Param pts storage for mapped Points ##
3288#Param stride size of record starting with Point, in bytes ##
3289#Param count number of Points to transform ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003290
3291#Example
Cary Clark154beea2017-10-26 07:58:48 -04003292 SkMatrix matrix;
3293 matrix.reset();
3294 struct PointZ {
3295 SkPoint fPt;
3296 SkPoint fStationary;
3297 } pts[] = {{{40, 70}, {40, 70}}, {{180, 70}, {180, 70}}, {{180, 220}, {180, 220}},
3298 {{40, 220}, {40, 220}}};
3299 constexpr int count = SK_ARRAY_COUNT(pts);
3300 SkPaint paint;
3301 paint.setARGB(77, 23, 99, 154);
3302 for (int i = 0; i < 5; ++i) {
3303 matrix.preRotate(10, 128, 128);
3304 matrix.mapPointsWithStride(&pts[0].fPt, sizeof(PointZ), count);
3305 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count * 2, &pts[0].fPt, paint);
3306 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003307##
3308
Cary Clark154beea2017-10-26 07:58:48 -04003309#SeeAlso mapPoints mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003310
3311##
3312
3313# ------------------------------------------------------------------------------
3314
3315#Method void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const
3316
Cary Clark154beea2017-10-26 07:58:48 -04003317Maps src Point array of length count to dst Point array, skipping stride bytes
3318to advance from one Point to the next.
3319Points are mapped by multiplying each Point by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003320
Cary Clark154beea2017-10-26 07:58:48 -04003321#Code
3322#Literal
3323 | A B C | | x |
3324Matrix = | D E F |, src = | y |
3325 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003326##
3327
Cary Clark154beea2017-10-26 07:58:48 -04003328each resulting dst Point is computed as:
3329
3330#Code
3331#Literal
3332 |A B C| |x| Ax+By+C Dx+Ey+F
3333Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3334 |G H I| |1| Gx+Hy+I Gx+Hy+I
3335##
3336
3337#Param dst storage for mapped Points ##
3338#Param src Points to transform ##
3339#Param stride size of record starting with Point, in bytes ##
3340#Param count number of Points to transform ##
3341
3342#Example
3343 struct PointZ {
3344 SkPoint fPt;
3345 const SkPoint fStationary;
3346 };
3347 const PointZ src[] = {{{40, 70}, {40, 70}}, {{180, 70}, {180, 70}}, {{180, 220}, {180, 220}},
3348 {{40, 220}, {40, 220}}};
3349 PointZ dst[] = {{{0, 0}, {60, 80}}, {{0, 0}, {150, 40}}, {{0, 0}, {100, 240}},
3350 {{0, 0}, {10, 250}}};
3351 constexpr int count = SK_ARRAY_COUNT(src);
3352 SkPaint paint;
3353 paint.setARGB(77, 23, 99, 154);
3354 for (int i = 0; i < 5; ++i) {
3355 SkMatrix matrix;
3356 matrix.setRotate(10 * i, 128, 128);
3357 matrix.mapPointsWithStride(&dst[0].fPt, &src[0].fPt, sizeof(PointZ), count);
3358 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count * 2, &dst[0].fPt, paint);
3359 }
3360##
3361
3362#SeeAlso mapPoints mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003363
3364##
3365
3366# ------------------------------------------------------------------------------
3367
Cary Clark154beea2017-10-26 07:58:48 -04003368#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
Cary Clarkbc5697d2017-10-04 14:31:33 -04003369
Cary Clark154beea2017-10-26 07:58:48 -04003370Maps src Point3 array of length count to dst Point3 array, which must of length count or
3371greater. Point3 array is mapped by multiplying each Point3 by Matrix. Given:
3372
3373#Code
3374#Literal
3375 | A B C | | x |
3376Matrix = | D E F |, src = | y |
3377 | G H I | | z |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003378##
3379
Cary Clark154beea2017-10-26 07:58:48 -04003380each resulting dst Point is computed as:
3381
3382#Code
3383#Literal
3384 |A B C| |x|
3385Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz|
3386 |G H I| |z|
Cary Clarkbc5697d2017-10-04 14:31:33 -04003387##
Cary Clark154beea2017-10-26 07:58:48 -04003388
3389#Param dst storage for mapped Point3 array ##
3390#Param src Point3 array to transform ##
3391#Param count items in Point3 array to transform ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003392
3393#Example
Cary Clark154beea2017-10-26 07:58:48 -04003394 SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3},
3395 {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}};
3396 int lines[] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
3397 constexpr int count = SK_ARRAY_COUNT(src);
3398 auto debugster = [=](SkPoint3 src[]) -> void {
3399 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) {
3400 const SkPoint3& s = src[lines[i]];
3401 const SkPoint3& e = src[lines[i + 1]];
3402 SkPaint paint;
3403 paint.setARGB(77, 23, 99, 154);
3404 canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint);
3405 }
3406 };
3407 canvas->save();
3408 canvas->translate(5, 5);
3409 canvas->scale(15, 15);
3410 debugster(src);
3411 canvas->restore();
3412 canvas->translate(128, 128);
3413 SkMatrix matrix;
3414 matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1);
3415 matrix.mapHomogeneousPoints(&src[0].fX, &src[0].fX, count);
3416 debugster(src);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003417##
3418
Cary Clark154beea2017-10-26 07:58:48 -04003419#SeeAlso mapPoints mapXY mapPointsWithStride mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003420
3421##
3422
3423# ------------------------------------------------------------------------------
3424
3425#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const
3426
Cary Clark154beea2017-10-26 07:58:48 -04003427Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003428
Cary Clark154beea2017-10-26 07:58:48 -04003429#Code
3430#Literal
3431 | A B C | | x |
3432Matrix = | D E F |, pt = | y |
3433 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003434##
3435
Cary Clark154beea2017-10-26 07:58:48 -04003436result is computed as:
3437
3438#Code
3439#Literal
3440 |A B C| |x| Ax+By+C Dx+Ey+F
3441Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3442 |G H I| |1| Gx+Hy+I Gx+Hy+I
3443##
3444
3445#Param x x-coordinate of Point to map ##
3446#Param y y-coordinate of Point to map ##
3447#Param result storage for mapped Point ##
3448
3449#Example
3450 SkPaint paint;
3451 paint.setAntiAlias(true);
3452 SkMatrix matrix;
3453 matrix.setRotate(60, 128, 128);
3454 SkPoint lines[] = {{50, 50}, {150, 50}, {150, 150}};
3455 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); ++i) {
3456 SkPoint pt;
3457 matrix.mapXY(lines[i].fX, lines[i].fY, &pt);
3458 canvas->drawCircle(pt.fX, pt.fY, 3, paint);
3459 }
3460 canvas->concat(matrix);
3461 canvas->drawPoints(SkCanvas::kPolygon_PointMode, SK_ARRAY_COUNT(lines), lines, paint);
3462##
3463
3464#SeeAlso mapPoints mapPointsWithStride mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003465
3466##
3467
3468# ------------------------------------------------------------------------------
3469
3470#Method SkPoint mapXY(SkScalar x, SkScalar y) const
3471
Cary Clark154beea2017-10-26 07:58:48 -04003472Returns Point (x, y) multiplied by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003473
Cary Clark154beea2017-10-26 07:58:48 -04003474#Code
3475#Literal
3476 | A B C | | x |
3477Matrix = | D E F |, pt = | y |
3478 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003479##
3480
Cary Clark154beea2017-10-26 07:58:48 -04003481result is computed as:
3482
3483#Code
3484#Literal
3485 |A B C| |x| Ax+By+C Dx+Ey+F
3486Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3487 |G H I| |1| Gx+Hy+I Gx+Hy+I
3488##
3489
3490#Param x x-coordinate of Point to map ##
3491#Param y y-coordinate of Point to map ##
3492
3493#Return mapped Point ##
3494
3495#Example
3496#Image 4
3497SkMatrix matrix;
3498SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {30, 206}};
3499SkRect::Make(source.bounds()).toQuad(bitmapBounds);
3500matrix.setPolyToPoly(bitmapBounds, perspect, 4);
3501SkPaint paint;
3502paint.setAntiAlias(true);
3503paint.setStrokeWidth(3);
3504for (int x : { 0, source.width() } ) {
3505 for (int y : { 0, source.height() } ) {
3506 canvas->drawPoint(matrix.mapXY(x, y), paint);
3507 }
3508}
3509canvas->concat(matrix);
3510canvas->drawBitmap(source, 0, 0);
3511##
3512
3513#SeeAlso mapPoints mapPointsWithStride mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003514
3515##
3516
3517# ------------------------------------------------------------------------------
3518
3519#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const
3520
Cary Clark154beea2017-10-26 07:58:48 -04003521Maps src Vector array of length count to Vector Point array of equal or greater
3522length. Vectors are mapped by multiplying each Vector by Matrix, treating
3523Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003524
Cary Clark154beea2017-10-26 07:58:48 -04003525#Code
3526#Literal
3527 | A B 0 | | x |
3528Matrix = | D E 0 |, src = | y |
3529 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003530##
Cary Clark154beea2017-10-26 07:58:48 -04003531
3532where
3533
3534#Code
3535#Literal
3536for (i = 0; i < count; ++i) {
3537 x = src[i].fX
3538 y = src[i].fY
3539}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003540##
Cary Clark154beea2017-10-26 07:58:48 -04003541
3542each dst Vector is computed as:
3543
3544#Code
3545#Literal
3546 |A B 0| |x| Ax+By Dx+Ey
3547Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
3548 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003549##
3550
Cary Clark154beea2017-10-26 07:58:48 -04003551src and dst may point to the same storage.
3552
3553#Param dst storage for mapped Vectors ##
3554#Param src Vectors to transform ##
3555#Param count number of Vectors to transform ##
3556
Cary Clarkbc5697d2017-10-04 14:31:33 -04003557#Example
Cary Clark154beea2017-10-26 07:58:48 -04003558 SkPaint paint;
3559 paint.setAntiAlias(true);
3560 paint.setStyle(SkPaint::kStroke_Style);
3561 SkMatrix matrix;
3562 matrix.reset();
3563 const SkVector radii[] = {{8, 4}, {9, 1}, {6, 2}, {7, 3}};
3564 for (int i = 0; i < 4; ++i) {
3565 SkVector rScaled[4];
3566 matrix.preScale(1.5f, 2.f);
3567 matrix.mapVectors(rScaled, radii, SK_ARRAY_COUNT(radii));
3568 SkRRect rrect;
3569 rrect.setRectRadii({20, 20, 180, 70}, rScaled);
3570 canvas->drawRRect(rrect, paint);
3571 canvas->translate(0, 60);
3572 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003573##
3574
Cary Clark154beea2017-10-26 07:58:48 -04003575#SeeAlso mapVector mapPoints mapPointsWithStride mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003576
3577##
3578
3579# ------------------------------------------------------------------------------
3580
3581#Method void mapVectors(SkVector vecs[], int count) const
3582
Cary Clark154beea2017-10-26 07:58:48 -04003583Maps vecs Vector array of length count in place, multiplying each Vector by
3584Matrix, treating Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003585
Cary Clark154beea2017-10-26 07:58:48 -04003586#Code
3587#Literal
3588 | A B 0 | | x |
3589Matrix = | D E 0 |, vec = | y |
3590 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003591##
Cary Clark154beea2017-10-26 07:58:48 -04003592
3593where
3594
3595#Code
3596#Literal
3597for (i = 0; i < count; ++i) {
3598 x = vecs[i].fX
3599 y = vecs[i].fY
3600}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003601##
3602
Cary Clark154beea2017-10-26 07:58:48 -04003603each result Vector is computed as:
3604
3605#Code
3606#Literal
3607 |A B 0| |x| Ax+By Dx+Ey
3608Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
3609 |G H I| |1| Gx+Hy+I Gx+Hy+I
3610##
3611
3612#Param vecs Vectors to transform, and storage for mapped Vectors ##
3613#Param count number of Vectors to transform ##
3614
Cary Clarkbc5697d2017-10-04 14:31:33 -04003615#Example
Cary Clark154beea2017-10-26 07:58:48 -04003616 SkPaint paint;
3617 paint.setAntiAlias(true);
3618 paint.setStyle(SkPaint::kStroke_Style);
3619 SkMatrix matrix;
3620 matrix.setScale(2, 3);
3621 SkVector radii[] = {{7, 7}, {3, 3}, {2, 2}, {4, 0}};
3622 for (int i = 0; i < 4; ++i) {
3623 SkRRect rrect;
3624 rrect.setRectRadii({20, 20, 180, 70}, radii);
3625 canvas->drawRRect(rrect, paint);
3626 canvas->translate(0, 60);
3627 matrix.mapVectors(radii, SK_ARRAY_COUNT(radii));
3628 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003629##
3630
Cary Clark154beea2017-10-26 07:58:48 -04003631#SeeAlso mapVector mapPoints mapPointsWithStride mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003632
3633##
3634
3635# ------------------------------------------------------------------------------
3636
3637#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const
3638
Cary Clark154beea2017-10-26 07:58:48 -04003639Maps Vector (x, y) to result. Vector is mapped by multiplying by Matrix,
3640treating Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003641
Cary Clark154beea2017-10-26 07:58:48 -04003642#Code
3643#Literal
3644 | A B 0 | | dx |
3645Matrix = | D E 0 |, vec = | dy |
3646 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003647##
3648
Cary Clark154beea2017-10-26 07:58:48 -04003649each result Vector is computed as:
3650
3651#Code
3652#Literal
3653#Outdent
3654 |A B 0| |dx| A*dx+B*dy D*dx+E*dy
3655Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
3656 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
3657##
3658
3659#Param dx x-coordinate of Vector to map ##
3660#Param dy y-coordinate of Vector to map ##
3661#Param result storage for mapped Vector ##
3662
3663#Example
3664 SkPaint paint;
3665 paint.setColor(SK_ColorGREEN);
3666 paint.setAntiAlias(true);
3667 paint.setTextSize(48);
3668 SkMatrix matrix;
3669 matrix.setRotate(90);
3670 SkVector offset = { 7, 7 };
3671 for (int i = 0; i < 4; ++i) {
3672 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
3673 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
3674 matrix.mapVector(offset.fX, offset.fY, &offset);
3675 canvas->translate(0, 60);
3676 canvas->drawString("Text", 50, 0, paint);
3677 }
3678##
3679
3680#SeeAlso mapVectors mapPoints mapPointsWithStride mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003681
3682##
3683
3684# ------------------------------------------------------------------------------
3685
3686#Method SkVector mapVector(SkScalar dx, SkScalar dy) const
3687
Cary Clark154beea2017-10-26 07:58:48 -04003688Returns Vector (x, y) multiplied by Matrix, treating Matrix translation as zero.
3689Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003690
Cary Clark154beea2017-10-26 07:58:48 -04003691#Code
3692#Literal
3693 | A B 0 | | dx |
3694Matrix = | D E 0 |, vec = | dy |
3695 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003696##
3697
Cary Clark154beea2017-10-26 07:58:48 -04003698each result Vector is computed as:
3699
3700#Code
3701#Literal
3702#Outdent
3703 |A B 0| |dx| A*dx+B*dy D*dx+E*dy
3704Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
3705 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
3706##
3707
3708#Param dx x-coordinate of Vector to map ##
3709#Param dy y-coordinate of Vector to map ##
3710
3711#Return mapped Vector ##
3712
3713#Example
3714 SkPaint paint;
3715 paint.setColor(SK_ColorGREEN);
3716 paint.setAntiAlias(true);
3717 paint.setTextSize(48);
3718 SkMatrix matrix;
3719 matrix.setRotate(90);
3720 SkVector offset = { 7, 7 };
3721 for (int i = 0; i < 4; ++i) {
3722 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
3723 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
3724 offset = matrix.mapVector(offset.fX, offset.fY);
3725 canvas->translate(0, 60);
3726 canvas->drawString("Text", 50, 0, paint);
3727 }
3728##
3729
3730#SeeAlso mapVectors mapPoints mapPointsWithStride mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003731
3732##
3733
3734# ------------------------------------------------------------------------------
3735
3736#Method bool mapRect(SkRect* dst, const SkRect& src) const
3737
Cary Clark154beea2017-10-26 07:58:48 -04003738Sets dst to bounds of src corners mapped by Matrix.
3739Returns true if mapped corners are dst corners.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003740
Cary Clark154beea2017-10-26 07:58:48 -04003741Returned value is the same as calling rectStaysRect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003742
Cary Clark154beea2017-10-26 07:58:48 -04003743#Param dst storage for bounds of mapped Points ##
3744#Param src Rect to map ##
3745
3746#Return true if dst is equivalent to mapped src ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003747
3748#Example
Cary Clark154beea2017-10-26 07:58:48 -04003749 SkPaint paint;
3750 paint.setAntiAlias(true);
3751 SkMatrix matrix;
3752 matrix.setRotate(45, 128, 128);
3753 SkRect rotatedBounds, bounds = {40, 50, 190, 200};
3754 matrix.mapRect(&rotatedBounds, bounds );
3755 paint.setColor(SK_ColorGRAY);
3756 canvas->drawRect(rotatedBounds, paint);
3757 canvas->concat(matrix);
3758 paint.setColor(SK_ColorRED);
3759 canvas->drawRect(bounds, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003760##
3761
Cary Clark154beea2017-10-26 07:58:48 -04003762#SeeAlso mapPoints rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003763
3764##
3765
3766# ------------------------------------------------------------------------------
3767
3768#Method bool mapRect(SkRect* rect) const
3769
Cary Clark154beea2017-10-26 07:58:48 -04003770Sets rect to bounds of rect corners mapped by Matrix.
3771Returns true if mapped corners are computed rect corners.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003772
Cary Clark154beea2017-10-26 07:58:48 -04003773Returned value is the same as calling rectStaysRect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003774
Cary Clark154beea2017-10-26 07:58:48 -04003775#Param rect rectangle to map, and storage for bounds of mapped corners ##
3776
3777#Return true if result is equivalent to mapped src ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003778
3779#Example
Cary Clark154beea2017-10-26 07:58:48 -04003780 SkPaint paint;
3781 paint.setAntiAlias(true);
3782 SkMatrix matrix;
3783 matrix.setRotate(45, 128, 128);
3784 SkRect bounds = {40, 50, 190, 200};
3785 matrix.mapRect(&bounds);
3786 paint.setColor(SK_ColorGRAY);
3787 canvas->drawRect(bounds, paint);
3788 canvas->concat(matrix);
3789 paint.setColor(SK_ColorRED);
3790 canvas->drawRect({40, 50, 190, 200}, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003791##
3792
Cary Clark154beea2017-10-26 07:58:48 -04003793#SeeAlso mapRectScaleTranslate mapPoints rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003794
3795##
3796
3797# ------------------------------------------------------------------------------
3798
3799#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const
3800
Cary Clark154beea2017-10-26 07:58:48 -04003801Maps four corners of rect to dst. Points are mapped by multiplying each
3802rect corner by Matrix. rect corner is processed in this order:
3803(rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom),
3804(rect.fLeft, rect.fBottom).
Cary Clarkbc5697d2017-10-04 14:31:33 -04003805
Cary Clark154beea2017-10-26 07:58:48 -04003806rect may be empty: rect.fLeft may be greater than or equal to rect.fRight;
3807rect.fTop may be greater than or equal to rect.fBottom.
3808
3809Given:
3810
3811#Code
3812#Literal
3813 | A B C | | x |
3814Matrix = | D E F |, pt = | y |
3815 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003816##
Cary Clark154beea2017-10-26 07:58:48 -04003817
3818where pt is initialized from each of (rect.fLeft, rect.fTop),
3819(rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom),
3820each dst Point is computed as:
3821
3822#Code
3823#Literal
3824 |A B C| |x| Ax+By+C Dx+Ey+F
3825Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3826 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003827##
3828
Cary Clark154beea2017-10-26 07:58:48 -04003829#Param dst storage for mapped corner Points ##
3830#Param rect Rect to map ##
3831
Cary Clarkbc5697d2017-10-04 14:31:33 -04003832#Example
Cary Clark2ade9972017-11-02 17:49:34 -04003833#Height 192
Cary Clark154beea2017-10-26 07:58:48 -04003834 SkPaint paint;
3835 paint.setAntiAlias(true);
3836 SkMatrix matrix;
3837 matrix.setRotate(60, 128, 128);
3838 SkRect rect = {50, 50, 150, 150};
3839 SkPoint pts[4];
3840 matrix.mapRectToQuad(pts, rect);
3841 for (int i = 0; i < 4; ++i) {
3842 canvas->drawCircle(pts[i].fX, pts[i].fY, 3, paint);
3843 }
3844 canvas->concat(matrix);
3845 paint.setStyle(SkPaint::kStroke_Style);
3846 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003847##
3848
Cary Clark154beea2017-10-26 07:58:48 -04003849#SeeAlso mapRect mapRectScaleTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04003850
3851##
3852
3853# ------------------------------------------------------------------------------
3854
3855#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const
3856
Cary Clark154beea2017-10-26 07:58:48 -04003857Sets dst to bounds of src corners mapped by Matrix. If matrix contains
3858elements other than scale or translate: asserts if SK_DEBUG is defined;
3859otherwise, results are undefined.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003860
Cary Clark154beea2017-10-26 07:58:48 -04003861#Param dst storage for bounds of mapped Points ##
3862#Param src Rect to map ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003863
3864#Example
Cary Clark154beea2017-10-26 07:58:48 -04003865 SkPaint paint;
3866 SkMatrix matrix;
3867 SkRect rect = {100, 50, 150, 180};
3868 matrix.setScale(2, .5f, rect.centerX(), rect.centerY());
3869 SkRect rotated;
3870 matrix.mapRectScaleTranslate(&rotated, rect);
3871 paint.setStyle(SkPaint::kStroke_Style);
3872 canvas->drawRect(rect, paint);
3873 paint.setColor(SK_ColorRED);
3874 canvas->drawRect(rotated, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003875##
3876
Cary Clark154beea2017-10-26 07:58:48 -04003877#SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003878
3879##
3880
3881# ------------------------------------------------------------------------------
3882
3883#Method SkScalar mapRadius(SkScalar radius) const
3884
Cary Clark154beea2017-10-26 07:58:48 -04003885Returns geometric mean radius of ellipse formed by constructing Circle of
3886size radius, and mapping constructed Circle with Matrix. The result squared is
3887equal to the major axis length times the minor axis length.
3888Result is not meaningful if Matrix contains perspective elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003889
Cary Clark154beea2017-10-26 07:58:48 -04003890#Param radius Circle size to map ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003891
Cary Clark154beea2017-10-26 07:58:48 -04003892#Return average mapped radius ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003893
3894#Example
Cary Clark154beea2017-10-26 07:58:48 -04003895#Description
3896The area enclosed by a square with sides equal to mappedRadius is the same as
3897the area enclosed by the ellipse major and minor axes.
3898##
3899 SkPaint paint;
3900 paint.setAntiAlias(true);
3901 SkMatrix matrix;
3902 const SkPoint center = {108, 93};
3903 matrix.setScale(2, .5f, center.fX, center.fY);
3904 matrix.postRotate(45, center.fX, center.fY);
3905 const SkScalar circleRadius = 50;
3906 SkScalar mappedRadius = matrix.mapRadius(circleRadius);
3907 SkVector minorAxis, majorAxis;
3908 matrix.mapVector(0, circleRadius, &minorAxis);
3909 matrix.mapVector(circleRadius, 0, &majorAxis);
3910 SkString mappedArea;
3911 mappedArea.printf("area = %g", mappedRadius * mappedRadius);
3912 canvas->drawString(mappedArea, 145, 250, paint);
3913 canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint);
3914 paint.setColor(SK_ColorRED);
3915 SkString axArea;
3916 axArea.printf("area = %g", majorAxis.length() * minorAxis.length());
3917 paint.setStyle(SkPaint::kFill_Style);
3918 canvas->drawString(axArea, 15, 250, paint);
3919 paint.setStyle(SkPaint::kStroke_Style);
3920 canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint);
3921 paint.setColor(SK_ColorBLACK);
3922 canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint);
3923 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint);
3924 canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint);
3925 canvas->concat(matrix);
3926 canvas->drawCircle(center.fX, center.fY, circleRadius, paint);
3927 paint.setColor(SK_ColorRED);
3928 canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint);
3929 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003930##
3931
Cary Clark154beea2017-10-26 07:58:48 -04003932#SeeAlso mapVector
Cary Clarkbc5697d2017-10-04 14:31:33 -04003933
3934##
3935
3936# ------------------------------------------------------------------------------
3937
3938#Method bool isFixedStepInX() const
3939
Cary Clark154beea2017-10-26 07:58:48 -04003940Returns true if a unit step in x at some y mapped through Matrix can be
3941represented by a constant Vector. Returns true if getType returns kIdentity_Mask,
3942or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003943
Cary Clark154beea2017-10-26 07:58:48 -04003944May return true if getType returns kPerspective_Mask, but only when Matrix
3945does not include rotation or skewing along the y-axis.
3946
3947#Return true if Matrix does not have complex perspective ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003948
3949#Example
Cary Clark154beea2017-10-26 07:58:48 -04003950 SkMatrix matrix;
3951 for (SkScalar px : { 0.0f, 0.1f } ) {
3952 for (SkScalar py : { 0.0f, 0.1f } ) {
3953 for (SkScalar sy : { 1, 2 } ) {
3954 matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1);
3955 matrix.dump();
3956 SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false");
3957 }
3958 }
3959 }
3960#StdOut
3961[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
3962isFixedStepInX: true
3963[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000]
3964isFixedStepInX: true
3965[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000]
3966isFixedStepInX: true
3967[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000]
3968isFixedStepInX: true
3969[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000]
3970isFixedStepInX: false
3971[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000]
3972isFixedStepInX: false
3973[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000]
3974isFixedStepInX: false
3975[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000]
3976isFixedStepInX: false
3977##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003978##
3979
Cary Clark154beea2017-10-26 07:58:48 -04003980#SeeAlso fixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04003981
3982##
3983
3984# ------------------------------------------------------------------------------
3985
3986#Method SkVector fixedStepInX(SkScalar y) const
3987
Cary Clark154beea2017-10-26 07:58:48 -04003988Returns Vector representing a unit step in x at y mapped through Matrix.
3989If isFixedStepInX is false, returned value is undefined.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003990
Cary Clark154beea2017-10-26 07:58:48 -04003991#Param y position of line parallel to x-axis ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003992
Cary Clark154beea2017-10-26 07:58:48 -04003993#Return Vector advance of mapped unit step in x ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003994
3995#Example
Cary Clark154beea2017-10-26 07:58:48 -04003996#Image 3
3997 SkMatrix matrix;
3998 const SkPoint center = { 128, 128 };
3999 matrix.setScale(20, 25, center.fX, center.fY);
4000 matrix.postRotate(75, center.fX, center.fY);
4001 {
4002 SkAutoCanvasRestore acr(canvas, true);
4003 canvas->concat(matrix);
4004 canvas->drawBitmap(source, 0, 0);
4005 }
4006 if (matrix.isFixedStepInX()) {
4007 SkPaint paint;
4008 paint.setAntiAlias(true);
4009 SkVector step = matrix.fixedStepInX(128);
4010 SkVector end = center + step;
4011 canvas->drawLine(center, end, paint);
4012 SkVector arrow = { step.fX + step.fY, step.fY - step.fX};
4013 arrow = arrow * .25f;
4014 canvas->drawLine(end, end - arrow, paint);
4015 canvas->drawLine(end, {end.fX + arrow.fY, end.fY - arrow.fX}, paint);
4016 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04004017##
4018
Cary Clark154beea2017-10-26 07:58:48 -04004019#SeeAlso isFixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04004020
4021##
4022
4023# ------------------------------------------------------------------------------
4024
4025#Method bool cheapEqualTo(const SkMatrix& m) const
4026
4027Returns true if Matrix equals m, using an efficient comparison.
4028
Cary Clark154beea2017-10-26 07:58:48 -04004029Returns false when the sign of zero values is the different; when one
Cary Clarkbc5697d2017-10-04 14:31:33 -04004030matrix has positive zero value and the other has negative zero value.
4031
Cary Clark154beea2017-10-26 07:58:48 -04004032Returns true even when both Matrices contain NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004033
Cary Clark154beea2017-10-26 07:58:48 -04004034NaN never equals any value, including itself. To improve performance, NaN values
4035are treated as bit patterns that are equal if their bit patterns are equal.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004036
Cary Clark154beea2017-10-26 07:58:48 -04004037#Param m Matrix to compare ##
4038
4039#Return true if m and Matrix are represented by identical bit patterns ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004040
4041#Example
Cary Clark154beea2017-10-26 07:58:48 -04004042 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
4043 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
4044 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
Cary Clarkbc5697d2017-10-04 14:31:33 -04004045 };
Cary Clark154beea2017-10-26 07:58:48 -04004046 SkMatrix a, b;
4047 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
4048 b.setIdentity();
4049 debugster("identity", a, b);
4050 a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1);
4051 debugster("neg zero", a, b);
4052 a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
4053 debugster(" one NaN", a, b);
4054 b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
4055 debugster("both NaN", a, b);
4056#StdOut
4057identity: a == b a.cheapEqualTo(b): true
4058neg zero: a == b a.cheapEqualTo(b): false
4059 one NaN: a != b a.cheapEqualTo(b): false
4060both NaN: a != b a.cheapEqualTo(b): true
4061##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004062##
4063
Cary Clark154beea2017-10-26 07:58:48 -04004064#SeeAlso operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004065
4066##
4067
4068# ------------------------------------------------------------------------------
4069
Cary Clark154beea2017-10-26 07:58:48 -04004070#Method bool operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004071
Cary Clark154beea2017-10-26 07:58:48 -04004072Compares a and b; returns true if a and b are numerically equal. Returns true
4073even if sign of zero values are different. Returns false if either Matrix
4074contains NaN, even if the other Matrix also contains NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004075
Cary Clark154beea2017-10-26 07:58:48 -04004076#Param a Matrix to compare ##
4077#Param b Matrix to compare ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004078
Cary Clark154beea2017-10-26 07:58:48 -04004079#Return true if m and Matrix are numerically equal ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004080
4081#Example
Cary Clark154beea2017-10-26 07:58:48 -04004082 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
4083 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
4084 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
4085 };
4086 SkMatrix a, b;
4087 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
4088 b.setScale(2, 4);
4089 b.postScale(0.5f, 0.25f);
4090 debugster("identity", a, b);
4091#StdOut
4092identity: a == b a.cheapEqualTo(b): true
4093##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004094##
4095
Cary Clark154beea2017-10-26 07:58:48 -04004096#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004097
4098##
4099
4100# ------------------------------------------------------------------------------
4101
Cary Clark154beea2017-10-26 07:58:48 -04004102#Method bool operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004103
Cary Clark154beea2017-10-26 07:58:48 -04004104Compares a and b; returns true if a and b are not numerically equal. Returns false
4105even if sign of zero values are different. Returns true if either Matrix
4106contains NaN, even if the other Matrix also contains NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004107
Cary Clark154beea2017-10-26 07:58:48 -04004108#Param a Matrix to compare ##
4109#Param b Matrix to compare ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004110
Cary Clark154beea2017-10-26 07:58:48 -04004111#Return true if m and Matrix are numerically not equal ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004112
4113#Example
Cary Clark154beea2017-10-26 07:58:48 -04004114 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
4115 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
4116 a != b ? '!' : '=', a.cheapEqualTo(b) ? "true" : "false");
4117 };
4118 SkMatrix a, b;
4119 a.setAll(1, 0, 0, 0, 1, 0, 1, 0, 1);
4120 a.invert(&b);
4121 debugster("identity", a, b);
Cary Clarkbc5697d2017-10-04 14:31:33 -04004122##
4123
Cary Clark154beea2017-10-26 07:58:48 -04004124#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004125
4126##
4127
4128# ------------------------------------------------------------------------------
4129
4130#Method void dump() const
4131
Cary Clark154beea2017-10-26 07:58:48 -04004132Writes text representation of Matrix to standard output. Floating point values
4133are written with limited precision; it may not be possible to reconstruct
4134original Matrix from output.
4135
Cary Clarkbc5697d2017-10-04 14:31:33 -04004136#Example
Cary Clark154beea2017-10-26 07:58:48 -04004137 SkMatrix matrix;
4138 matrix.setRotate(45);
4139 matrix.dump();
4140 SkMatrix nearlyEqual;
4141 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
4142 nearlyEqual.dump();
4143 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
4144#StdOut
4145[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4146[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4147matrix != nearlyEqual
4148##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004149##
4150
Cary Clark154beea2017-10-26 07:58:48 -04004151#SeeAlso toString
Cary Clarkbc5697d2017-10-04 14:31:33 -04004152
4153##
4154
4155# ------------------------------------------------------------------------------
4156
4157#Method void toString(SkString* str) const
4158
Cary Clark154beea2017-10-26 07:58:48 -04004159Creates string representation of Matrix. Floating point values
4160are written with limited precision; it may not be possible to reconstruct
4161original Matrix from output.
4162
4163#Param str storage for string representation of Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004164
4165#Example
Cary Clark154beea2017-10-26 07:58:48 -04004166 SkMatrix matrix;
4167 matrix.setRotate(45);
4168 SkString mStr, neStr;
4169 matrix.toString(&mStr);
4170 SkMatrix nearlyEqual;
4171 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
4172 nearlyEqual.toString(&neStr);
4173 SkDebugf("mStr %s\n", mStr.c_str());
4174 SkDebugf("neStr %s\n", neStr.c_str());
4175 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
4176#StdOut
4177mStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4178neStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4179matrix != nearlyEqual
4180##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004181##
4182
Cary Clark154beea2017-10-26 07:58:48 -04004183#SeeAlso dump
Cary Clarkbc5697d2017-10-04 14:31:33 -04004184
4185##
4186
4187# ------------------------------------------------------------------------------
4188
4189#Method SkScalar getMinScale() const
4190
Cary Clark154beea2017-10-26 07:58:48 -04004191Returns the minimum scaling factor of Matrix by decomposing the scaling and
4192skewing elements.
4193Returns -1 if scale factor overflows or Matrix contains perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004194
4195#Return minimum scale factor
4196##
4197
4198#Example
Cary Clark154beea2017-10-26 07:58:48 -04004199 SkMatrix matrix;
4200 matrix.setScale(42, 24);
4201 SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale());
4202#StdOut
4203matrix.getMinScale() 24
4204##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004205##
4206
Cary Clark154beea2017-10-26 07:58:48 -04004207#SeeAlso getMaxScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04004208
4209##
4210
4211# ------------------------------------------------------------------------------
4212
4213#Method SkScalar getMaxScale() const
4214
Cary Clark154beea2017-10-26 07:58:48 -04004215Returns the maximum scaling factor of Matrix by decomposing the scaling and
4216skewing elements.
4217Returns -1 if scale factor overflows or Matrix contains perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004218
4219#Return maximum scale factor
4220##
4221
4222#Example
Cary Clark154beea2017-10-26 07:58:48 -04004223 SkMatrix matrix;
4224 matrix.setScale(42, 24);
4225 SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale());
4226#StdOut
4227matrix.getMaxScale() 42
4228##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004229##
4230
Cary Clark154beea2017-10-26 07:58:48 -04004231#SeeAlso getMinScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04004232
4233##
4234
4235# ------------------------------------------------------------------------------
4236
4237#Method bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const
4238
Cary Clark154beea2017-10-26 07:58:48 -04004239Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the
4240maximum scaling factor. Scaling factors are computed by decomposing
4241the Matrix scaling and skewing elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004242
Cary Clark154beea2017-10-26 07:58:48 -04004243Returns true if scaleFactors are found; otherwise, returns false and sets
4244scaleFactors to undefined values.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004245
Cary Clark154beea2017-10-26 07:58:48 -04004246#Param scaleFactors storage for minimum and maximum scale factors ##
4247
4248#Return true if scale factors were computed correctly ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004249
4250#Example
Cary Clark154beea2017-10-26 07:58:48 -04004251 SkMatrix matrix;
4252 matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0);
4253 matrix.invert(&matrix);
4254 SkScalar factor[2] = {2, 2};
4255 bool result = matrix.getMinMaxScales(factor);
4256 SkDebugf("matrix.getMinMaxScales() %s %g %g\n", result ? "true" : "false", factor[0], factor[1]);
4257#StdOut
4258matrix.getMinMaxScales() false 2 2
4259##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004260##
4261
Cary Clark154beea2017-10-26 07:58:48 -04004262#SeeAlso getMinScale getMaxScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04004263
4264##
4265
4266# ------------------------------------------------------------------------------
4267
4268#Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const
4269
Cary Clark154beea2017-10-26 07:58:48 -04004270Decomposes Matrix into scale components and whatever remains. Returns false if
4271Matrix could not be decomposed.
4272
4273Sets scale to portion of Matrix that scales in x and y. Sets remaining to Matrix
4274with x and y scaling factored out. remaining may be passed as nullptr
4275to determine if Matrix can be decomposed without computing remainder.
4276
4277Returns true if scale components are found. scale and remaining are
4278unchanged if Matrix contains perspective; scale factors are not finite, or
4279are nearly zero.
4280
4281On success
4282
Cary Clarkbc5697d2017-10-04 14:31:33 -04004283#Formula
Cary Clark154beea2017-10-26 07:58:48 -04004284Matrix = scale * Remaining
Cary Clarkbc5697d2017-10-04 14:31:33 -04004285##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004286
Cary Clark154beea2017-10-26 07:58:48 -04004287#Param scale x and y scaling factors; may be nullptr ##
4288#Param remaining Matrix without scaling; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004289
Cary Clark154beea2017-10-26 07:58:48 -04004290#Return true if scale can be computed ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004291
4292#Example
Cary Clark154beea2017-10-26 07:58:48 -04004293 SkMatrix matrix;
4294 matrix.setRotate(90 * SK_Scalar1);
4295 matrix.postScale(1.f / 4, 1.f / 2);
4296 matrix.dump();
4297 SkSize scale = {SK_ScalarNaN, SK_ScalarNaN};
4298 SkMatrix remaining;
4299 remaining.reset();
4300 bool success = matrix.decomposeScale(&scale, &remaining);
4301 SkDebugf("success: %s ", success ? "true" : "false");
4302 SkDebugf("scale: %g, %g\n", scale.width(), scale.height());
4303 remaining.dump();
4304 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height());
4305 SkMatrix combined = SkMatrix::Concat(scaleMatrix, remaining);
4306 combined.dump();
4307#StdOut
4308[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4309success: true scale: 0.5, 0.25
4310[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4311[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4312##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004313##
4314
Cary Clark154beea2017-10-26 07:58:48 -04004315#SeeAlso setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04004316
4317##
4318
4319# ------------------------------------------------------------------------------
4320
4321#Method static const SkMatrix& I()
4322
Cary Clark154beea2017-10-26 07:58:48 -04004323Returns reference to const identity Matrix. Returned Matrix is set to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004324
Cary Clark154beea2017-10-26 07:58:48 -04004325#Code
4326#Literal
4327| 1 0 0 |
4328| 0 1 0 |
4329| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004330##
4331
Cary Clark154beea2017-10-26 07:58:48 -04004332#Return const identity Matrix ##
4333
4334#Example
4335 SkMatrix m1, m2, m3;
4336 m1.reset();
4337 m2.setIdentity();
4338 m3 = SkMatrix::I();
4339 SkDebugf("m1 %c= m2\n", m1 == m2 ? '=' : '!');
4340 SkDebugf("m2 %c= m3\n", m1 == m2 ? '=' : '!');
4341#StdOut
4342m1 == m2
4343m2 == m3
4344##
4345##
4346
4347#SeeAlso reset() setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04004348
4349##
4350
4351# ------------------------------------------------------------------------------
4352
4353#Method static const SkMatrix& InvalidMatrix()
4354
Cary Clark154beea2017-10-26 07:58:48 -04004355Returns reference to a const Matrix with invalid values. Returned Matrix is set
4356to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004357
Cary Clark154beea2017-10-26 07:58:48 -04004358#Code
4359#Literal
4360| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
4361| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
4362| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004363##
4364
Cary Clark154beea2017-10-26 07:58:48 -04004365#Return const invalid Matrix ##
4366
4367#Example
4368 SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX());
4369#StdOut
4370scaleX 3.40282e+38
4371##
4372##
4373
4374#SeeAlso SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04004375
4376##
4377
4378# ------------------------------------------------------------------------------
4379
4380#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b)
4381
Cary Clark154beea2017-10-26 07:58:48 -04004382Returns Matrix a multiplied by Matrix b.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004383
Cary Clark154beea2017-10-26 07:58:48 -04004384Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004385
Cary Clark154beea2017-10-26 07:58:48 -04004386#Code
4387#Literal
4388 | A B C | | J K L |
4389a = | D E F |, b = | M N O |
4390 | G H I | | P Q R |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004391##
4392
Cary Clark154beea2017-10-26 07:58:48 -04004393sets Matrix to:
4394
4395#Code
4396#Literal
4397 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
4398a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
4399 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
4400##
4401
4402#Param a Matrix on left side of multiply expression ##
4403#Param b Matrix on right side of multiply expression ##
4404
4405#Return Matrix computed from a times b ##
4406
4407#Example
4408#Height 64
4409#Image 4
4410#Description
4411setPolyToPoly creates perspective matrices, one the inverse of the other.
4412Multiplying the matrix by its inverse turns into an identity matrix.
4413##
4414SkMatrix matrix, matrix2;
4415SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
4416SkRect::Make(source.bounds()).toQuad(bitmapBounds);
4417matrix.setPolyToPoly(bitmapBounds, perspect, 4);
4418matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
4419SkMatrix concat = SkMatrix::Concat(matrix, matrix2);
4420canvas->concat(concat);
4421canvas->drawBitmap(source, 0, 0);
4422##
4423
4424#SeeAlso preConcat postConcat
Cary Clarkbc5697d2017-10-04 14:31:33 -04004425
4426##
4427
4428# ------------------------------------------------------------------------------
4429
4430#Method void dirtyMatrixTypeCache()
4431
Cary Clark154beea2017-10-26 07:58:48 -04004432Sets internal cache to unknown state. Use to force update after repeated
4433modifications to Matrix element reference returned by operator[](int index).
Cary Clarkbc5697d2017-10-04 14:31:33 -04004434
4435#Example
Cary Clark154beea2017-10-26 07:58:48 -04004436SkMatrix matrix;
4437matrix.setIdentity();
4438SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
4439SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
4440skewRef = 0;
4441SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
4442skewRef = 1;
4443SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
4444matrix.dirtyMatrixTypeCache();
4445SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
4446#StdOut
4447with identity matrix: x = 24
4448after skew x mod: x = 24
4449after 2nd skew x mod: x = 24
4450after dirty cache: x = 66
4451##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004452##
4453
Cary Clark154beea2017-10-26 07:58:48 -04004454#SeeAlso operator[](int index) getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04004455
4456##
4457
4458# ------------------------------------------------------------------------------
4459
4460#Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
4461
Cary Clark154beea2017-10-26 07:58:48 -04004462Initializes Matrix with scale and translate elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004463
Cary Clark154beea2017-10-26 07:58:48 -04004464#Code
4465#Literal
4466| sx 0 tx |
4467| 0 sy ty |
4468| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004469##
4470
Cary Clark154beea2017-10-26 07:58:48 -04004471#Param sx horizontal scale factor to store ##
4472#Param sy vertical scale factor to store ##
4473#Param tx horizontal translation to store ##
4474#Param ty vertical translation to store ##
4475
4476#Example
4477SkMatrix matrix;
4478matrix.setScaleTranslate(1, 2, 3, 4);
4479matrix.dump();
4480#StdOut
4481[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000]
4482##
4483##
4484
4485#SeeAlso setScale preTranslate postTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04004486
4487##
4488
4489# ------------------------------------------------------------------------------
4490
4491#Method bool isFinite() const
4492
Cary Clark154beea2017-10-26 07:58:48 -04004493Returns true if all elements of the matrix are finite. Returns false if any
4494element is infinity, or NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004495
Cary Clark154beea2017-10-26 07:58:48 -04004496#Return true if matrix has only finite elements ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004497
4498#Example
Cary Clark154beea2017-10-26 07:58:48 -04004499SkMatrix matrix = SkMatrix::MakeTrans(SK_ScalarNaN, 0);
4500matrix.dump();
4501SkDebugf("matrix is finite: %s\n", matrix.isFinite() ? "true" : "false");
4502SkDebugf("matrix %c= matrix\n", matrix == matrix ? '=' : '!');
4503#StdOut
4504[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
4505matrix is finite: false
4506matrix != matrix
4507##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004508##
4509
Cary Clark154beea2017-10-26 07:58:48 -04004510#SeeAlso operator==
Cary Clarkbc5697d2017-10-04 14:31:33 -04004511
4512##
4513
4514#Class SkMatrix ##
4515
4516#Topic Matrix ##