blob: 63040e8a213749f26ce3e22f43822aaa1dbf099f [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
Cary Clark08895c42018-02-01 09:37:32 -05005#Subtopic Overview
Cary Clark4855f782018-02-06 09:41:53 -05006 #Subtopic Subtopic
Cary Clark08895c42018-02-01 09:37:32 -05007 #Populate
8 ##
9##
10
Cary Clarkbc5697d2017-10-04 14:31:33 -040011#Class SkMatrix
12
Cary Clark154beea2017-10-26 07:58:48 -040013Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping
14Points and Vectors with translation, scaling, skewing, rotation, and
15perspective.
Cary Clark884dd7d2017-10-11 10:37:52 -040016
Cary Clark154beea2017-10-26 07:58:48 -040017Matrix elements are in row major order. Matrix does not have a constructor,
18so it must be explicitly initialized. setIdentity initializes Matrix
19so it has no effect. setTranslate, setScale, setSkew, setRotate, set9 and setAll
20initializes all Matrix elements with the corresponding mapping.
Cary Clark884dd7d2017-10-11 10:37:52 -040021
Cary Clark154beea2017-10-26 07:58:48 -040022Matrix includes a hidden variable that classifies the type of matrix to
23improve performance. Matrix is not thread safe unless getType is called first.
Cary Clarkbc5697d2017-10-04 14:31:33 -040024
Cary Clark4855f782018-02-06 09:41:53 -050025#Subtopic Member_Function
Cary Clark08895c42018-02-01 09:37:32 -050026#Populate
27##
Cary Clarkbc5697d2017-10-04 14:31:33 -040028
Cary Clark78de7512018-02-07 07:27:09 -050029#Subtopic Related_Function
30#Populate
31##
32
Cary Clarkbc5697d2017-10-04 14:31:33 -040033# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -050034#Subtopic Constructor
35#Populate
36##
Cary Clarkbc5697d2017-10-04 14:31:33 -040037
38#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy)
Cary Clark4855f782018-02-06 09:41:53 -050039#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -050040#Line # constructs from scale in x and y ##
Cary Clark154beea2017-10-26 07:58:48 -040041Sets Matrix to scale by (sx, sy). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -040042
Cary Clark154beea2017-10-26 07:58:48 -040043#Code
44#Literal
45| sx 0 0 |
46| 0 sy 0 |
47| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -040048##
49
Cary Clark154beea2017-10-26 07:58:48 -040050#Param sx horizontal scale factor ##
51#Param sy vertical scale factor ##
52
53#Return Matrix with scale ##
54
55#Example
56#Image 4
57canvas->concat(SkMatrix::MakeScale(4, 3));
58canvas->drawBitmap(source, 0, 0);
59##
60
61#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -040062
63##
64
65# ------------------------------------------------------------------------------
66
67#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale)
68
Cary Clark154beea2017-10-26 07:58:48 -040069Sets Matrix to scale by (scale, scale). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -040070
Cary Clark154beea2017-10-26 07:58:48 -040071#Code
72#Literal
73| scale 0 0 |
74| 0 scale 0 |
75| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -040076##
77
Cary Clark154beea2017-10-26 07:58:48 -040078#Param scale horizontal and vertical scale factor ##
79
80#Return Matrix with scale ##
81
82#Example
83#Image 4
84canvas->concat(SkMatrix::MakeScale(4));
85canvas->drawBitmap(source, 0, 0);
86##
87
88#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -040089
90##
91
92# ------------------------------------------------------------------------------
93
94#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy)
Cary Clark4855f782018-02-06 09:41:53 -050095#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -050096#Line # constructs from translate in x and y ##
Cary Clark154beea2017-10-26 07:58:48 -040097Sets Matrix to translate by (dx, dy). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -040098
Cary Clark154beea2017-10-26 07:58:48 -040099#Code
100#Literal
Cary Clarkcfee6ec2017-10-26 10:34:05 -0400101| 1 0 dx |
102| 0 1 dy |
103| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400104##
105
Cary Clark154beea2017-10-26 07:58:48 -0400106#Param dx horizontal translation ##
107#Param dy vertical translation ##
108
109#Return Matrix with translation ##
110
111#Example
112#Image 4
113SkMatrix matrix = SkMatrix::MakeTrans(64, 48);
114for (int i = 0; i < 4; ++i) {
115 canvas->drawBitmap(source, 0, 0);
116 canvas->concat(matrix);
117}
118##
119
120#SeeAlso setTranslate postTranslate preTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400121
122##
123
124# ------------------------------------------------------------------------------
125
Cary Clarkbef063a2017-10-31 15:44:45 -0400126#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
127 SkScalar skewY, SkScalar scaleY, SkScalar transY,
128 SkScalar pers0, SkScalar pers1, SkScalar pers2)
Cary Clark4855f782018-02-06 09:41:53 -0500129#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -0500130#Line # constructs all nine values ##
Cary Clarkbef063a2017-10-31 15:44:45 -0400131
132
133Sets Matrix to:
134
135#Code
136#Literal
137| scaleX skewX transX |
138| skewY scaleY transY |
139| pers0 pers1 pers2 |
140##
141
142#Param scaleX horizontal scale factor ##
143#Param skewX horizontal skew factor ##
144#Param transX horizontal translation ##
145#Param skewY vertical skew factor ##
146#Param scaleY vertical scale factor ##
147#Param transY vertical translation ##
148#Param pers0 input x perspective factor ##
149#Param pers1 input y perspective factor ##
150#Param pers2 perspective scale factor ##
151
152#Return Matrix constructed from parameters ##
153
154#Example
155 SkPaint p;
156 p.setAntiAlias(true);
157 p.setTextSize(64);
158 for (SkScalar sx : { -1, 1 } ) {
159 for (SkScalar sy : { -1, 1 } ) {
160 SkAutoCanvasRestore autoRestore(canvas, true);
161 SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1);
162 canvas->concat(m);
163 canvas->drawString("K", 0, 0, p);
164 }
165 }
166##
167
168#SeeAlso setAll set9 postConcat preConcat
169
170##
171
172
173# ------------------------------------------------------------------------------
174
Cary Clarkbc5697d2017-10-04 14:31:33 -0400175#Enum TypeMask
176
177#Code
178 enum TypeMask {
179 kIdentity_Mask = 0,
180 kTranslate_Mask = 0x01,
181 kScale_Mask = 0x02,
182 kAffine_Mask = 0x04,
183 kPerspective_Mask = 0x08,
184 };
185##
186
Cary Clark154beea2017-10-26 07:58:48 -0400187Enum of bit fields for mask returned by getType.
188Used to identify the complexity of Matrix, to optimize performance.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400189
Cary Clark154beea2017-10-26 07:58:48 -0400190#Const kIdentity_Mask 0
191all bits clear if Matrix is identity
Cary Clarkbc5697d2017-10-04 14:31:33 -0400192##
Cary Clark154beea2017-10-26 07:58:48 -0400193#Const kTranslate_Mask 1
194set if Matrix has translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400195##
Cary Clark154beea2017-10-26 07:58:48 -0400196#Const kScale_Mask 2
197set if Matrix has x or y scale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400198##
Cary Clark154beea2017-10-26 07:58:48 -0400199#Const kAffine_Mask 4
200set if Matrix skews or rotates
Cary Clarkbc5697d2017-10-04 14:31:33 -0400201##
Cary Clark154beea2017-10-26 07:58:48 -0400202#Const kPerspective_Mask 8
203set if Matrix has perspective
Cary Clarkbc5697d2017-10-04 14:31:33 -0400204##
205
206#Example
Cary Clark154beea2017-10-26 07:58:48 -0400207 auto debugster = [](const char* prefix, const SkMatrix& matrix) -> void {
208 SkString typeMask;
209 typeMask += SkMatrix::kIdentity_Mask == matrix.getType() ? "kIdentity_Mask " : "";
210 typeMask += SkMatrix::kTranslate_Mask & matrix.getType() ? "kTranslate_Mask " : "";
211 typeMask += SkMatrix::kScale_Mask & matrix.getType() ? "kScale_Mask " : "";
212 typeMask += SkMatrix::kAffine_Mask & matrix.getType() ? "kAffine_Mask " : "";
213 typeMask += SkMatrix::kPerspective_Mask & matrix.getType() ? "kPerspective_Mask" : "";
214 SkDebugf("after %s: %s\n", prefix, typeMask.c_str());
215 };
216SkMatrix matrix;
217matrix.reset();
218debugster("reset", matrix);
219matrix.postTranslate(1, 0);
220debugster("postTranslate", matrix);
221matrix.postScale(2, 1);
222debugster("postScale", matrix);
223matrix.postRotate(45);
224debugster("postScale", matrix);
225SkPoint polys[][4] = {{{0, 0}, {0, 1}, {1, 1}, {1, 0}}, {{0, 0}, {0, 1}, {2, 1}, {1, 0}}};
226matrix.setPolyToPoly(polys[0], polys[1], 4);
227debugster("setPolyToPoly", matrix);
228#StdOut
229after reset: kIdentity_Mask
230after postTranslate: kTranslate_Mask
231after postScale: kTranslate_Mask kScale_Mask
232after postScale: kTranslate_Mask kScale_Mask kAffine_Mask
233after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask
234##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400235##
236
Cary Clark154beea2017-10-26 07:58:48 -0400237#SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400238
239##
240
241# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500242#Subtopic Property
243#Populate
244#Line # values and attributes ##
245##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400246
247#Method TypeMask getType() const
Cary Clark4855f782018-02-06 09:41:53 -0500248#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500249#Line # returns transform complexity ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400250Returns a bit field describing the transformations the matrix may
251perform. The bit field is computed conservatively, so it may include
Cary Clark154beea2017-10-26 07:58:48 -0400252false positives. For example, when kPerspective_Mask is set, all
253other bits are set.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400254
Cary Clark154beea2017-10-26 07:58:48 -0400255#Return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask,
256 kAffine_Mask, kPerspective_Mask
Cary Clarkbc5697d2017-10-04 14:31:33 -0400257##
258
Cary Clark154beea2017-10-26 07:58:48 -0400259#Example
260SkMatrix matrix;
261matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
262SkDebugf("identity flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
263matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, .5f);
264SkDebugf("set all flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
265#StdOut
266identity flags hex: 0 decimal: 0
267set all flags hex: f decimal: 15
268##
269##
270
271#SeeAlso TypeMask
Cary Clarkbc5697d2017-10-04 14:31:33 -0400272
273##
274
275# ------------------------------------------------------------------------------
276
277#Method bool isIdentity() const
Cary Clark4855f782018-02-06 09:41:53 -0500278#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500279#Line # returns if matrix equals the identity Matrix ##
Cary Clark154beea2017-10-26 07:58:48 -0400280Returns true if Matrix is identity. Identity matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400281
Cary Clark154beea2017-10-26 07:58:48 -0400282#Code
283#Literal
284| 1 0 0 |
285| 0 1 0 |
286| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400287##
288
Cary Clark154beea2017-10-26 07:58:48 -0400289#Return true if Matrix has no effect ##
290
291#Example
292SkMatrix matrix;
293matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
294SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
295matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 2);
296SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
297#StdOut
298is identity: true
299is identity: false
300##
301##
302
303#SeeAlso reset() setIdentity getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400304
305##
306
307# ------------------------------------------------------------------------------
308
309#Method bool isScaleTranslate() const
Cary Clark4855f782018-02-06 09:41:53 -0500310#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500311#Line # returns if transform is limited to scale and translate ##
Cary Clark154beea2017-10-26 07:58:48 -0400312Returns true if Matrix at most scales and translates. Matrix may be identity,
313contain only scale elements, only translate elements, or both. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400314
Cary Clark154beea2017-10-26 07:58:48 -0400315#Code
316#Literal
317| scale-x 0 translate-x |
318| 0 scale-y translate-y |
319| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400320##
321
Cary Clark154beea2017-10-26 07:58:48 -0400322#Return true if Matrix is identity; or scales, translates, or both ##
323
324#Example
325SkMatrix matrix;
326for (SkScalar scaleX : { 1, 2 } ) {
327 for (SkScalar translateX : { 0, 20 } ) {
328 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
329 SkDebugf("is scale-translate: %s\n", matrix.isScaleTranslate() ? "true" : "false");
330 }
331}
332#StdOut
333is scale-translate: true
334is scale-translate: true
335is scale-translate: true
336is scale-translate: true
337##
338##
339
340#SeeAlso setScale isTranslate setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400341
342##
343
344# ------------------------------------------------------------------------------
345
346#Method bool isTranslate() const
Cary Clark4855f782018-02-06 09:41:53 -0500347#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500348#Line # returns if transform is limited to translate ##
Cary Clark154beea2017-10-26 07:58:48 -0400349Returns true if Matrix is identity, or translates. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400350
Cary Clark154beea2017-10-26 07:58:48 -0400351#Code
352#Literal
353| 1 0 translate-x |
354| 0 1 translate-y |
355| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400356##
357
Cary Clark154beea2017-10-26 07:58:48 -0400358#Return true if Matrix is identity, or translates ##
359
360#Example
361SkMatrix matrix;
362for (SkScalar scaleX : { 1, 2 } ) {
363 for (SkScalar translateX : { 0, 20 } ) {
364 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
365 SkDebugf("is translate: %s\n", matrix.isTranslate() ? "true" : "false");
366 }
367}
368#StdOut
369is translate: true
370is translate: true
371is translate: false
372is translate: false
373##
374##
375
376#SeeAlso setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400377
378##
379
380# ------------------------------------------------------------------------------
381
382#Method bool rectStaysRect() const
Cary Clark4855f782018-02-06 09:41:53 -0500383#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500384#Line # returns if mapped Rect can be represented by another Rect ##
Cary Clark154beea2017-10-26 07:58:48 -0400385Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
386or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
387cases, Matrix may also have translation. Matrix form is either:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400388
Cary Clark154beea2017-10-26 07:58:48 -0400389#Code
390#Literal
391| scale-x 0 translate-x |
392| 0 scale-y translate-y |
393| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400394##
395
Cary Clark154beea2017-10-26 07:58:48 -0400396or
397
398#Code
399#Literal
400| 0 rotate-x translate-x |
401| rotate-y 0 translate-y |
402| 0 0 1 |
403##
404
405for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
406
407Also called preservesAxisAlignment; use the one that provides better inline
408documentation.
409
410#Return true if Matrix maps one Rect into another ##
411
412#Example
413SkMatrix matrix;
414for (SkScalar angle: { 0, 90, 180, 270 } ) {
415 matrix.setRotate(angle);
416 SkDebugf("rectStaysRect: %s\n", matrix.rectStaysRect() ? "true" : "false");
417}
418#StdOut
419rectStaysRect: true
420rectStaysRect: true
421rectStaysRect: true
422rectStaysRect: true
423##
424##
425
426#SeeAlso preservesAxisAlignment preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400427
428##
429
430# ------------------------------------------------------------------------------
431
432#Method bool preservesAxisAlignment() const
Cary Clark4855f782018-02-06 09:41:53 -0500433#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500434#Line # returns if mapping restricts to 90 degree multiples and mirroring ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400435
Cary Clark154beea2017-10-26 07:58:48 -0400436Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
437or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
438cases, Matrix may also have translation. Matrix form is either:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400439
Cary Clark154beea2017-10-26 07:58:48 -0400440#Code
441#Literal
442| scale-x 0 translate-x |
443| 0 scale-y translate-y |
444| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400445##
446
Cary Clark154beea2017-10-26 07:58:48 -0400447or
448
449#Code
450#Literal
451| 0 rotate-x translate-x |
452| rotate-y 0 translate-y |
453| 0 0 1 |
454##
455
456for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
457
458Also called rectStaysRect; use the one that provides better inline
459documentation.
460
461#Return true if Matrix maps one Rect into another ##
462
463#Example
464SkMatrix matrix;
465for (SkScalar angle: { 0, 90, 180, 270 } ) {
466 matrix.setRotate(angle);
467 SkDebugf("preservesAxisAlignment: %s\n", matrix.preservesAxisAlignment() ? "true" : "false");
468}
469#StdOut
470preservesAxisAlignment: true
471preservesAxisAlignment: true
472preservesAxisAlignment: true
473preservesAxisAlignment: true
474##
475##
476
477#SeeAlso rectStaysRect preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400478
479##
480
481# ------------------------------------------------------------------------------
482
483#Method bool hasPerspective() const
Cary Clark4855f782018-02-06 09:41:53 -0500484#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500485#Line # returns if transform includes perspective ##
Cary Clark154beea2017-10-26 07:58:48 -0400486Returns true if the matrix contains perspective elements. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400487
Cary Clark154beea2017-10-26 07:58:48 -0400488#Code
489#Literal
490| -- -- -- |
491| -- -- -- |
492| perspective-x perspective-y perspective-scale |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400493##
494
Cary Clark154beea2017-10-26 07:58:48 -0400495where perspective-x or perspective-y is non-zero, or perspective-scale is
496not one. All other elements may have any value.
497
498#Return true if Matrix is in most general form ##
499
500#Example
501#Image 4
502SkMatrix matrix;
503SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
504SkRect::Make(source.bounds()).toQuad(bitmapBounds);
505matrix.setPolyToPoly(bitmapBounds, perspect, 4);
506canvas->concat(matrix);
507SkString string;
508string.printf("hasPerspective %s", matrix.hasPerspective() ? "true" : "false");
509canvas->drawBitmap(source, 0, 0);
510SkPaint paint;
511paint.setAntiAlias(true);
512paint.setTextSize(48);
513canvas->drawString(string, 0, source.bounds().height() + 48, paint);
514##
515
Cary Clarkbef063a2017-10-31 15:44:45 -0400516#SeeAlso setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -0400517
518##
519
520# ------------------------------------------------------------------------------
521
522#Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const
Cary Clark4855f782018-02-06 09:41:53 -0500523#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500524#Line # returns if transform is limited to square scale and rotation ##
Cary Clark154beea2017-10-26 07:58:48 -0400525Returns true if Matrix contains only translation, rotation, reflection, and
526uniform scale.
527Returns false if Matrix contains different scales, skewing, perspective, or
528degenerate forms that collapse to a line or point.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400529
Cary Clark154beea2017-10-26 07:58:48 -0400530Describes that the Matrix makes rendering with and without the matrix are
531visually alike; a transformed circle remains a circle. Mathematically, this is
Cary Clarka560c472017-11-27 10:44:06 -0500532referred to as similarity of a Euclidean_Space, or a similarity transformation.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400533
Cary Clark154beea2017-10-26 07:58:48 -0400534Preserves right angles, keeping the arms of the angle equal lengths.
535
536#Param tol to be deprecated ##
537
538#Return true if Matrix only rotates, uniformly scales, translates ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400539
540#Example
Cary Clark154beea2017-10-26 07:58:48 -0400541#Description
542String is drawn four times through but only two are visible. Drawing the pair
543with isSimilarity false reveals the pair not visible through the matrix.
544##
545 SkPaint p;
546 p.setAntiAlias(true);
547 SkMatrix m;
548 int below = 175;
549 for (SkScalar sx : { -1, 1 } ) {
550 for (SkScalar sy : { -1, 1 } ) {
551 m.setAll(sx, 1, 128, 1, sy, 32, 0, 0, 1);
552 bool isSimilarity = m.isSimilarity();
553 SkString str;
554 str.printf("sx: %g sy: %g sim: %s", sx, sy, isSimilarity ? "true" : "false");
555 {
556 SkAutoCanvasRestore autoRestore(canvas, true);
557 canvas->concat(m);
558 canvas->drawString(str, 0, 0, p);
559 }
560 if (!isSimilarity) {
561 canvas->drawString(str, 40, below, p);
562 below += 20;
563 }
564 }
565 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400566##
567
Cary Clark154beea2017-10-26 07:58:48 -0400568#SeeAlso isScaleTranslate preservesRightAngles rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400569
570##
571
572# ------------------------------------------------------------------------------
573
574#Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const
Cary Clark4855f782018-02-06 09:41:53 -0500575#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500576#Line # returns if mapped 90 angle remains 90 degrees ##
Cary Clark154beea2017-10-26 07:58:48 -0400577Returns true if Matrix contains only translation, rotation, reflection, and
578scale. Scale may differ along rotated axes.
579Returns false if Matrix skewing, perspective, or degenerate forms that collapse
580to a line or point.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400581
Cary Clark154beea2017-10-26 07:58:48 -0400582Preserves right angles, but not requiring that the arms of the angle
583retain equal lengths.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400584
Cary Clark154beea2017-10-26 07:58:48 -0400585#Param tol to be deprecated ##
586
587#Return true if Matrix only rotates, scales, translates ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400588
589#Example
Cary Clark154beea2017-10-26 07:58:48 -0400590#Height 128
591#Description
592Equal scale is both similar and preserves right angles.
593Unequal scale is not similar but preserves right angles.
594Skews are not similar and do not preserve right angles.
595##
596SkPaint p;
597p.setAntiAlias(true);
598SkMatrix m;
599int pos = 0;
600for (SkScalar sx : { 1, 2 } ) {
601 for (SkScalar kx : { 0, 1 } ) {
602 m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1);
603 bool isSimilarity = m.isSimilarity();
604 bool preservesRightAngles = m.preservesRightAngles();
605 SkString str;
606 str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "",
607 preservesRightAngles ? "right" : "");
608 SkAutoCanvasRestore autoRestore(canvas, true);
609 canvas->concat(m);
610 canvas->drawString(str, 0, pos, p);
611 pos += 20;
612 }
613}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400614##
615
Cary Clark154beea2017-10-26 07:58:48 -0400616#SeeAlso isScaleTranslate isSimilarity rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400617
618##
619
620# ------------------------------------------------------------------------------
621
Cary Clark154beea2017-10-26 07:58:48 -0400622#Enum
Cary Clarkbc5697d2017-10-04 14:31:33 -0400623
624#Code
625 enum {
626 kMScaleX,
627 kMSkewX,
628 kMTransX,
629 kMSkewY,
630 kMScaleY,
631 kMTransY,
632 kMPersp0,
633 kMPersp1,
634 kMPersp2,
635 };
636##
637
Cary Clark154beea2017-10-26 07:58:48 -0400638Matrix organizes its values in row order. These members correspond to
639each value in Matrix.
640
Cary Clarkbc5697d2017-10-04 14:31:33 -0400641#Const kMScaleX 0
Cary Clark154beea2017-10-26 07:58:48 -0400642horizontal scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400643##
644#Const kMSkewX 1
Cary Clark154beea2017-10-26 07:58:48 -0400645horizontal skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400646##
647#Const kMTransX 2
Cary Clark154beea2017-10-26 07:58:48 -0400648horizontal translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400649##
650#Const kMSkewY 3
Cary Clark154beea2017-10-26 07:58:48 -0400651vertical skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400652##
653#Const kMScaleY 4
Cary Clark154beea2017-10-26 07:58:48 -0400654vertical scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400655##
656#Const kMTransY 5
Cary Clark154beea2017-10-26 07:58:48 -0400657vertical translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400658##
659#Const kMPersp0 6
Cary Clark154beea2017-10-26 07:58:48 -0400660input x perspective factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400661##
662#Const kMPersp1 7
Cary Clark154beea2017-10-26 07:58:48 -0400663input y perspective factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400664##
665#Const kMPersp2 8
Cary Clark154beea2017-10-26 07:58:48 -0400666perspective bias
Cary Clarkbc5697d2017-10-04 14:31:33 -0400667##
668
669#Example
Cary Clark154beea2017-10-26 07:58:48 -0400670SkPaint black;
671black.setAntiAlias(true);
672black.setTextSize(48);
673SkPaint gray = black;
674gray.setColor(0xFF9f9f9f);
675SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 };
676for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX,
677 SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY,
678 SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) {
679 SkMatrix m;
680 m.setIdentity();
681 m.set(i, offset[i]);
682 SkAutoCanvasRestore autoRestore(canvas, true);
683 canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88);
684 canvas->drawString("&", 0, 0, gray);
685 canvas->concat(m);
686 canvas->drawString("&", 0, 0, black);
687}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400688##
689
Cary Clark154beea2017-10-26 07:58:48 -0400690#SeeAlso get() set()
Cary Clarkbc5697d2017-10-04 14:31:33 -0400691
692##
693
694# ------------------------------------------------------------------------------
695
Cary Clark154beea2017-10-26 07:58:48 -0400696#Enum
Cary Clarkbc5697d2017-10-04 14:31:33 -0400697
698#Code
699 enum {
700 kAScaleX,
701 kASkewY,
702 kASkewX,
703 kAScaleY,
704 kATransX,
705 kATransY,
706 };
707##
708
Cary Clark154beea2017-10-26 07:58:48 -0400709Affine arrays are in column major order to match the matrix used by
710PDF and XPS.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400711
712#Const kAScaleX 0
Cary Clark154beea2017-10-26 07:58:48 -0400713horizontal scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400714##
715#Const kASkewY 1
Cary Clark154beea2017-10-26 07:58:48 -0400716vertical skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400717##
718#Const kASkewX 2
Cary Clark154beea2017-10-26 07:58:48 -0400719horizontal skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400720##
721#Const kAScaleY 3
Cary Clark154beea2017-10-26 07:58:48 -0400722vertical scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400723##
724#Const kATransX 4
Cary Clark154beea2017-10-26 07:58:48 -0400725horizontal translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400726##
727#Const kATransY 5
Cary Clark154beea2017-10-26 07:58:48 -0400728vertical translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400729##
730
Cary Clark154beea2017-10-26 07:58:48 -0400731#NoExample
Cary Clarkbc5697d2017-10-04 14:31:33 -0400732##
733
Cary Clark154beea2017-10-26 07:58:48 -0400734#SeeAlso SetAffineIdentity asAffine setAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -0400735
736##
737
738# ------------------------------------------------------------------------------
Cary Clark78de7512018-02-07 07:27:09 -0500739#Subtopic Operator
740#Populate
741##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400742
Cary Clarka560c472017-11-27 10:44:06 -0500743#Method SkScalar operator[](int index)_const
Cary Clarkbc5697d2017-10-04 14:31:33 -0400744
Cary Clark08895c42018-02-01 09:37:32 -0500745#Line # returns Matrix value ##
Cary Clark154beea2017-10-26 07:58:48 -0400746Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
747defined.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400748
Cary Clark154beea2017-10-26 07:58:48 -0400749#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
750 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -0400751##
752
Cary Clark154beea2017-10-26 07:58:48 -0400753#Return value corresponding to index ##
754
755#Example
756SkMatrix matrix;
757matrix.setScale(42, 24);
758SkDebugf("matrix[SkMatrix::kMScaleX] %c= 42\n", matrix[SkMatrix::kMScaleX] == 42 ? '=' : '!');
759SkDebugf("matrix[SkMatrix::kMScaleY] %c= 24\n", matrix[SkMatrix::kMScaleY] == 24 ? '=' : '!');
760#StdOut
761matrix[SkMatrix::kMScaleX] == 42
762matrix[SkMatrix::kMScaleY] == 24
763##
764##
765
766#SeeAlso get set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400767
768##
769
770# ------------------------------------------------------------------------------
771
772#Method SkScalar get(int index) const
Cary Clark4855f782018-02-06 09:41:53 -0500773#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500774#Line # returns one of nine Matrix values ##
Cary Clark154beea2017-10-26 07:58:48 -0400775Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
776defined.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400777
Cary Clark154beea2017-10-26 07:58:48 -0400778#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
779 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -0400780##
781
Cary Clark154beea2017-10-26 07:58:48 -0400782#Return value corresponding to index ##
783
784#Example
785SkMatrix matrix;
786matrix.setSkew(42, 24);
787SkDebugf("matrix.get(SkMatrix::kMSkewX) %c= 42\n",
788 matrix.get(SkMatrix::kMSkewX) == 42 ? '=' : '!');
789SkDebugf("matrix.get(SkMatrix::kMSkewY) %c= 24\n",
790 matrix.get(SkMatrix::kMSkewY) == 24 ? '=' : '!');
791#StdOut
792matrix.get(SkMatrix::kMSkewX) == 42
793matrix.get(SkMatrix::kMSkewY) == 24
794##
795##
796
797#SeeAlso operator[](int index) set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400798
799##
800
801# ------------------------------------------------------------------------------
802
803#Method SkScalar getScaleX() const
Cary Clark4855f782018-02-06 09:41:53 -0500804#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500805#Line # returns horizontal scale factor ##
Cary Clark154beea2017-10-26 07:58:48 -0400806Returns scale factor multiplied by x input, contributing to x output.
807With mapPoints, scales Points along the x-axis.
808
809#Return horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400810
811#Example
Cary Clark154beea2017-10-26 07:58:48 -0400812SkMatrix matrix;
813matrix.setScale(42, 24);
814SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!');
815#StdOut
816matrix.getScaleX() == 42
817##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400818##
819
Cary Clark154beea2017-10-26 07:58:48 -0400820#SeeAlso get getScaleY setScaleX setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400821
822##
823
824# ------------------------------------------------------------------------------
825
826#Method SkScalar getScaleY() const
Cary Clark4855f782018-02-06 09:41:53 -0500827#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500828#Line # returns vertical scale factor ##
Cary Clark154beea2017-10-26 07:58:48 -0400829Returns scale factor multiplied by y input, contributing to y output.
830With mapPoints, scales Points along the y-axis.
831
832#Return vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400833
834#Example
Cary Clark154beea2017-10-26 07:58:48 -0400835SkMatrix matrix;
836matrix.setScale(42, 24);
837SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!');
838#StdOut
839matrix.getScaleY() == 24
840##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400841##
842
Cary Clark154beea2017-10-26 07:58:48 -0400843#SeeAlso get getScaleX setScaleY setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400844
845##
846
847# ------------------------------------------------------------------------------
848
849#Method SkScalar getSkewY() const
Cary Clark4855f782018-02-06 09:41:53 -0500850#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500851#Line # returns vertical skew factor ##
Cary Clark154beea2017-10-26 07:58:48 -0400852Returns scale factor multiplied by x input, contributing to y output.
853With mapPoints, skews Points along the y-axis.
854Skew x and y together can rotate Points.
855
856#Return vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400857
858#Example
Cary Clark154beea2017-10-26 07:58:48 -0400859SkMatrix matrix;
860matrix.setSkew(42, 24);
861SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!');
862#StdOut
863matrix.getSkewY() == 24
864##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400865##
866
Cary Clark154beea2017-10-26 07:58:48 -0400867#SeeAlso get getSkewX setSkewY setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400868
869##
870
871# ------------------------------------------------------------------------------
872
873#Method SkScalar getSkewX() const
Cary Clark4855f782018-02-06 09:41:53 -0500874#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500875#Line # returns horizontal skew factor ##
Cary Clark154beea2017-10-26 07:58:48 -0400876Returns scale factor multiplied by y input, contributing to x output.
877With mapPoints, skews Points along the x-axis.
878Skew x and y together can rotate Points.
879
880#Return horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400881
882#Example
Cary Clark154beea2017-10-26 07:58:48 -0400883SkMatrix matrix;
884matrix.setSkew(42, 24);
885SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!');
886#StdOut
887matrix.getSkewX() == 42
888##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400889##
890
Cary Clark154beea2017-10-26 07:58:48 -0400891#SeeAlso get getSkewY setSkewX setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400892
893##
894
895# ------------------------------------------------------------------------------
896
897#Method SkScalar getTranslateX() const
Cary Clark4855f782018-02-06 09:41:53 -0500898#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500899#Line # returns horizontal translation ##
Cary Clark154beea2017-10-26 07:58:48 -0400900Returns translation contributing to x output.
901With mapPoints, moves Points along the x-axis.
902
903#Return horizontal translation factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400904
905#Example
Cary Clark154beea2017-10-26 07:58:48 -0400906SkMatrix matrix;
907matrix.setTranslate(42, 24);
908SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!');
909#StdOut
910matrix.getTranslateX() == 42
911##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400912##
913
Cary Clark154beea2017-10-26 07:58:48 -0400914#SeeAlso get getTranslateY setTranslateX setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400915
916##
917
918# ------------------------------------------------------------------------------
919
920#Method SkScalar getTranslateY() const
Cary Clark4855f782018-02-06 09:41:53 -0500921#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500922#Line # returns vertical translation ##
Cary Clark154beea2017-10-26 07:58:48 -0400923Returns translation contributing to y output.
924With mapPoints, moves Points along the y-axis.
925
926#Return vertical translation factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400927
928#Example
Cary Clark154beea2017-10-26 07:58:48 -0400929SkMatrix matrix;
930matrix.setTranslate(42, 24);
931SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!');
932#StdOut
933matrix.getTranslateY() == 24
934##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400935##
936
Cary Clark154beea2017-10-26 07:58:48 -0400937#SeeAlso get getTranslateX setTranslateY setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400938
939##
940
941# ------------------------------------------------------------------------------
942
943#Method SkScalar getPerspX() const
Cary Clark4855f782018-02-06 09:41:53 -0500944#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500945#Line # returns input x perspective factor ##
Cary Clark154beea2017-10-26 07:58:48 -0400946Returns factor scaling input x relative to input y.
947
948#Return input x perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400949
950#Example
Cary Clark154beea2017-10-26 07:58:48 -0400951 SkMatrix m;
952 m.setIdentity();
953 m.set(SkMatrix::kMPersp0, -0.004f);
954 SkAutoCanvasRestore autoRestore(canvas, true);
955 canvas->translate(22, 144);
956 SkPaint black;
957 black.setAntiAlias(true);
958 black.setTextSize(24);
959 SkPaint gray = black;
960 gray.setColor(0xFF9f9f9f);
961 SkString string;
962 string.appendScalar(m.getPerspX());
963 canvas->drawString(string, 0, -72, gray);
964 canvas->concat(m);
965 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400966##
967
Cary Clark154beea2017-10-26 07:58:48 -0400968#SeeAlso kMPersp0 getPerspY
Cary Clarkbc5697d2017-10-04 14:31:33 -0400969
970##
971
972# ------------------------------------------------------------------------------
973
974#Method SkScalar getPerspY() const
Cary Clark4855f782018-02-06 09:41:53 -0500975#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500976#Line # returns input y perspective factor ##
Cary Clark154beea2017-10-26 07:58:48 -0400977
978Returns factor scaling input y relative to input x.
979
980#Return input y perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400981
982#Example
Cary Clark154beea2017-10-26 07:58:48 -0400983 SkMatrix m;
984 m.setIdentity();
985 m.set(SkMatrix::kMPersp1, -0.004f);
986 SkAutoCanvasRestore autoRestore(canvas, true);
987 canvas->translate(22, 144);
988 SkPaint black;
989 black.setAntiAlias(true);
990 black.setTextSize(24);
991 SkPaint gray = black;
992 gray.setColor(0xFF9f9f9f);
993 SkString string;
994 string.appendScalar(m.getPerspY());
995 canvas->drawString(string, 0, -72, gray);
996 canvas->concat(m);
997 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400998##
999
Cary Clark154beea2017-10-26 07:58:48 -04001000#SeeAlso kMPersp1 getPerspX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001001
1002##
1003
1004# ------------------------------------------------------------------------------
1005
Cary Clark154beea2017-10-26 07:58:48 -04001006#Method SkScalar& operator[](int index)
Cary Clarkbc5697d2017-10-04 14:31:33 -04001007
Cary Clark08895c42018-02-01 09:37:32 -05001008#Line # returns writable reference to Matrix value ##
Cary Clark154beea2017-10-26 07:58:48 -04001009Returns writable Matrix value. Asserts if index is out of range and SK_DEBUG is
1010defined. Clears internal cache anticipating that caller will change Matrix value.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001011
Cary Clark154beea2017-10-26 07:58:48 -04001012Next call to read Matrix state may recompute cache; subsequent writes to Matrix
1013value must be followed by dirtyMatrixTypeCache.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001014
Cary Clark154beea2017-10-26 07:58:48 -04001015#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1016 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -04001017##
1018
Cary Clark154beea2017-10-26 07:58:48 -04001019#Return writable value corresponding to index ##
1020
1021#Example
1022SkMatrix matrix;
1023matrix.setIdentity();
1024SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
1025SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
1026skewRef = 0;
1027SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1028skewRef = 1;
1029SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1030matrix.dirtyMatrixTypeCache();
1031SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
1032#StdOut
1033with identity matrix: x = 24
1034after skew x mod: x = 24
1035after 2nd skew x mod: x = 24
1036after dirty cache: x = 66
1037##
1038##
1039
1040#SeeAlso get dirtyMatrixTypeCache set
Cary Clarkbc5697d2017-10-04 14:31:33 -04001041
1042##
1043
1044# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05001045#Subtopic Set
1046#Populate
1047#Line # set one or more matrix values ##
1048##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001049
1050#Method void set(int index, SkScalar value)
Cary Clark4855f782018-02-06 09:41:53 -05001051#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001052#Line # sets one value ##
Cary Clark154beea2017-10-26 07:58:48 -04001053Sets Matrix value. Asserts if index is out of range and SK_DEBUG is
1054defined. Safer than operator[]; internal cache is always maintained.
1055
1056#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1057 kMPersp0, kMPersp1, kMPersp2
1058##
1059#Param value Scalar to store in Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001060
1061#Example
Cary Clark154beea2017-10-26 07:58:48 -04001062SkMatrix matrix;
1063matrix.setIdentity();
1064SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
1065matrix.set(SkMatrix::kMSkewX, 0);
1066SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1067matrix.set(SkMatrix::kMSkewX, 1);
1068SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1069#StdOut
1070with identity matrix: x = 24
1071after skew x mod: x = 24
1072after 2nd skew x mod: x = 66
1073##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001074##
1075
Cary Clark154beea2017-10-26 07:58:48 -04001076#SeeAlso operator[] get
Cary Clarkbc5697d2017-10-04 14:31:33 -04001077
Cary Clark154beea2017-10-26 07:58:48 -04001078#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001079
1080# ------------------------------------------------------------------------------
1081
1082#Method void setScaleX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001083#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001084#Line # sets horizontal scale factor ##
Cary Clark154beea2017-10-26 07:58:48 -04001085Sets horizontal scale factor.
1086
1087#Param v horizontal scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001088
1089#Example
Cary Clark154beea2017-10-26 07:58:48 -04001090#Height 64
1091SkPaint paint;
1092paint.setAntiAlias(true);
1093paint.setTextSize(24);
1094canvas->drawString("normal", 12, 24, paint);
1095SkMatrix matrix;
1096matrix.setIdentity();
1097matrix.setScaleX(3);
1098canvas->concat(matrix);
1099canvas->drawString("x scale", 0, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001100##
1101
Cary Clark154beea2017-10-26 07:58:48 -04001102#SeeAlso set setScale setScaleY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001103
Cary Clark154beea2017-10-26 07:58:48 -04001104#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001105
1106# ------------------------------------------------------------------------------
1107
1108#Method void setScaleY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001109#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001110#Line # sets vertical scale factor ##
Cary Clark154beea2017-10-26 07:58:48 -04001111Sets vertical scale factor.
1112
1113#Param v vertical scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001114
1115#Example
Cary Clark154beea2017-10-26 07:58:48 -04001116#Height 192
1117SkPaint paint;
1118paint.setAntiAlias(true);
1119paint.setTextSize(24);
1120canvas->drawString("normal", 12, 24, paint);
1121SkMatrix matrix;
1122matrix.setIdentity();
1123matrix.setScaleY(3);
1124canvas->concat(matrix);
1125canvas->drawString("y scale", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001126##
1127
Cary Clark154beea2017-10-26 07:58:48 -04001128#SeeAlso set setScale setScaleX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001129
Cary Clark154beea2017-10-26 07:58:48 -04001130#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001131
1132# ------------------------------------------------------------------------------
1133
1134#Method void setSkewY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001135#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001136#Line # sets vertical skew factor ##
Cary Clark154beea2017-10-26 07:58:48 -04001137Sets vertical skew factor.
1138
1139#Param v vertical skew factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001140
1141#Example
Cary Clark154beea2017-10-26 07:58:48 -04001142#Height 96
1143SkPaint paint;
1144paint.setAntiAlias(true);
1145paint.setTextSize(24);
1146canvas->drawString("normal", 12, 24, paint);
1147SkMatrix matrix;
1148matrix.setIdentity();
1149matrix.setSkewY(.3f);
1150canvas->concat(matrix);
1151canvas->drawString("y skew", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001152##
1153
Cary Clark154beea2017-10-26 07:58:48 -04001154#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001155
Cary Clark154beea2017-10-26 07:58:48 -04001156#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001157
1158# ------------------------------------------------------------------------------
1159
1160#Method void setSkewX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001161#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001162#Line # sets horizontal skew factor ##
Cary Clark154beea2017-10-26 07:58:48 -04001163Sets horizontal skew factor.
1164
1165#Param v horizontal skew factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001166
1167#Example
Cary Clark154beea2017-10-26 07:58:48 -04001168#Height 64
1169SkPaint paint;
1170paint.setAntiAlias(true);
1171paint.setTextSize(24);
1172canvas->drawString("normal", 12, 24, paint);
1173SkMatrix matrix;
1174matrix.setIdentity();
1175matrix.setSkewX(-.7f);
1176canvas->concat(matrix);
1177canvas->drawString("x skew", 36, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001178##
1179
Cary Clark154beea2017-10-26 07:58:48 -04001180#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001181
Cary Clark154beea2017-10-26 07:58:48 -04001182#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001183
1184# ------------------------------------------------------------------------------
1185
1186#Method void setTranslateX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001187#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001188#Line # sets horizontal translation ##
Cary Clark154beea2017-10-26 07:58:48 -04001189Sets horizontal translation.
1190
1191#Param v horizontal translation to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001192
1193#Example
Cary Clark154beea2017-10-26 07:58:48 -04001194#Height 48
1195SkPaint paint;
1196paint.setAntiAlias(true);
1197paint.setTextSize(24);
1198canvas->drawString("normal", 8, 24, paint);
1199SkMatrix matrix;
1200matrix.setIdentity();
1201matrix.setTranslateX(96);
1202canvas->concat(matrix);
1203canvas->drawString("x translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001204##
1205
Cary Clark154beea2017-10-26 07:58:48 -04001206#SeeAlso set setTranslate setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001207
Cary Clark154beea2017-10-26 07:58:48 -04001208#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001209
1210# ------------------------------------------------------------------------------
1211
1212#Method void setTranslateY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001213#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001214#Line # sets vertical translation ##
Cary Clark154beea2017-10-26 07:58:48 -04001215Sets vertical translation.
1216
1217#Param v vertical translation to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001218
1219#Example
Cary Clark154beea2017-10-26 07:58:48 -04001220#Height 64
1221SkPaint paint;
1222paint.setAntiAlias(true);
1223paint.setTextSize(24);
1224canvas->drawString("normal", 8, 24, paint);
1225SkMatrix matrix;
1226matrix.setIdentity();
1227matrix.setTranslateY(24);
1228canvas->concat(matrix);
1229canvas->drawString("y translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001230##
1231
Cary Clark154beea2017-10-26 07:58:48 -04001232#SeeAlso set setTranslate setTranslateX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001233
Cary Clark154beea2017-10-26 07:58:48 -04001234#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001235
1236# ------------------------------------------------------------------------------
1237
1238#Method void setPerspX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001239#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001240#Line # sets input x perspective factor ##
Cary Clark154beea2017-10-26 07:58:48 -04001241Sets input x perspective factor, which causes mapXY to vary input x inversely
1242proportional to input y.
1243
1244#Param v perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001245
1246#Example
Cary Clark154beea2017-10-26 07:58:48 -04001247#Image 4
1248for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
1249 SkMatrix matrix;
1250 matrix.setIdentity();
1251 matrix.setPerspX(perspX);
1252 canvas->save();
1253 canvas->concat(matrix);
1254 canvas->drawBitmap(source, 0, 0);
1255 canvas->restore();
1256 canvas->translate(64, 64);
1257}
Cary Clarkbc5697d2017-10-04 14:31:33 -04001258##
1259
Cary Clarkbef063a2017-10-31 15:44:45 -04001260#SeeAlso getPerspX set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001261
Cary Clark154beea2017-10-26 07:58:48 -04001262#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001263
1264# ------------------------------------------------------------------------------
1265
1266#Method void setPerspY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -05001267#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001268#Line # sets input y perspective factor ##
Cary Clark154beea2017-10-26 07:58:48 -04001269Sets input y perspective factor, which causes mapXY to vary input y inversely
1270proportional to input x.
1271
1272#Param v perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001273
1274#Example
Cary Clark154beea2017-10-26 07:58:48 -04001275#Image 4
1276for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
1277 SkMatrix matrix;
1278 matrix.setIdentity();
1279 matrix.setPerspY(perspX);
1280 canvas->save();
1281 canvas->concat(matrix);
1282 canvas->drawBitmap(source, 0, 0);
1283 canvas->restore();
1284 canvas->translate(64, 64);
1285}
Cary Clarkbc5697d2017-10-04 14:31:33 -04001286##
1287
Cary Clarkbef063a2017-10-31 15:44:45 -04001288#SeeAlso getPerspY set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001289
Cary Clark154beea2017-10-26 07:58:48 -04001290#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001291
1292# ------------------------------------------------------------------------------
1293
1294#Method void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
1295 SkScalar skewY, SkScalar scaleY, SkScalar transY,
1296 SkScalar persp0, SkScalar persp1, SkScalar persp2)
Cary Clark4855f782018-02-06 09:41:53 -05001297#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001298#Line # sets all values from parameters ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001299
Cary Clark154beea2017-10-26 07:58:48 -04001300Sets all values from parameters. Sets matrix to:
1301
1302#Code
1303#Literal
1304| scaleX skewX transX |
1305| skewY scaleY transY |
1306| persp0 persp1 persp2 |
1307##
1308
1309#Param scaleX horizontal scale factor to store ##
1310#Param skewX horizontal skew factor to store ##
1311#Param transX horizontal translation to store ##
1312#Param skewY vertical skew factor to store ##
1313#Param scaleY vertical scale factor to store ##
1314#Param transY vertical translation to store ##
1315#Param persp0 input x perspective factor to store ##
1316#Param persp1 input y perspective factor to store ##
1317#Param persp2 perspective scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001318
1319#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001320#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001321 SkPaint p;
1322 p.setAntiAlias(true);
1323 p.setTextSize(64);
1324 SkMatrix m;
1325 for (SkScalar sx : { -1, 1 } ) {
1326 for (SkScalar sy : { -1, 1 } ) {
1327 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001328 m.setAll(sx, 1, 128, 0, sy, 64, 0, 0, 1);
Cary Clark154beea2017-10-26 07:58:48 -04001329 canvas->concat(m);
1330 canvas->drawString("K", 0, 0, p);
1331 }
1332 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001333##
1334
Cary Clarkbef063a2017-10-31 15:44:45 -04001335#SeeAlso set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001336
Cary Clark154beea2017-10-26 07:58:48 -04001337#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001338
1339# ------------------------------------------------------------------------------
1340
1341#Method void get9(SkScalar buffer[9]) const
Cary Clark4855f782018-02-06 09:41:53 -05001342#In Property
Cary Clark08895c42018-02-01 09:37:32 -05001343#Line # returns all nine Matrix values ##
Cary Clark154beea2017-10-26 07:58:48 -04001344Copies nine Scalar values contained by Matrix into buffer, in member value
1345ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1346kMPersp0, kMPersp1, kMPersp2.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001347
Cary Clark154beea2017-10-26 07:58:48 -04001348#Param buffer storage for nine Scalar values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001349
1350#Example
Cary Clark154beea2017-10-26 07:58:48 -04001351SkMatrix matrix = SkMatrix::MakeRectToRect({0, 0, 1, 1}, {3, 4, 7, 9},
1352 SkMatrix::kFill_ScaleToFit);
1353SkScalar b[9];
1354matrix.get9(b);
1355SkDebugf("{%g, %g, %g},\n{%g, %g, %g},\n{%g, %g, %g}\n", b[0], b[1], b[2],
1356 b[3], b[4], b[5], b[6], b[7], b[8]);
1357#StdOut
1358{4, 0, 3},
1359{0, 5, 4},
1360{0, 0, 1}
1361##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001362##
1363
Cary Clark154beea2017-10-26 07:58:48 -04001364#SeeAlso set9
Cary Clarkbc5697d2017-10-04 14:31:33 -04001365
Cary Clark154beea2017-10-26 07:58:48 -04001366#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001367
1368# ------------------------------------------------------------------------------
1369
1370#Method void set9(const SkScalar buffer[9])
Cary Clark4855f782018-02-06 09:41:53 -05001371#In Set
1372#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -05001373#Line # sets all values from Scalar array ##
Cary Clark154beea2017-10-26 07:58:48 -04001374Sets Matrix to nine Scalar values in buffer, in member value ascending order:
1375kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1,
1376kMPersp2.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001377
Cary Clark154beea2017-10-26 07:58:48 -04001378Sets matrix to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04001379
Cary Clark154beea2017-10-26 07:58:48 -04001380#Code
1381#Literal
1382| buffer[0] buffer[1] buffer[2] |
1383| buffer[3] buffer[4] buffer[5] |
1384| buffer[6] buffer[7] buffer[8] |
1385##
1386
1387In the future, set9 followed by get9 may not return the same values. Since Matrix
1388maps non-homogeneous coordinates, scaling all nine values produces an equivalent
1389transformation, possibly improving precision.
1390
1391#Param buffer nine Scalar values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001392
1393#Example
Cary Clark154beea2017-10-26 07:58:48 -04001394#Image 4
1395SkMatrix m;
1396SkScalar buffer[9] = {4, 0, 3, 0, 5, 4, 0, 0, 1};
1397m.set9(buffer);
1398canvas->concat(m);
1399canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001400##
1401
Cary Clarkbef063a2017-10-31 15:44:45 -04001402#SeeAlso setAll get9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001403
Cary Clark154beea2017-10-26 07:58:48 -04001404#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001405
1406# ------------------------------------------------------------------------------
1407
1408#Method void reset()
Cary Clark4855f782018-02-06 09:41:53 -05001409#In Constructor
1410#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001411#Line # sets Matrix to identity ##
Cary Clark154beea2017-10-26 07:58:48 -04001412Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
1413
1414#Code
1415#Literal
1416| 1 0 0 |
1417| 0 1 0 |
1418| 0 0 1 |
1419##
1420
1421Also called setIdentity(); use the one that provides better inline
1422documentation.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001423
1424#Example
Cary Clark154beea2017-10-26 07:58:48 -04001425SkMatrix m;
1426m.reset();
1427SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1428#StdOut
1429m.isIdentity(): true
1430##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001431##
1432
Cary Clark154beea2017-10-26 07:58:48 -04001433#SeeAlso isIdentity setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04001434
Cary Clark154beea2017-10-26 07:58:48 -04001435#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001436
1437# ------------------------------------------------------------------------------
1438
1439#Method void setIdentity()
Cary Clark4855f782018-02-06 09:41:53 -05001440#In Constructor
1441#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001442#Line # sets Matrix to identity ##
Cary Clark154beea2017-10-26 07:58:48 -04001443Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
1444
1445#Code
1446#Literal
1447| 1 0 0 |
1448| 0 1 0 |
1449| 0 0 1 |
1450##
1451
1452Also called reset(); use the one that provides better inline
1453documentation.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001454
1455#Example
Cary Clark154beea2017-10-26 07:58:48 -04001456SkMatrix m;
1457m.setIdentity();
1458SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1459#StdOut
1460m.isIdentity(): true
1461##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001462##
1463
Cary Clark154beea2017-10-26 07:58:48 -04001464#SeeAlso isIdentity reset
Cary Clarkbc5697d2017-10-04 14:31:33 -04001465
Cary Clark154beea2017-10-26 07:58:48 -04001466#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001467
1468# ------------------------------------------------------------------------------
1469
1470#Method void setTranslate(SkScalar dx, SkScalar dy)
Cary Clark4855f782018-02-06 09:41:53 -05001471#In Constructor
1472#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001473#Line # sets to translate in x and y ##
Cary Clark154beea2017-10-26 07:58:48 -04001474Sets Matrix to translate by (dx, dy).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001475
Cary Clark154beea2017-10-26 07:58:48 -04001476#Param dx horizontal translation ##
1477#Param dy vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001478
1479#Example
Cary Clark154beea2017-10-26 07:58:48 -04001480#Height 64
1481SkPaint paint;
1482paint.setAntiAlias(true);
1483paint.setTextSize(24);
1484canvas->drawString("normal", 8, 24, paint);
1485SkMatrix matrix;
1486matrix.setTranslate(96, 24);
1487canvas->concat(matrix);
1488canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001489##
1490
Cary Clark154beea2017-10-26 07:58:48 -04001491#SeeAlso setTranslateX setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001492
Cary Clark154beea2017-10-26 07:58:48 -04001493#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001494
1495# ------------------------------------------------------------------------------
1496
1497#Method void setTranslate(const SkVector& v)
1498
Cary Clark154beea2017-10-26 07:58:48 -04001499Sets Matrix to translate by (v.fX, v.fY).
1500
1501#Param v Vector containing horizontal and vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001502
1503#Example
Cary Clark154beea2017-10-26 07:58:48 -04001504#Height 64
1505SkPaint paint;
1506paint.setAntiAlias(true);
1507paint.setTextSize(24);
1508canvas->drawString("normal", 8, 24, paint);
1509SkMatrix matrix;
1510matrix.setTranslate({96, 24});
1511canvas->concat(matrix);
1512canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001513##
1514
Cary Clark154beea2017-10-26 07:58:48 -04001515#SeeAlso setTranslateX setTranslateY MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001516
Cary Clark154beea2017-10-26 07:58:48 -04001517#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001518
1519# ------------------------------------------------------------------------------
1520
1521#Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001522#In Constructor
1523#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001524#Line # sets to scale about a point ##
Cary Clark154beea2017-10-26 07:58:48 -04001525Sets Matrix to scale by sx and sy, about a pivot point at (px, py).
1526The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001527
Cary Clark154beea2017-10-26 07:58:48 -04001528#Param sx horizontal scale factor ##
1529#Param sy vertical scale factor ##
1530#Param px pivot x ##
1531#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001532
1533#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001534#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001535 SkPaint p;
1536 p.setAntiAlias(true);
1537 p.setTextSize(64);
1538 SkMatrix m;
1539 for (SkScalar sx : { -1, 1 } ) {
1540 for (SkScalar sy : { -1, 1 } ) {
1541 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001542 m.setScale(sx, sy, 128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001543 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001544 canvas->drawString("%", 128, 64, p);
Cary Clark154beea2017-10-26 07:58:48 -04001545 }
1546 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001547##
1548
Cary Clark154beea2017-10-26 07:58:48 -04001549#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001550
Cary Clark154beea2017-10-26 07:58:48 -04001551#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001552
1553# ------------------------------------------------------------------------------
1554
1555#Method void setScale(SkScalar sx, SkScalar sy)
1556
Cary Clark154beea2017-10-26 07:58:48 -04001557Sets Matrix to scale by sx and sy about at pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001558
Cary Clark154beea2017-10-26 07:58:48 -04001559#Param sx horizontal scale factor ##
1560#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001561
1562#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001563#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001564 SkPaint p;
1565 p.setAntiAlias(true);
1566 p.setTextSize(64);
1567 SkMatrix m;
1568 for (SkScalar sx : { -1, 1 } ) {
1569 for (SkScalar sy : { -1, 1 } ) {
1570 SkAutoCanvasRestore autoRestore(canvas, true);
1571 m.setScale(sx, sy);
Cary Clark2ade9972017-11-02 17:49:34 -04001572 m.postTranslate(128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001573 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001574 canvas->drawString("@", 0, 0, p);
Cary Clark154beea2017-10-26 07:58:48 -04001575 }
1576 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001577##
1578
Cary Clark154beea2017-10-26 07:58:48 -04001579#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001580
Cary Clark154beea2017-10-26 07:58:48 -04001581#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001582
1583# ------------------------------------------------------------------------------
1584
1585#Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001586#In Constructor
1587#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001588#Line # sets to rotate about a point ##
Cary Clark154beea2017-10-26 07:58:48 -04001589Sets Matrix to rotate by degrees about a pivot point at (px, py).
1590The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001591
Cary Clark154beea2017-10-26 07:58:48 -04001592Positive degrees rotates clockwise.
1593
1594#Param degrees angle of axes relative to upright axes ##
1595#Param px pivot x ##
1596#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001597
1598#Example
Cary Clark154beea2017-10-26 07:58:48 -04001599#Height 128
1600 SkPaint paint;
1601 paint.setColor(SK_ColorGRAY);
1602 paint.setAntiAlias(true);
1603 SkRect rect = {20, 20, 100, 100};
1604 canvas->drawRect(rect, paint);
1605 paint.setColor(SK_ColorRED);
1606 SkMatrix matrix;
1607 matrix.setRotate(25, rect.centerX(), rect.centerY());
1608 canvas->concat(matrix);
1609 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001610##
1611
Cary Clark154beea2017-10-26 07:58:48 -04001612#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001613
Cary Clark154beea2017-10-26 07:58:48 -04001614#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001615
1616# ------------------------------------------------------------------------------
1617
1618#Method void setRotate(SkScalar degrees)
1619
Cary Clark154beea2017-10-26 07:58:48 -04001620Sets Matrix to rotate by degrees about a pivot point at (0, 0).
1621Positive degrees rotates clockwise.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001622
Cary Clark154beea2017-10-26 07:58:48 -04001623#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001624
1625#Example
Cary Clark154beea2017-10-26 07:58:48 -04001626#Height 128
1627 SkPaint paint;
1628 paint.setColor(SK_ColorGRAY);
1629 paint.setAntiAlias(true);
1630 SkRect rect = {20, 20, 100, 100};
1631 canvas->drawRect(rect, paint);
1632 paint.setColor(SK_ColorRED);
1633 SkMatrix matrix;
1634 matrix.setRotate(25);
1635 canvas->translate(rect.centerX(), rect.centerY());
1636 canvas->concat(matrix);
1637 canvas->translate(-rect.centerX(), -rect.centerY());
1638 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001639##
1640
Cary Clark154beea2017-10-26 07:58:48 -04001641#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001642
Cary Clark154beea2017-10-26 07:58:48 -04001643#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001644
1645# ------------------------------------------------------------------------------
1646
1647#Method void setSinCos(SkScalar sinValue, SkScalar cosValue,
1648 SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001649#In Constructor
1650#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001651#Line # sets to rotate and scale about a point ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001652
Cary Clark154beea2017-10-26 07:58:48 -04001653Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (px, py).
1654The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001655
Cary Clark154beea2017-10-26 07:58:48 -04001656Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
1657Vector length specifies scale.
1658
1659#Param sinValue rotation vector x component ##
1660#Param cosValue rotation vector y component ##
1661#Param px pivot x ##
1662#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001663
1664#Example
Cary Clark154beea2017-10-26 07:58:48 -04001665#Height 128
1666 SkPaint paint;
1667 paint.setColor(SK_ColorGRAY);
1668 paint.setAntiAlias(true);
1669 SkRect rect = {20, 20, 100, 100};
1670 canvas->drawRect(rect, paint);
1671 paint.setColor(SK_ColorRED);
1672 SkMatrix matrix;
1673 matrix.setSinCos(.25f, .85f, rect.centerX(), rect.centerY());
1674 canvas->concat(matrix);
1675 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001676##
1677
Cary Clark154beea2017-10-26 07:58:48 -04001678#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001679
Cary Clark154beea2017-10-26 07:58:48 -04001680#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001681
1682# ------------------------------------------------------------------------------
1683
1684#Method void setSinCos(SkScalar sinValue, SkScalar cosValue)
1685
Cary Clark154beea2017-10-26 07:58:48 -04001686Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001687
Cary Clark154beea2017-10-26 07:58:48 -04001688Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
1689Vector length specifies scale.
1690
1691#Param sinValue rotation vector x component ##
1692#Param cosValue rotation vector y component ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001693
1694#Example
Cary Clark154beea2017-10-26 07:58:48 -04001695#Description
1696Canvas needs offset after applying Matrix to pivot about Rect center.
1697##
1698#Height 128
1699 SkPaint paint;
1700 paint.setColor(SK_ColorGRAY);
1701 paint.setAntiAlias(true);
1702 SkRect rect = {20, 20, 100, 100};
1703 canvas->drawRect(rect, paint);
1704 paint.setColor(SK_ColorRED);
1705 SkMatrix matrix;
1706 matrix.setSinCos(.25f, .85f);
1707 matrix.postTranslate(rect.centerX(), rect.centerY());
1708 canvas->concat(matrix);
1709 canvas->translate(-rect.centerX(), -rect.centerY());
1710 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001711##
1712
Cary Clark154beea2017-10-26 07:58:48 -04001713#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001714
Cary Clark154beea2017-10-26 07:58:48 -04001715#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001716
1717# ------------------------------------------------------------------------------
1718
1719#Method SkMatrix& setRSXform(const SkRSXform& rsxForm)
Cary Clark4855f782018-02-06 09:41:53 -05001720#In Constructor
1721#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001722#Line # sets to rotate, scale, and translate ##
Cary Clark154beea2017-10-26 07:58:48 -04001723Sets Matrix to rotate, scale, and translate using a compressed matrix form.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001724
Cary Clark154beea2017-10-26 07:58:48 -04001725Vector (rsxForm.fSSin, rsxForm.fSCos) describes the angle of rotation relative
1726to (0, 1). Vector length specifies scale. Mapped point is rotated and scaled
1727by Vector, then translated by (rsxForm.fTx, rsxForm.fTy).
1728
1729#Param rsxForm compressed RSXform matrix ##
1730
1731#Return reference to Matrix ##
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.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY()));
1746 canvas->concat(matrix);
1747 canvas->translate(-rect.centerX(), -rect.centerY());
1748 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001749##
1750
Cary Clark154beea2017-10-26 07:58:48 -04001751#SeeAlso setSinCos setScale setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001752
Cary Clark154beea2017-10-26 07:58:48 -04001753#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001754
1755# ------------------------------------------------------------------------------
1756
1757#Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001758#In Constructor
1759#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001760#Line # sets to skew about a point ##
Cary Clark154beea2017-10-26 07:58:48 -04001761Sets Matrix to skew by kx and ky, about a pivot point at (px, py).
1762The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001763
Cary Clark154beea2017-10-26 07:58:48 -04001764#Param kx horizontal skew factor ##
1765#Param ky vertical skew factor ##
1766#Param px pivot x ##
1767#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001768
1769#Example
Cary Clark154beea2017-10-26 07:58:48 -04001770 SkPaint p;
1771 p.setAntiAlias(true);
1772 p.setTextSize(48);
1773 SkMatrix m;
1774 for (SkScalar sx : { -1, 0, 1 } ) {
1775 for (SkScalar sy : { -1, 0, 1 } ) {
1776 SkAutoCanvasRestore autoRestore(canvas, true);
1777 m.setSkew(sx, sy, 96 + 64 * sx, 128 + 48 * sy);
1778 canvas->concat(m);
1779 canvas->drawString("K", 96 + 64 * sx, 128 + 48 * sy, p);
1780 }
1781 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001782##
1783
Cary Clark154beea2017-10-26 07:58:48 -04001784#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001785
Cary Clark154beea2017-10-26 07:58:48 -04001786#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001787
1788# ------------------------------------------------------------------------------
1789
1790#Method void setSkew(SkScalar kx, SkScalar ky)
1791
Cary Clark154beea2017-10-26 07:58:48 -04001792Sets Matrix to skew by kx and ky, about a pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001793
Cary Clark154beea2017-10-26 07:58:48 -04001794#Param kx horizontal skew factor ##
1795#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001796
1797#Example
Cary Clark154beea2017-10-26 07:58:48 -04001798 SkPaint p;
1799 p.setAntiAlias(true);
1800 p.setTextSize(48);
1801 SkMatrix m;
1802 for (SkScalar sx : { -1, 0, 1 } ) {
1803 for (SkScalar sy : { -1, 0, 1 } ) {
1804 SkAutoCanvasRestore autoRestore(canvas, true);
1805 m.setSkew(sx, sy);
1806 m.postTranslate(96 + 64 * sx, 128 + 48 * sy);
1807 canvas->concat(m);
1808 canvas->drawString("K", 0, 0, p);
1809 }
1810 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001811##
1812
Cary Clark154beea2017-10-26 07:58:48 -04001813#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001814
Cary Clark154beea2017-10-26 07:58:48 -04001815#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001816
1817# ------------------------------------------------------------------------------
1818
1819#Method void setConcat(const SkMatrix& a, const SkMatrix& b)
Cary Clark4855f782018-02-06 09:41:53 -05001820#In Constructor
1821#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001822#Line # sets to Matrix parameter multiplied by Matrix parameter ##
Cary Clark154beea2017-10-26 07:58:48 -04001823Sets Matrix to Matrix a multiplied by Matrix b. Either a or b may be this.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001824
Cary Clark154beea2017-10-26 07:58:48 -04001825Given:
1826
1827#Code
1828#Literal
1829 | A B C | | J K L |
1830a = | D E F |, b = | M N O |
1831 | G H I | | P Q R |
1832##
1833
1834sets Matrix to:
1835
1836#Code
1837#Literal
1838 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
1839a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
1840 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
1841##
1842
1843#Param a Matrix on left side of multiply expression ##
1844#Param b Matrix on right side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001845
1846#Example
Cary Clark154beea2017-10-26 07:58:48 -04001847#Image 3
1848#Description
1849setPolyToPoly creates perspective matrices, one the inverse of the other.
1850Multiplying the matrix by its inverse turns into an identity matrix.
1851##
1852SkMatrix matrix, matrix2;
1853SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1854SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1855matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1856matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
1857matrix.setConcat(matrix, matrix2);
1858canvas->concat(matrix);
1859canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001860##
1861
Cary Clark154beea2017-10-26 07:58:48 -04001862#SeeAlso Concat preConcat postConcat SkCanvas::concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04001863
Cary Clark154beea2017-10-26 07:58:48 -04001864#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001865
1866# ------------------------------------------------------------------------------
1867
1868#Method void preTranslate(SkScalar dx, SkScalar dy)
Cary Clark4855f782018-02-06 09:41:53 -05001869#In Set
1870#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05001871#Line # pre-multiplies Matrix by translation ##
Cary Clark154beea2017-10-26 07:58:48 -04001872Sets Matrix to Matrix multiplied by Matrix constructed from translation (dx, dy).
1873This can be thought of as moving the point to be mapped before applying Matrix.
1874
1875Given:
1876
1877#Code
1878#Literal
1879 | A B C | | 1 0 dx |
1880Matrix = | D E F |, T(dx, dy) = | 0 1 dy |
1881 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001882##
1883
Cary Clark154beea2017-10-26 07:58:48 -04001884sets Matrix to:
1885
1886#Code
1887#Literal
1888 | A B C | | 1 0 dx | | A B A*dx+B*dy+C |
1889Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F |
1890 | G H I | | 0 0 1 | | G H G*dx+H*dy+I |
1891##
1892
1893#Param dx x translation before applying Matrix ##
1894#Param dy y translation before applying Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001895
1896#Example
Cary Clark154beea2017-10-26 07:58:48 -04001897#Height 160
1898 SkPaint paint;
1899 paint.setAntiAlias(true);
1900 SkRect rect = {20, 20, 100, 100};
1901 for (int i = 0; i < 2; ++i ) {
1902 SkMatrix matrix;
1903 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
1904 {
1905 SkAutoCanvasRestore acr(canvas, true);
1906 canvas->concat(matrix);
1907 paint.setColor(SK_ColorGRAY);
1908 canvas->drawRect(rect, paint);
1909 }
1910 paint.setColor(SK_ColorRED);
1911 for (int j = 0; j < 2; ++j ) {
1912 SkAutoCanvasRestore acr(canvas, true);
1913 matrix.preTranslate(40, 40);
1914 canvas->concat(matrix);
1915 canvas->drawCircle(0, 0, 3, paint);
1916 }
1917 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001918##
1919
Cary Clark154beea2017-10-26 07:58:48 -04001920#SeeAlso postTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001921
Cary Clark154beea2017-10-26 07:58:48 -04001922#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001923
1924# ------------------------------------------------------------------------------
1925
1926#Method void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001927#In Set
1928#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05001929#Line # pre-multiplies Matrix by scale ##
Cary Clark154beea2017-10-26 07:58:48 -04001930Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
1931about pivot point (px, py).
1932This can be thought of as scaling about a pivot point before applying Matrix.
1933
1934Given:
1935
1936#Code
1937#Literal
1938 | A B C | | sx 0 dx |
1939Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy |
1940 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001941##
1942
Cary Clark154beea2017-10-26 07:58:48 -04001943where
1944
1945#Code
1946#Literal
1947dx = px - sx * px
1948dy = py - sy * py
1949##
1950
1951sets Matrix to:
1952
1953#Code
1954#Literal
1955 | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C |
1956Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F |
1957 | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I |
1958##
1959
1960#Param sx horizontal scale factor ##
1961#Param sy vertical scale factor ##
1962#Param px pivot x ##
1963#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001964
1965#Example
Cary Clark154beea2017-10-26 07:58:48 -04001966#Image 3
1967SkMatrix matrix;
1968SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1969SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1970matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1971matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
1972canvas->concat(matrix);
1973canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001974##
1975
Cary Clark154beea2017-10-26 07:58:48 -04001976#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001977
Cary Clark154beea2017-10-26 07:58:48 -04001978#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001979
1980# ------------------------------------------------------------------------------
1981
1982#Method void preScale(SkScalar sx, SkScalar sy)
Cary Clark4855f782018-02-06 09:41:53 -05001983#In Set
1984#In Operator
Cary Clark154beea2017-10-26 07:58:48 -04001985Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
1986about pivot point (0, 0).
1987This can be thought of as scaling about the origin before applying Matrix.
1988
1989Given:
1990
1991#Code
1992#Literal
1993 | A B C | | sx 0 0 |
1994Matrix = | D E F |, S(sx, sy) = | 0 sy 0 |
1995 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001996##
1997
Cary Clark154beea2017-10-26 07:58:48 -04001998sets Matrix to:
1999
2000#Code
2001#Literal
2002 | A B C | | sx 0 0 | | A*sx B*sy C |
2003Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F |
2004 | G H I | | 0 0 1 | | G*sx H*sy I |
2005##
2006
2007#Param sx horizontal scale factor ##
2008#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002009
2010#Example
Cary Clark154beea2017-10-26 07:58:48 -04002011#Image 3
2012SkMatrix matrix;
2013SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2014SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2015matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2016matrix.preScale(.75f, 1.5f);
2017canvas->concat(matrix);
2018canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002019##
2020
Cary Clark154beea2017-10-26 07:58:48 -04002021#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002022
Cary Clark154beea2017-10-26 07:58:48 -04002023#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002024
2025# ------------------------------------------------------------------------------
2026
2027#Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05002028#In Set
2029#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002030#Line # pre-multiplies Matrix by rotation ##
Cary Clark154beea2017-10-26 07:58:48 -04002031Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
2032about pivot point (px, py).
2033This can be thought of as rotating about a pivot point before applying Matrix.
2034
2035Positive degrees rotates clockwise.
2036
2037Given:
2038
2039#Code
2040#Literal
2041 | A B C | | c -s dx |
2042Matrix = | D E F |, R(degrees, px, py) = | s c dy |
2043 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002044##
2045
Cary Clark154beea2017-10-26 07:58:48 -04002046where
2047
2048#Code
2049#Literal
2050c = cos(degrees)
2051s = sin(degrees)
2052dx = s * py + (1 - c) * px
2053dy = -s * px + (1 - c) * py
2054##
2055
2056sets Matrix to:
2057
2058#Code
2059#Literal
2060 | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C |
2061Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F |
2062 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I |
2063##
2064
2065#Param degrees angle of axes relative to upright axes ##
2066#Param px pivot x ##
2067#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002068
2069#Example
Cary Clark154beea2017-10-26 07:58:48 -04002070#Image 3
2071SkMatrix matrix;
2072SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2073SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2074matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2075matrix.preRotate(45, source.width() / 2, source.height() / 2);
2076canvas->concat(matrix);
2077canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002078##
2079
Cary Clark154beea2017-10-26 07:58:48 -04002080#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002081
Cary Clark154beea2017-10-26 07:58:48 -04002082#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002083
2084# ------------------------------------------------------------------------------
2085
2086#Method void preRotate(SkScalar degrees)
2087
Cary Clark154beea2017-10-26 07:58:48 -04002088Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
2089about pivot point (0, 0).
2090This can be thought of as rotating about the origin before applying Matrix.
2091
2092Positive degrees rotates clockwise.
2093
2094Given:
2095
2096#Code
2097#Literal
2098 | A B C | | c -s 0 |
2099Matrix = | D E F |, R(degrees, px, py) = | s c 0 |
2100 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002101##
2102
Cary Clark154beea2017-10-26 07:58:48 -04002103where
2104
2105#Code
2106#Literal
2107c = cos(degrees)
2108s = sin(degrees)
2109##
2110
2111sets Matrix to:
2112
2113#Code
2114#Literal
2115 | A B C | | c -s 0 | | Ac+Bs -As+Bc C |
2116Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F |
2117 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I |
2118##
2119
2120#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002121
2122#Example
Cary Clark154beea2017-10-26 07:58:48 -04002123#Image 3
2124SkMatrix matrix;
2125SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2126SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2127matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2128matrix.preRotate(45);
2129canvas->concat(matrix);
2130canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002131##
2132
Cary Clark154beea2017-10-26 07:58:48 -04002133#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002134
Cary Clark154beea2017-10-26 07:58:48 -04002135#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002136
2137# ------------------------------------------------------------------------------
2138
2139#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05002140#In Set
2141#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002142#Line # pre-multiplies Matrix by skew ##
Cary Clark154beea2017-10-26 07:58:48 -04002143Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
2144about pivot point (px, py).
2145This can be thought of as skewing about a pivot point before applying Matrix.
2146
2147Given:
2148
2149#Code
2150#Literal
2151 | A B C | | 1 kx dx |
2152Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy |
2153 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002154##
2155
Cary Clark154beea2017-10-26 07:58:48 -04002156where
2157
2158#Code
2159#Literal
2160dx = -kx * py
2161dy = -ky * px
2162##
2163
2164sets Matrix to:
2165
2166#Code
2167#Literal
2168 | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C |
2169Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F |
2170 | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I |
2171##
2172
2173#Param kx horizontal skew factor ##
2174#Param ky vertical skew factor ##
2175#Param px pivot x ##
2176#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002177
2178#Example
Cary Clark154beea2017-10-26 07:58:48 -04002179#Image 3
2180SkMatrix matrix;
2181SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2182SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2183matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2184matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2);
2185canvas->concat(matrix);
2186canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002187##
2188
Cary Clark154beea2017-10-26 07:58:48 -04002189#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002190
Cary Clark154beea2017-10-26 07:58:48 -04002191#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002192
2193# ------------------------------------------------------------------------------
2194
2195#Method void preSkew(SkScalar kx, SkScalar ky)
2196
Cary Clark154beea2017-10-26 07:58:48 -04002197Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
2198about pivot point (0, 0).
2199This can be thought of as skewing about the origin before applying Matrix.
2200
2201Given:
2202
2203#Code
2204#Literal
2205 | A B C | | 1 kx 0 |
2206Matrix = | D E F |, K(kx, ky) = | ky 1 0 |
2207 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002208##
2209
Cary Clark154beea2017-10-26 07:58:48 -04002210sets Matrix to:
2211
2212#Code
2213#Literal
2214 | A B C | | 1 kx 0 | | A+B*ky A*kx+B C |
2215Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F |
2216 | G H I | | 0 0 1 | | G+H*ky G*kx+H I |
2217##
2218
2219#Param kx horizontal skew factor ##
2220#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002221
2222#Example
Cary Clark154beea2017-10-26 07:58:48 -04002223#Image 3
2224SkMatrix matrix;
2225SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2226SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2227matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2228matrix.preSkew(.5f, 0);
2229canvas->concat(matrix);
2230canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002231##
2232
Cary Clark154beea2017-10-26 07:58:48 -04002233#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002234
Cary Clark154beea2017-10-26 07:58:48 -04002235#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002236
2237# ------------------------------------------------------------------------------
2238
2239#Method void preConcat(const SkMatrix& other)
Cary Clark4855f782018-02-06 09:41:53 -05002240#In Set
2241#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002242#Line # pre-multiplies Matrix by Matrix parameter ##
Cary Clark154beea2017-10-26 07:58:48 -04002243Sets Matrix to Matrix multiplied by Matrix other.
2244This can be thought of mapping by other before applying Matrix.
2245
2246Given:
2247
2248#Code
2249#Literal
2250 | A B C | | J K L |
2251Matrix = | D E F |, other = | M N O |
2252 | G H I | | P Q R |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002253##
2254
Cary Clark154beea2017-10-26 07:58:48 -04002255sets Matrix to:
2256
2257#Code
2258#Literal
2259 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
2260Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
2261 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
2262##
2263
2264#Param other Matrix on right side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002265
2266#Example
Cary Clark154beea2017-10-26 07:58:48 -04002267#Image 3
2268#Description
2269setPolyToPoly creates perspective matrices, one the inverse of the other.
2270Multiplying the matrix by its inverse turns into an identity matrix.
2271##
2272SkMatrix matrix, matrix2;
2273SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2274SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2275matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2276matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
2277matrix.preConcat(matrix2);
2278canvas->concat(matrix);
2279canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002280##
2281
Cary Clark154beea2017-10-26 07:58:48 -04002282#SeeAlso postConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002283
Cary Clark154beea2017-10-26 07:58:48 -04002284#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002285
2286# ------------------------------------------------------------------------------
2287
2288#Method void postTranslate(SkScalar dx, SkScalar dy)
Cary Clark4855f782018-02-06 09:41:53 -05002289#In Set
2290#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002291#Line # post-multiplies Matrix by translation ##
Cary Clark154beea2017-10-26 07:58:48 -04002292Sets Matrix to Matrix constructed from translation (dx, dy) multiplied by Matrix.
2293This can be thought of as moving the point to be mapped after applying Matrix.
2294
2295Given:
2296
2297#Code
2298#Literal
2299 | J K L | | 1 0 dx |
2300Matrix = | M N O |, T(dx, dy) = | 0 1 dy |
2301 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002302##
2303
Cary Clark154beea2017-10-26 07:58:48 -04002304sets Matrix to:
2305
2306#Code
2307#Literal
2308 | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R |
2309T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R |
2310 | 0 0 1 | | P Q R | | P Q R |
2311##
2312
2313#Param dx x translation after applying Matrix ##
2314#Param dy y translation after applying Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002315
2316#Example
Cary Clark154beea2017-10-26 07:58:48 -04002317#Height 160
2318#Description
2319Compare with preTranslate example.
2320##
2321 SkPaint paint;
2322 paint.setAntiAlias(true);
2323 SkRect rect = {20, 20, 100, 100};
2324 for (int i = 0; i < 2; ++i ) {
2325 SkMatrix matrix;
2326 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
2327 {
2328 SkAutoCanvasRestore acr(canvas, true);
2329 canvas->concat(matrix);
2330 paint.setColor(SK_ColorGRAY);
2331 canvas->drawRect(rect, paint);
2332 }
2333 paint.setColor(SK_ColorRED);
2334 for (int j = 0; j < 2; ++j ) {
2335 SkAutoCanvasRestore acr(canvas, true);
2336 matrix.postTranslate(40, 40);
2337 canvas->concat(matrix);
2338 canvas->drawCircle(0, 0, 3, paint);
2339 }
2340 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002341##
2342
Cary Clark154beea2017-10-26 07:58:48 -04002343#SeeAlso preTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04002344
Cary Clark154beea2017-10-26 07:58:48 -04002345#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002346
2347# ------------------------------------------------------------------------------
2348
2349#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05002350#In Set
2351#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002352#Line # post-multiplies Matrix by scale ##
Cary Clark154beea2017-10-26 07:58:48 -04002353Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
2354(px, py), multiplied by Matrix.
2355This can be thought of as scaling about a pivot point after applying Matrix.
2356
2357Given:
2358
2359#Code
2360#Literal
2361 | J K L | | sx 0 dx |
2362Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy |
2363 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002364##
2365
Cary Clark154beea2017-10-26 07:58:48 -04002366where
2367
2368#Code
2369#Literal
2370dx = px - sx * px
2371dy = py - sy * py
2372##
2373
2374sets Matrix to:
2375
2376#Code
2377#Literal
2378 | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R |
2379S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R |
2380 | 0 0 1 | | P Q R | | P Q R |
2381##
2382
2383#Param sx horizontal scale factor ##
2384#Param sy vertical scale factor ##
2385#Param px pivot x ##
2386#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002387
2388#Example
Cary Clark154beea2017-10-26 07:58:48 -04002389#Image 3
2390SkMatrix matrix;
2391SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2392SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2393matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2394matrix.postScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
2395canvas->concat(matrix);
2396canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002397##
2398
Cary Clark154beea2017-10-26 07:58:48 -04002399#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002400
2401##
2402
2403# ------------------------------------------------------------------------------
2404
2405#Method void postScale(SkScalar sx, SkScalar sy)
2406
Cary Clark154beea2017-10-26 07:58:48 -04002407Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
2408(0, 0), multiplied by Matrix.
2409This can be thought of as scaling about the origin after applying Matrix.
2410
2411Given:
2412
2413#Code
2414#Literal
2415 | J K L | | sx 0 0 |
2416Matrix = | M N O |, S(sx, sy) = | 0 sy 0 |
2417 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002418##
2419
Cary Clark154beea2017-10-26 07:58:48 -04002420sets Matrix to:
2421
2422#Code
2423#Literal
2424 | sx 0 0 | | J K L | | sx*J sx*K sx*L |
2425S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
2426 | 0 0 1 | | P Q R | | P Q R |
2427##
2428
2429#Param sx horizontal scale factor ##
2430#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002431
2432#Example
Cary Clark154beea2017-10-26 07:58:48 -04002433#Image 3
2434SkMatrix matrix;
2435SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2436SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2437matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2438matrix.postScale(.75f, 1.5f);
2439canvas->concat(matrix);
2440canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002441##
2442
Cary Clark154beea2017-10-26 07:58:48 -04002443#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002444
2445##
2446
2447# ------------------------------------------------------------------------------
2448
2449#Method bool postIDiv(int divx, int divy)
Cary Clark4855f782018-02-06 09:41:53 -05002450#In Set
2451#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002452#Line # post-multiplies Matrix by inverse scale ##
Cary Clark154beea2017-10-26 07:58:48 -04002453Sets Matrix to Matrix constructed from scaling by
Cary Clarkbc5697d2017-10-04 14:31:33 -04002454#Formula
Cary Clark154beea2017-10-26 07:58:48 -04002455(1/divx, 1/divy)
2456##
2457about pivot point (px, py), multiplied by Matrix.
2458
2459Returns false if either divx or divy is zero.
2460
2461Given:
2462
2463#Code
2464#Literal
2465 | J K L | | sx 0 0 |
2466Matrix = | M N O |, I(divx, divy) = | 0 sy 0 |
2467 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002468##
2469
Cary Clark154beea2017-10-26 07:58:48 -04002470where
Cary Clarkbc5697d2017-10-04 14:31:33 -04002471
Cary Clark154beea2017-10-26 07:58:48 -04002472#Code
2473#Literal
2474sx = 1 / divx
2475sy = 1 / divy
2476##
2477
2478sets Matrix to:
2479
2480#Code
2481#Literal
2482 | sx 0 0 | | J K L | | sx*J sx*K sx*L |
2483I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
2484 | 0 0 1 | | P Q R | | P Q R |
2485##
2486
2487#Param divx integer divisor for inverse scale in x ##
2488#Param divy integer divisor for inverse scale in y ##
2489
2490#Return true on successful scale ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002491
2492#Example
Cary Clark154beea2017-10-26 07:58:48 -04002493#Image 3
Cary Clark681287e2018-03-16 11:34:15 -04002494SkMatrix matrix;
Cary Clark154beea2017-10-26 07:58:48 -04002495SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2496SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2497matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2498matrix.postIDiv(1, 2);
2499canvas->concat(matrix);
2500canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002501##
2502
Cary Clark154beea2017-10-26 07:58:48 -04002503#SeeAlso postScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002504
2505##
2506
2507# ------------------------------------------------------------------------------
2508
2509#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05002510#In Set
2511#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002512#Line # post-multiplies Matrix by rotation ##
Cary Clark154beea2017-10-26 07:58:48 -04002513Sets Matrix to Matrix constructed from rotating by degrees about pivot point
2514(px, py), multiplied by Matrix.
2515This can be thought of as rotating about a pivot point after applying Matrix.
2516
2517Positive degrees rotates clockwise.
2518
2519Given:
2520
2521#Code
2522#Literal
2523 | J K L | | c -s dx |
2524Matrix = | M N O |, R(degrees, px, py) = | s c dy |
2525 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002526##
2527
Cary Clark154beea2017-10-26 07:58:48 -04002528where
2529
2530#Code
2531#Literal
2532c = cos(degrees)
2533s = sin(degrees)
2534dx = s * py + (1 - c) * px
2535dy = -s * px + (1 - c) * py
2536##
2537
2538sets Matrix to:
2539
2540#Code
2541#Literal
2542 |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R|
2543R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R|
2544 |0 0 1| |P Q R| | P Q R|
2545##
2546
2547#Param degrees angle of axes relative to upright axes ##
2548#Param px pivot x ##
2549#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002550
2551#Example
Cary Clark154beea2017-10-26 07:58:48 -04002552#Image 3
2553SkMatrix matrix;
2554SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2555SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2556matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2557matrix.postRotate(45, source.width() / 2, source.height() / 2);
2558canvas->concat(matrix);
2559canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002560##
2561
Cary Clark154beea2017-10-26 07:58:48 -04002562#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002563
2564##
2565
2566# ------------------------------------------------------------------------------
2567
2568#Method void postRotate(SkScalar degrees)
2569
Cary Clark154beea2017-10-26 07:58:48 -04002570Sets Matrix to Matrix constructed from rotating by degrees about pivot point
2571(0, 0), multiplied by Matrix.
2572This can be thought of as rotating about the origin after applying Matrix.
2573
2574Positive degrees rotates clockwise.
2575
2576Given:
2577
2578#Code
2579#Literal
2580 | J K L | | c -s 0 |
2581Matrix = | M N O |, R(degrees, px, py) = | s c 0 |
2582 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002583##
2584
Cary Clark154beea2017-10-26 07:58:48 -04002585where
2586
2587#Code
2588#Literal
2589c = cos(degrees)
2590s = sin(degrees)
2591##
2592
2593sets Matrix to:
2594
2595#Code
2596#Literal
2597 | c -s dx | | J K L | | cJ-sM cK-sN cL-sO |
2598R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO |
2599 | 0 0 1 | | P Q R | | P Q R |
2600##
2601
2602#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002603
2604#Example
Cary Clark154beea2017-10-26 07:58:48 -04002605#Image 3
2606SkMatrix matrix;
2607SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2608SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2609matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2610matrix.postRotate(45);
2611canvas->concat(matrix);
2612canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002613##
2614
Cary Clark154beea2017-10-26 07:58:48 -04002615#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002616
2617##
2618
2619# ------------------------------------------------------------------------------
2620
2621#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05002622#In Set
2623#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002624#Line # post-multiplies Matrix by skew ##
Cary Clark154beea2017-10-26 07:58:48 -04002625Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
2626(px, py), multiplied by Matrix.
2627This can be thought of as skewing about a pivot point after applying Matrix.
2628
2629Given:
2630
2631#Code
2632#Literal
2633 | J K L | | 1 kx dx |
2634Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy |
2635 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002636##
2637
Cary Clark154beea2017-10-26 07:58:48 -04002638where
2639
2640#Code
2641#Literal
2642dx = -kx * py
2643dy = -ky * px
2644##
2645
2646sets Matrix to:
2647
2648#Code
2649#Literal
2650 | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R|
2651K(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|
2652 | 0 0 1| |P Q R| | P Q R|
2653##
2654
2655#Param kx horizontal skew factor ##
2656#Param ky vertical skew factor ##
2657#Param px pivot x ##
2658#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002659
2660#Example
Cary Clark154beea2017-10-26 07:58:48 -04002661#Image 3
2662SkMatrix matrix;
2663SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2664SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2665matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2666matrix.postSkew(.5f, 0, source.width() / 2, source.height() / 2);
2667canvas->concat(matrix);
2668canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002669##
2670
Cary Clark154beea2017-10-26 07:58:48 -04002671#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002672
2673##
2674
2675# ------------------------------------------------------------------------------
2676
2677#Method void postSkew(SkScalar kx, SkScalar ky)
2678
Cary Clark154beea2017-10-26 07:58:48 -04002679Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
2680(0, 0), multiplied by Matrix.
2681This can be thought of as skewing about the origin after applying Matrix.
2682
2683Given:
2684
2685#Code
2686#Literal
2687 | J K L | | 1 kx 0 |
2688Matrix = | M N O |, K(kx, ky) = | ky 1 0 |
2689 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002690##
2691
Cary Clark154beea2017-10-26 07:58:48 -04002692sets Matrix to:
2693
2694#Code
2695#Literal
2696 | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O |
2697K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O |
2698 | 0 0 1 | | P Q R | | P Q R |
2699##
2700
2701#Param kx horizontal skew factor ##
2702#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002703
2704#Example
Cary Clark154beea2017-10-26 07:58:48 -04002705#Image 3
2706SkMatrix matrix;
2707SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2708SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2709matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2710matrix.postSkew(.5f, 0);
2711canvas->concat(matrix);
2712canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002713##
2714
Cary Clark154beea2017-10-26 07:58:48 -04002715#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002716
2717##
2718
2719# ------------------------------------------------------------------------------
2720
2721#Method void postConcat(const SkMatrix& other)
Cary Clark4855f782018-02-06 09:41:53 -05002722#In Set
2723#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002724#Line # post-multiplies Matrix by Matrix parameter ##
Cary Clark154beea2017-10-26 07:58:48 -04002725Sets Matrix to Matrix other multiplied by Matrix.
2726This can be thought of mapping by other after applying Matrix.
2727
2728Given:
2729
2730#Code
2731#Literal
2732 | J K L | | A B C |
2733Matrix = | M N O |, other = | D E F |
2734 | P Q R | | G H I |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002735##
2736
Cary Clark154beea2017-10-26 07:58:48 -04002737sets Matrix to:
2738
2739#Code
2740#Literal
2741 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
2742other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
2743 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
2744##
2745
2746#Param other Matrix on left side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002747
2748#Example
Cary Clark154beea2017-10-26 07:58:48 -04002749#Image 3
2750#Height 64
Cary Clark681287e2018-03-16 11:34:15 -04002751SkMatrix matrix;
Cary Clark154beea2017-10-26 07:58:48 -04002752SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2753SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2754matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2755matrix.postConcat(matrix);
2756canvas->concat(matrix);
2757canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002758##
2759
Cary Clark154beea2017-10-26 07:58:48 -04002760#SeeAlso preConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002761
2762##
2763
2764# ------------------------------------------------------------------------------
2765
2766#Enum ScaleToFit
2767
2768#Code
2769 enum ScaleToFit {
2770 kFill_ScaleToFit,
2771 kStart_ScaleToFit,
2772 kCenter_ScaleToFit,
2773 kEnd_ScaleToFit,
2774 };
2775##
2776
Cary Clark154beea2017-10-26 07:58:48 -04002777ScaleToFit describes how Matrix is constructed to map one Rect to another.
2778ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling,
2779or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies
2780how Matrix maps to the side or center of the destination Rect.
2781
2782#Const kFill_ScaleToFit 0
2783 Computes Matrix that scales in x and y independently, so that source Rect is
2784 mapped to completely fill destination Rect. The aspect ratio of source Rect
2785 may change.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002786##
Cary Clark154beea2017-10-26 07:58:48 -04002787#Const kStart_ScaleToFit 1
2788 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2789 width or height to destination Rect. Aligns mapping to left and top edges
2790 of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002791##
Cary Clark154beea2017-10-26 07:58:48 -04002792#Const kCenter_ScaleToFit 2
2793 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2794 width or height to destination Rect. Aligns mapping to center of destination
2795 Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002796##
Cary Clark154beea2017-10-26 07:58:48 -04002797#Const kEnd_ScaleToFit 3
2798 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2799 width or height to destination Rect. Aligns mapping to right and bottom
2800 edges of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002801##
2802
2803#Example
Cary Clark154beea2017-10-26 07:58:48 -04002804 const char* labels[] = { "Fill", "Start", "Center", "End" };
2805 SkRect rects[] = {{5, 5, 59, 59}, {5, 74, 59, 108}, {10, 123, 44, 172}, {10, 187, 54, 231}};
2806 SkRect bounds;
2807 source.getBounds(&bounds);
2808 SkPaint paint;
2809 paint.setAntiAlias(true);
2810 for (auto fit : { SkMatrix::kFill_ScaleToFit, SkMatrix::kStart_ScaleToFit,
2811 SkMatrix::kCenter_ScaleToFit, SkMatrix::kEnd_ScaleToFit } ) {
2812 for (auto rect : rects ) {
2813 canvas->drawRect(rect, paint);
2814 SkMatrix matrix;
2815 if (!matrix.setRectToRect(bounds, rect, fit)) {
2816 continue;
2817 }
2818 SkAutoCanvasRestore acr(canvas, true);
2819 canvas->concat(matrix);
2820 canvas->drawBitmap(source, 0, 0);
2821 }
2822 canvas->drawString(labels[fit], 10, 255, paint);
2823 canvas->translate(64, 0);
2824 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002825##
2826
Cary Clark154beea2017-10-26 07:58:48 -04002827#SeeAlso setRectToRect MakeRectToRect setPolyToPoly
Cary Clarkbc5697d2017-10-04 14:31:33 -04002828
2829##
2830
2831# ------------------------------------------------------------------------------
2832
2833#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
Cary Clark4855f782018-02-06 09:41:53 -05002834#In Set
Cary Clark08895c42018-02-01 09:37:32 -05002835#Line # sets to map one Rect to another ##
Cary Clark154beea2017-10-26 07:58:48 -04002836Sets Matrix to scale and translate src Rect to dst Rect. stf selects whether
2837mapping completely fills dst or preserves the aspect ratio, and how to align
2838src within dst. Returns false if src is empty, and sets Matrix to identity.
2839Returns true if dst is empty, and sets Matrix to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04002840
Cary Clark154beea2017-10-26 07:58:48 -04002841#Code
2842#Literal
2843| 0 0 0 |
2844| 0 0 0 |
2845| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002846##
2847
Cary Clark154beea2017-10-26 07:58:48 -04002848#Param src Rect to map from ##
2849#Param dst Rect to map to ##
2850#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
2851 kCenter_ScaleToFit, kEnd_ScaleToFit
Cary Clarkbc5697d2017-10-04 14:31:33 -04002852##
2853
Cary Clark154beea2017-10-26 07:58:48 -04002854#Return true if Matrix can represent Rect mapping ##
2855
Cary Clarkbc5697d2017-10-04 14:31:33 -04002856#Example
Cary Clark154beea2017-10-26 07:58:48 -04002857 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
2858 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
2859 for (auto src : srcs) {
2860 for (auto dst : dsts) {
2861 SkMatrix matrix;
2862 matrix.setAll(-1, -1, -1, -1, -1, -1, -1, -1, -1);
2863 bool success = matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
2864 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g success: %s\n",
2865 src.fLeft, src.fTop, src.fRight, src.fBottom,
2866 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, success ? "true" : "false");
2867 matrix.dump();
2868 }
2869 }
2870#StdOut
2871src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false
2872[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2873src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false
2874[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2875src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true
2876[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2877src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true
2878[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
2879##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002880##
2881
Cary Clark154beea2017-10-26 07:58:48 -04002882#SeeAlso MakeRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04002883
2884##
2885
2886# ------------------------------------------------------------------------------
2887
2888#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
Cary Clark4855f782018-02-06 09:41:53 -05002889#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -05002890#Line # constructs from source Rect to destination Rect ##
Cary Clark154beea2017-10-26 07:58:48 -04002891Returns Matrix set to scale and translate src Rect to dst Rect. stf selects
2892whether mapping completely fills dst or preserves the aspect ratio, and how to
2893align src within dst. Returns the identity Matrix if src is empty. If dst is
2894empty, returns Matrix set to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04002895
Cary Clark154beea2017-10-26 07:58:48 -04002896#Code
2897#Literal
2898| 0 0 0 |
2899| 0 0 0 |
2900| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002901##
2902
Cary Clark154beea2017-10-26 07:58:48 -04002903#Param src Rect to map from ##
2904#Param dst Rect to map to ##
2905#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
2906 kCenter_ScaleToFit, kEnd_ScaleToFit
2907##
2908
2909#Return Matrix mapping src to dst ##
2910
2911#Example
2912 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
2913 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
2914 for (auto src : srcs) {
2915 for (auto dst : dsts) {
2916 SkMatrix matrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
2917 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g\n",
2918 src.fLeft, src.fTop, src.fRight, src.fBottom,
2919 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom);
2920 matrix.dump();
2921 }
2922 }
2923#StdOut
2924src: 0, 0, 0, 0 dst: 0, 0, 0, 0
2925[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2926src: 0, 0, 0, 0 dst: 5, 6, 8, 9
2927[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2928src: 1, 2, 3, 4 dst: 0, 0, 0, 0
2929[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2930src: 1, 2, 3, 4 dst: 5, 6, 8, 9
2931[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
2932##
2933##
2934
2935#SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04002936
2937##
2938
2939# ------------------------------------------------------------------------------
2940
2941#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
Cary Clark4855f782018-02-06 09:41:53 -05002942#In Set
Cary Clark08895c42018-02-01 09:37:32 -05002943#Line # sets to map one to four points to an equal array of points ##
Cary Clark154beea2017-10-26 07:58:48 -04002944Sets Matrix to map src to dst. count must be zero or greater, and four or less.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002945
Cary Clark154beea2017-10-26 07:58:48 -04002946If count is zero, sets Matrix to identity and returns true.
2947If count is one, sets Matrix to translate and returns true.
2948If count is two or more, sets Matrix to map Points if possible; returns false
2949if Matrix cannot be constructed. If count is four, Matrix may include
2950perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002951
Cary Clark154beea2017-10-26 07:58:48 -04002952#Param src Points to map from ##
2953#Param dst Points to map to ##
2954#Param count number of Points in src and dst ##
2955
2956#Return true if Matrix was constructed successfully
Cary Clarkbc5697d2017-10-04 14:31:33 -04002957##
2958
2959#Example
Cary Clark154beea2017-10-26 07:58:48 -04002960 const SkPoint src[] = { { 0, 0}, {30, 0}, {30, -30}, { 0, -30} };
2961 const SkPoint dst[] = { {50, 0}, {80, -10}, {90, -30}, {60, -40} };
2962 SkPaint blackPaint;
2963 blackPaint.setAntiAlias(true);
2964 blackPaint.setTextSize(42);
2965 SkPaint redPaint = blackPaint;
2966 redPaint.setColor(SK_ColorRED);
2967 for (int count : { 1, 2, 3, 4 } ) {
2968 canvas->translate(35, 55);
2969 for (int index = 0; index < count; ++index) {
2970 canvas->drawCircle(src[index], 3, blackPaint);
2971 canvas->drawCircle(dst[index], 3, blackPaint);
2972 if (index > 0) {
2973 canvas->drawLine(src[index], src[index - 1], blackPaint);
2974 canvas->drawLine(dst[index], dst[index - 1], blackPaint);
2975 }
2976 }
2977 SkMatrix matrix;
2978 matrix.setPolyToPoly(src, dst, count);
2979 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
2980 SkAutoCanvasRestore acr(canvas, true);
2981 canvas->concat(matrix);
2982 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
2983 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002984##
2985
Cary Clark154beea2017-10-26 07:58:48 -04002986#SeeAlso setRectToRect MakeRectToRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04002987
2988##
2989
2990# ------------------------------------------------------------------------------
2991
2992#Method bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const
Cary Clark4855f782018-02-06 09:41:53 -05002993#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05002994#Line # returns inverse, if possible ##
Cary Clark154beea2017-10-26 07:58:48 -04002995Sets inverse to reciprocal matrix, returning true if Matrix can be inverted.
2996Geometrically, if Matrix maps from source to destination, inverse Matrix
2997maps from destination to source. If Matrix can not be inverted, inverse is
2998unchanged.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002999
Cary Clark154beea2017-10-26 07:58:48 -04003000#Param inverse storage for inverted Matrix; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003001
Cary Clark154beea2017-10-26 07:58:48 -04003002#Return true if Matrix can be inverted ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003003
3004#Example
Cary Clark154beea2017-10-26 07:58:48 -04003005#Height 128
3006 const SkPoint src[] = { { 10, 120}, {120, 120}, {120, 10}, { 10, 10} };
3007 const SkPoint dst[] = { {150, 120}, {200, 100}, {240, 30}, { 130, 40} };
3008 SkPaint paint;
3009 paint.setAntiAlias(true);
3010 SkMatrix matrix;
3011 matrix.setPolyToPoly(src, dst, 4);
3012 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, src, paint);
3013 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, dst, paint);
3014 paint.setColor(SK_ColorBLUE);
3015 paint.setStrokeWidth(3);
3016 paint.setStrokeCap(SkPaint::kRound_Cap);
3017 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
Cary Clark681287e2018-03-16 11:34:15 -04003018 if (matrix.invert(&matrix)) {
3019 canvas->concat(matrix);
3020 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
3021 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003022##
3023
Cary Clark154beea2017-10-26 07:58:48 -04003024#SeeAlso Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04003025
3026##
3027
3028# ------------------------------------------------------------------------------
3029
3030#Method static void SetAffineIdentity(SkScalar affine[6])
Cary Clark4855f782018-02-06 09:41:53 -05003031#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -05003032#Line # sets 3x2 array to identity ##
Cary Clark154beea2017-10-26 07:58:48 -04003033Fills affine with identity values in column major order.
3034Sets affine to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003035
Cary Clark154beea2017-10-26 07:58:48 -04003036#Code
3037#Literal
3038| 1 0 0 |
3039| 0 1 0 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003040##
3041
Cary Clark154beea2017-10-26 07:58:48 -04003042Affine 3x2 matrices in column major order are used by OpenGL and XPS.
3043
3044#Param affine storage for 3x2 affine matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003045
3046#Example
Cary Clark154beea2017-10-26 07:58:48 -04003047 SkScalar affine[6];
3048 SkMatrix::SetAffineIdentity(affine);
3049 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3050 for (int i = 0; i < 6; ++i) {
3051 SkDebugf("%s: %g ", names[i], affine[i]);
3052 }
3053 SkDebugf("\n");
3054#StdOut
3055ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0
3056##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003057##
3058
Cary Clark154beea2017-10-26 07:58:48 -04003059#SeeAlso setAffine asAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -04003060
3061##
3062
3063# ------------------------------------------------------------------------------
3064
3065#Method bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const
Cary Clark4855f782018-02-06 09:41:53 -05003066#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -05003067#Line # copies to 3x2 array ##
Cary Clark154beea2017-10-26 07:58:48 -04003068Fills affine in column major order. Sets affine to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003069
Cary Clark154beea2017-10-26 07:58:48 -04003070#Code
3071#Literal
3072| scale-x skew-x translate-x |
3073| skew-y scale-y translate-y |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003074##
3075
Cary Clark154beea2017-10-26 07:58:48 -04003076If Matrix contains perspective, returns false and leaves affine unchanged.
3077
3078#Param affine storage for 3x2 affine matrix; may be nullptr ##
3079
3080#Return true if Matrix does not contain perspective ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003081
3082#Example
Cary Clark154beea2017-10-26 07:58:48 -04003083SkMatrix matrix;
3084matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
3085SkScalar affine[6];
Cary Clark681287e2018-03-16 11:34:15 -04003086if (matrix.asAffine(affine)) {
3087 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3088 for (int i = 0; i < 6; ++i) {
3089 SkDebugf("%s: %g ", names[i], affine[i]);
3090 }
3091 SkDebugf("\n");
Cary Clark154beea2017-10-26 07:58:48 -04003092}
Cary Clark154beea2017-10-26 07:58:48 -04003093#StdOut
3094ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
3095##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003096##
3097
Cary Clark154beea2017-10-26 07:58:48 -04003098#SeeAlso setAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04003099
3100##
3101
3102# ------------------------------------------------------------------------------
3103
3104#Method void setAffine(const SkScalar affine[6])
Cary Clark4855f782018-02-06 09:41:53 -05003105#In Constructor
3106#In Set
Cary Clark08895c42018-02-01 09:37:32 -05003107#Line # sets left two columns ##
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];
Cary Clark681287e2018-03-16 11:34:15 -04003132if (matrix.asAffine(affine)) {
3133 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3134 for (int i = 0; i < 6; ++i) {
3135 SkDebugf("%s: %g ", names[i], affine[i]);
3136 }
3137 SkDebugf("\n");
3138 matrix.reset();
3139 matrix.setAffine(affine);
3140 matrix.dump();
Cary Clark154beea2017-10-26 07:58:48 -04003141}
Cary Clark154beea2017-10-26 07:58:48 -04003142#StdOut
3143ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
3144[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000]
3145##
3146##
3147
3148#SeeAlso asAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04003149
3150##
3151
3152# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05003153#Subtopic Transform
3154#Populate
3155#Line # map points with Matrix ##
3156##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003157
3158#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Cary Clark4855f782018-02-06 09:41:53 -05003159#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003160#Line # maps Point array ##
Cary Clark154beea2017-10-26 07:58:48 -04003161Maps src Point array of length count to dst Point array of equal or greater
3162length. Points are mapped by multiplying each Point by Matrix. Given:
3163
3164#Code
3165#Literal
3166 | A B C | | x |
3167Matrix = | D E F |, pt = | y |
3168 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003169##
3170
Cary Clark154beea2017-10-26 07:58:48 -04003171where
3172
3173#Code
3174#Literal
3175for (i = 0; i < count; ++i) {
3176 x = src[i].fX
3177 y = src[i].fY
3178}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003179##
Cary Clark154beea2017-10-26 07:58:48 -04003180
3181each dst Point is computed as:
3182
3183#Code
3184#Literal
3185 |A B C| |x| Ax+By+C Dx+Ey+F
3186Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3187 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003188##
Cary Clark154beea2017-10-26 07:58:48 -04003189
3190src and dst may point to the same storage.
3191
3192#Param dst storage for mapped Points ##
3193#Param src Points to transform ##
3194#Param count number of Points to transform ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003195
3196#Example
Cary Clark154beea2017-10-26 07:58:48 -04003197 SkMatrix matrix;
3198 matrix.reset();
3199 const int count = 4;
3200 SkPoint src[count];
3201 matrix.mapRectToQuad(src, {40, 70, 180, 220} );
3202 SkPaint paint;
3203 paint.setARGB(77, 23, 99, 154);
3204 for (int i = 0; i < 5; ++i) {
3205 SkPoint dst[count];
3206 matrix.mapPoints(dst, src, count);
3207 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, dst, paint);
3208 matrix.preRotate(35, 128, 128);
3209 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003210##
3211
Brian Salomonfa3783f2018-01-05 13:49:07 -05003212#SeeAlso mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003213
3214##
3215
3216# ------------------------------------------------------------------------------
3217
3218#Method void mapPoints(SkPoint pts[], int count) const
3219
Cary Clark154beea2017-10-26 07:58:48 -04003220Maps pts Point array of length count in place. Points are mapped by multiplying
3221each Point by Matrix. Given:
3222
3223#Code
3224#Literal
3225 | A B C | | x |
3226Matrix = | D E F |, pt = | y |
3227 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003228##
3229
Cary Clark154beea2017-10-26 07:58:48 -04003230where
3231
3232#Code
3233#Literal
3234for (i = 0; i < count; ++i) {
3235 x = pts[i].fX
3236 y = pts[i].fY
3237}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003238##
Cary Clark154beea2017-10-26 07:58:48 -04003239
3240each resulting pts Point is computed as:
3241
3242#Code
3243#Literal
3244 |A B C| |x| Ax+By+C Dx+Ey+F
3245Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3246 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003247##
3248
Cary Clark154beea2017-10-26 07:58:48 -04003249#Param pts storage for mapped Points ##
3250#Param count number of Points to transform ##
3251
Cary Clarkbc5697d2017-10-04 14:31:33 -04003252#Example
Cary Clark154beea2017-10-26 07:58:48 -04003253 SkMatrix matrix;
3254 matrix.setRotate(35, 128, 128);
3255 const int count = 4;
3256 SkPoint pts[count];
3257 matrix.mapRectToQuad(pts, {40, 70, 180, 220} );
3258 SkPaint paint;
3259 paint.setARGB(77, 23, 99, 154);
3260 for (int i = 0; i < 5; ++i) {
3261 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, pts, paint);
3262 matrix.mapPoints(pts, count);
3263 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003264##
3265
Brian Salomonfa3783f2018-01-05 13:49:07 -05003266#SeeAlso mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003267
3268##
3269
3270# ------------------------------------------------------------------------------
3271
Cary Clark154beea2017-10-26 07:58:48 -04003272#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
Cary Clark4855f782018-02-06 09:41:53 -05003273#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003274#Line # maps Point3 array ##
Cary Clark154beea2017-10-26 07:58:48 -04003275Maps src Point3 array of length count to dst Point3 array, which must of length count or
3276greater. Point3 array is mapped by multiplying each Point3 by Matrix. Given:
3277
3278#Code
3279#Literal
3280 | A B C | | x |
3281Matrix = | D E F |, src = | y |
3282 | G H I | | z |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003283##
3284
Cary Clark154beea2017-10-26 07:58:48 -04003285each resulting dst Point is computed as:
3286
3287#Code
3288#Literal
3289 |A B C| |x|
3290Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz|
3291 |G H I| |z|
Cary Clarkbc5697d2017-10-04 14:31:33 -04003292##
Cary Clark154beea2017-10-26 07:58:48 -04003293
3294#Param dst storage for mapped Point3 array ##
3295#Param src Point3 array to transform ##
3296#Param count items in Point3 array to transform ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003297
3298#Example
Cary Clark154beea2017-10-26 07:58:48 -04003299 SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3},
3300 {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}};
3301 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 };
3302 constexpr int count = SK_ARRAY_COUNT(src);
3303 auto debugster = [=](SkPoint3 src[]) -> void {
3304 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) {
3305 const SkPoint3& s = src[lines[i]];
3306 const SkPoint3& e = src[lines[i + 1]];
3307 SkPaint paint;
3308 paint.setARGB(77, 23, 99, 154);
3309 canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint);
3310 }
3311 };
3312 canvas->save();
3313 canvas->translate(5, 5);
3314 canvas->scale(15, 15);
3315 debugster(src);
3316 canvas->restore();
3317 canvas->translate(128, 128);
3318 SkMatrix matrix;
3319 matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1);
Cary Clarka560c472017-11-27 10:44:06 -05003320 matrix.mapHomogeneousPoints(src, src, count);
Cary Clark154beea2017-10-26 07:58:48 -04003321 debugster(src);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003322##
3323
Brian Salomonfa3783f2018-01-05 13:49:07 -05003324#SeeAlso mapPoints mapXY mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003325
3326##
3327
3328# ------------------------------------------------------------------------------
3329
3330#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const
Cary Clark4855f782018-02-06 09:41:53 -05003331#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003332#Line # maps Point ##
Cary Clark154beea2017-10-26 07:58:48 -04003333Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003334
Cary Clark154beea2017-10-26 07:58:48 -04003335#Code
3336#Literal
3337 | A B C | | x |
3338Matrix = | D E F |, pt = | y |
3339 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003340##
3341
Cary Clark154beea2017-10-26 07:58:48 -04003342result is computed as:
3343
3344#Code
3345#Literal
3346 |A B C| |x| Ax+By+C Dx+Ey+F
3347Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3348 |G H I| |1| Gx+Hy+I Gx+Hy+I
3349##
3350
3351#Param x x-coordinate of Point to map ##
3352#Param y y-coordinate of Point to map ##
3353#Param result storage for mapped Point ##
3354
3355#Example
3356 SkPaint paint;
3357 paint.setAntiAlias(true);
3358 SkMatrix matrix;
3359 matrix.setRotate(60, 128, 128);
3360 SkPoint lines[] = {{50, 50}, {150, 50}, {150, 150}};
3361 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); ++i) {
3362 SkPoint pt;
3363 matrix.mapXY(lines[i].fX, lines[i].fY, &pt);
3364 canvas->drawCircle(pt.fX, pt.fY, 3, paint);
3365 }
3366 canvas->concat(matrix);
3367 canvas->drawPoints(SkCanvas::kPolygon_PointMode, SK_ARRAY_COUNT(lines), lines, paint);
3368##
3369
Brian Salomonfa3783f2018-01-05 13:49:07 -05003370#SeeAlso mapPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003371
3372##
3373
3374# ------------------------------------------------------------------------------
3375
3376#Method SkPoint mapXY(SkScalar x, SkScalar y) const
3377
Cary Clark154beea2017-10-26 07:58:48 -04003378Returns Point (x, y) multiplied by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003379
Cary Clark154beea2017-10-26 07:58:48 -04003380#Code
3381#Literal
3382 | A B C | | x |
3383Matrix = | D E F |, pt = | y |
3384 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003385##
3386
Cary Clark154beea2017-10-26 07:58:48 -04003387result is computed as:
3388
3389#Code
3390#Literal
3391 |A B C| |x| Ax+By+C Dx+Ey+F
3392Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3393 |G H I| |1| Gx+Hy+I Gx+Hy+I
3394##
3395
3396#Param x x-coordinate of Point to map ##
3397#Param y y-coordinate of Point to map ##
3398
3399#Return mapped Point ##
3400
3401#Example
3402#Image 4
3403SkMatrix matrix;
3404SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {30, 206}};
3405SkRect::Make(source.bounds()).toQuad(bitmapBounds);
3406matrix.setPolyToPoly(bitmapBounds, perspect, 4);
3407SkPaint paint;
3408paint.setAntiAlias(true);
3409paint.setStrokeWidth(3);
3410for (int x : { 0, source.width() } ) {
3411 for (int y : { 0, source.height() } ) {
3412 canvas->drawPoint(matrix.mapXY(x, y), paint);
3413 }
3414}
3415canvas->concat(matrix);
3416canvas->drawBitmap(source, 0, 0);
3417##
3418
Brian Salomonfa3783f2018-01-05 13:49:07 -05003419#SeeAlso mapPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003420
3421##
3422
3423# ------------------------------------------------------------------------------
3424
3425#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const
Cary Clark4855f782018-02-06 09:41:53 -05003426#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003427#Line # maps Vector array ##
Cary Clark154beea2017-10-26 07:58:48 -04003428Maps src Vector array of length count to Vector Point array of equal or greater
3429length. Vectors are mapped by multiplying each Vector by Matrix, treating
3430Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003431
Cary Clark154beea2017-10-26 07:58:48 -04003432#Code
3433#Literal
3434 | A B 0 | | x |
3435Matrix = | D E 0 |, src = | y |
3436 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003437##
Cary Clark154beea2017-10-26 07:58:48 -04003438
3439where
3440
3441#Code
3442#Literal
3443for (i = 0; i < count; ++i) {
3444 x = src[i].fX
3445 y = src[i].fY
3446}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003447##
Cary Clark154beea2017-10-26 07:58:48 -04003448
3449each dst Vector is computed as:
3450
3451#Code
3452#Literal
3453 |A B 0| |x| Ax+By Dx+Ey
3454Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
3455 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003456##
3457
Cary Clark154beea2017-10-26 07:58:48 -04003458src and dst may point to the same storage.
3459
3460#Param dst storage for mapped Vectors ##
3461#Param src Vectors to transform ##
3462#Param count number of Vectors to transform ##
3463
Cary Clarkbc5697d2017-10-04 14:31:33 -04003464#Example
Cary Clark154beea2017-10-26 07:58:48 -04003465 SkPaint paint;
3466 paint.setAntiAlias(true);
3467 paint.setStyle(SkPaint::kStroke_Style);
3468 SkMatrix matrix;
3469 matrix.reset();
3470 const SkVector radii[] = {{8, 4}, {9, 1}, {6, 2}, {7, 3}};
3471 for (int i = 0; i < 4; ++i) {
3472 SkVector rScaled[4];
3473 matrix.preScale(1.5f, 2.f);
3474 matrix.mapVectors(rScaled, radii, SK_ARRAY_COUNT(radii));
3475 SkRRect rrect;
3476 rrect.setRectRadii({20, 20, 180, 70}, rScaled);
3477 canvas->drawRRect(rrect, paint);
3478 canvas->translate(0, 60);
3479 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003480##
3481
Brian Salomonfa3783f2018-01-05 13:49:07 -05003482#SeeAlso mapVector mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003483
3484##
3485
3486# ------------------------------------------------------------------------------
3487
3488#Method void mapVectors(SkVector vecs[], int count) const
3489
Cary Clark154beea2017-10-26 07:58:48 -04003490Maps vecs Vector array of length count in place, multiplying each Vector by
3491Matrix, treating Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003492
Cary Clark154beea2017-10-26 07:58:48 -04003493#Code
3494#Literal
3495 | A B 0 | | x |
3496Matrix = | D E 0 |, vec = | y |
3497 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003498##
Cary Clark154beea2017-10-26 07:58:48 -04003499
3500where
3501
3502#Code
3503#Literal
3504for (i = 0; i < count; ++i) {
3505 x = vecs[i].fX
3506 y = vecs[i].fY
3507}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003508##
3509
Cary Clark154beea2017-10-26 07:58:48 -04003510each result Vector is computed as:
3511
3512#Code
3513#Literal
3514 |A B 0| |x| Ax+By Dx+Ey
3515Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
3516 |G H I| |1| Gx+Hy+I Gx+Hy+I
3517##
3518
3519#Param vecs Vectors to transform, and storage for mapped Vectors ##
3520#Param count number of Vectors to transform ##
3521
Cary Clarkbc5697d2017-10-04 14:31:33 -04003522#Example
Cary Clark154beea2017-10-26 07:58:48 -04003523 SkPaint paint;
3524 paint.setAntiAlias(true);
3525 paint.setStyle(SkPaint::kStroke_Style);
3526 SkMatrix matrix;
3527 matrix.setScale(2, 3);
3528 SkVector radii[] = {{7, 7}, {3, 3}, {2, 2}, {4, 0}};
3529 for (int i = 0; i < 4; ++i) {
3530 SkRRect rrect;
3531 rrect.setRectRadii({20, 20, 180, 70}, radii);
3532 canvas->drawRRect(rrect, paint);
3533 canvas->translate(0, 60);
3534 matrix.mapVectors(radii, SK_ARRAY_COUNT(radii));
3535 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003536##
3537
Brian Salomonfa3783f2018-01-05 13:49:07 -05003538#SeeAlso mapVector mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003539
3540##
3541
3542# ------------------------------------------------------------------------------
3543
3544#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const
Cary Clark4855f782018-02-06 09:41:53 -05003545#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003546#Line # maps Vector ##
Cary Clark154beea2017-10-26 07:58:48 -04003547Maps Vector (x, y) to result. Vector is mapped by multiplying by Matrix,
3548treating Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003549
Cary Clark154beea2017-10-26 07:58:48 -04003550#Code
3551#Literal
3552 | A B 0 | | dx |
3553Matrix = | D E 0 |, vec = | dy |
3554 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003555##
3556
Cary Clark154beea2017-10-26 07:58:48 -04003557each result Vector is computed as:
3558
3559#Code
3560#Literal
3561#Outdent
3562 |A B 0| |dx| A*dx+B*dy D*dx+E*dy
3563Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
3564 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
3565##
3566
3567#Param dx x-coordinate of Vector to map ##
3568#Param dy y-coordinate of Vector to map ##
3569#Param result storage for mapped Vector ##
3570
3571#Example
3572 SkPaint paint;
3573 paint.setColor(SK_ColorGREEN);
3574 paint.setAntiAlias(true);
3575 paint.setTextSize(48);
3576 SkMatrix matrix;
3577 matrix.setRotate(90);
3578 SkVector offset = { 7, 7 };
3579 for (int i = 0; i < 4; ++i) {
3580 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
3581 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
3582 matrix.mapVector(offset.fX, offset.fY, &offset);
3583 canvas->translate(0, 60);
3584 canvas->drawString("Text", 50, 0, paint);
3585 }
3586##
3587
Brian Salomonfa3783f2018-01-05 13:49:07 -05003588#SeeAlso mapVectors mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003589
3590##
3591
3592# ------------------------------------------------------------------------------
3593
3594#Method SkVector mapVector(SkScalar dx, SkScalar dy) const
3595
Cary Clark154beea2017-10-26 07:58:48 -04003596Returns Vector (x, y) multiplied by Matrix, treating Matrix translation as zero.
3597Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003598
Cary Clark154beea2017-10-26 07:58:48 -04003599#Code
3600#Literal
3601 | A B 0 | | dx |
3602Matrix = | D E 0 |, vec = | dy |
3603 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003604##
3605
Cary Clark154beea2017-10-26 07:58:48 -04003606each result Vector is computed as:
3607
3608#Code
3609#Literal
3610#Outdent
3611 |A B 0| |dx| A*dx+B*dy D*dx+E*dy
3612Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
3613 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
3614##
3615
3616#Param dx x-coordinate of Vector to map ##
3617#Param dy y-coordinate of Vector to map ##
3618
3619#Return mapped Vector ##
3620
3621#Example
3622 SkPaint paint;
3623 paint.setColor(SK_ColorGREEN);
3624 paint.setAntiAlias(true);
3625 paint.setTextSize(48);
3626 SkMatrix matrix;
3627 matrix.setRotate(90);
3628 SkVector offset = { 7, 7 };
3629 for (int i = 0; i < 4; ++i) {
3630 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
3631 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
3632 offset = matrix.mapVector(offset.fX, offset.fY);
3633 canvas->translate(0, 60);
3634 canvas->drawString("Text", 50, 0, paint);
3635 }
3636##
3637
Brian Salomonfa3783f2018-01-05 13:49:07 -05003638#SeeAlso mapVectors mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003639
3640##
3641
3642# ------------------------------------------------------------------------------
3643
3644#Method bool mapRect(SkRect* dst, const SkRect& src) const
Cary Clark4855f782018-02-06 09:41:53 -05003645#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003646#Line # returns bounds of mapped Rect ##
Cary Clark154beea2017-10-26 07:58:48 -04003647Sets dst to bounds of src corners mapped by Matrix.
3648Returns true if mapped corners are dst corners.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003649
Cary Clark154beea2017-10-26 07:58:48 -04003650Returned value is the same as calling rectStaysRect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003651
Cary Clark154beea2017-10-26 07:58:48 -04003652#Param dst storage for bounds of mapped Points ##
3653#Param src Rect to map ##
3654
3655#Return true if dst is equivalent to mapped src ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003656
3657#Example
Cary Clark154beea2017-10-26 07:58:48 -04003658 SkPaint paint;
3659 paint.setAntiAlias(true);
3660 SkMatrix matrix;
3661 matrix.setRotate(45, 128, 128);
3662 SkRect rotatedBounds, bounds = {40, 50, 190, 200};
3663 matrix.mapRect(&rotatedBounds, bounds );
3664 paint.setColor(SK_ColorGRAY);
3665 canvas->drawRect(rotatedBounds, paint);
3666 canvas->concat(matrix);
3667 paint.setColor(SK_ColorRED);
3668 canvas->drawRect(bounds, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003669##
3670
Cary Clark154beea2017-10-26 07:58:48 -04003671#SeeAlso mapPoints rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003672
3673##
3674
3675# ------------------------------------------------------------------------------
3676
3677#Method bool mapRect(SkRect* rect) const
3678
Cary Clark154beea2017-10-26 07:58:48 -04003679Sets rect to bounds of rect corners mapped by Matrix.
3680Returns true if mapped corners are computed rect corners.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003681
Cary Clark154beea2017-10-26 07:58:48 -04003682Returned value is the same as calling rectStaysRect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003683
Cary Clark154beea2017-10-26 07:58:48 -04003684#Param rect rectangle to map, and storage for bounds of mapped corners ##
3685
3686#Return true if result is equivalent to mapped src ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003687
3688#Example
Cary Clark154beea2017-10-26 07:58:48 -04003689 SkPaint paint;
3690 paint.setAntiAlias(true);
3691 SkMatrix matrix;
3692 matrix.setRotate(45, 128, 128);
3693 SkRect bounds = {40, 50, 190, 200};
3694 matrix.mapRect(&bounds);
3695 paint.setColor(SK_ColorGRAY);
3696 canvas->drawRect(bounds, paint);
3697 canvas->concat(matrix);
3698 paint.setColor(SK_ColorRED);
3699 canvas->drawRect({40, 50, 190, 200}, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003700##
3701
Cary Clark154beea2017-10-26 07:58:48 -04003702#SeeAlso mapRectScaleTranslate mapPoints rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003703
3704##
3705
3706# ------------------------------------------------------------------------------
3707
3708#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const
Cary Clark4855f782018-02-06 09:41:53 -05003709#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003710#Line # maps Rect to Point array ##
Cary Clark154beea2017-10-26 07:58:48 -04003711Maps four corners of rect to dst. Points are mapped by multiplying each
3712rect corner by Matrix. rect corner is processed in this order:
3713(rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom),
3714(rect.fLeft, rect.fBottom).
Cary Clarkbc5697d2017-10-04 14:31:33 -04003715
Cary Clark154beea2017-10-26 07:58:48 -04003716rect may be empty: rect.fLeft may be greater than or equal to rect.fRight;
3717rect.fTop may be greater than or equal to rect.fBottom.
3718
3719Given:
3720
3721#Code
3722#Literal
3723 | A B C | | x |
3724Matrix = | D E F |, pt = | y |
3725 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003726##
Cary Clark154beea2017-10-26 07:58:48 -04003727
3728where pt is initialized from each of (rect.fLeft, rect.fTop),
3729(rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom),
3730each dst Point is computed as:
3731
3732#Code
3733#Literal
3734 |A B C| |x| Ax+By+C Dx+Ey+F
3735Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3736 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003737##
3738
Cary Clark154beea2017-10-26 07:58:48 -04003739#Param dst storage for mapped corner Points ##
3740#Param rect Rect to map ##
3741
Cary Clarkbc5697d2017-10-04 14:31:33 -04003742#Example
Cary Clark2ade9972017-11-02 17:49:34 -04003743#Height 192
Cary Clark154beea2017-10-26 07:58:48 -04003744 SkPaint paint;
3745 paint.setAntiAlias(true);
3746 SkMatrix matrix;
3747 matrix.setRotate(60, 128, 128);
3748 SkRect rect = {50, 50, 150, 150};
3749 SkPoint pts[4];
3750 matrix.mapRectToQuad(pts, rect);
3751 for (int i = 0; i < 4; ++i) {
3752 canvas->drawCircle(pts[i].fX, pts[i].fY, 3, paint);
3753 }
3754 canvas->concat(matrix);
3755 paint.setStyle(SkPaint::kStroke_Style);
3756 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003757##
3758
Cary Clark154beea2017-10-26 07:58:48 -04003759#SeeAlso mapRect mapRectScaleTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04003760
3761##
3762
3763# ------------------------------------------------------------------------------
3764
3765#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const
Cary Clark4855f782018-02-06 09:41:53 -05003766#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003767#Line # returns bounds of mapped Rect ##
Cary Clark154beea2017-10-26 07:58:48 -04003768Sets dst to bounds of src corners mapped by Matrix. If matrix contains
3769elements other than scale or translate: asserts if SK_DEBUG is defined;
3770otherwise, results are undefined.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003771
Cary Clark154beea2017-10-26 07:58:48 -04003772#Param dst storage for bounds of mapped Points ##
3773#Param src Rect to map ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003774
3775#Example
Cary Clark154beea2017-10-26 07:58:48 -04003776 SkPaint paint;
3777 SkMatrix matrix;
3778 SkRect rect = {100, 50, 150, 180};
3779 matrix.setScale(2, .5f, rect.centerX(), rect.centerY());
3780 SkRect rotated;
3781 matrix.mapRectScaleTranslate(&rotated, rect);
3782 paint.setStyle(SkPaint::kStroke_Style);
3783 canvas->drawRect(rect, paint);
3784 paint.setColor(SK_ColorRED);
3785 canvas->drawRect(rotated, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003786##
3787
Cary Clark154beea2017-10-26 07:58:48 -04003788#SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003789
3790##
3791
3792# ------------------------------------------------------------------------------
3793
3794#Method SkScalar mapRadius(SkScalar radius) const
Cary Clark4855f782018-02-06 09:41:53 -05003795#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05003796#Line # returns mean radius of mapped Circle ##
Cary Clark154beea2017-10-26 07:58:48 -04003797Returns geometric mean radius of ellipse formed by constructing Circle of
3798size radius, and mapping constructed Circle with Matrix. The result squared is
3799equal to the major axis length times the minor axis length.
3800Result is not meaningful if Matrix contains perspective elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003801
Cary Clark154beea2017-10-26 07:58:48 -04003802#Param radius Circle size to map ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003803
Cary Clark154beea2017-10-26 07:58:48 -04003804#Return average mapped radius ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003805
3806#Example
Cary Clark154beea2017-10-26 07:58:48 -04003807#Description
3808The area enclosed by a square with sides equal to mappedRadius is the same as
3809the area enclosed by the ellipse major and minor axes.
3810##
3811 SkPaint paint;
3812 paint.setAntiAlias(true);
3813 SkMatrix matrix;
3814 const SkPoint center = {108, 93};
3815 matrix.setScale(2, .5f, center.fX, center.fY);
3816 matrix.postRotate(45, center.fX, center.fY);
3817 const SkScalar circleRadius = 50;
3818 SkScalar mappedRadius = matrix.mapRadius(circleRadius);
3819 SkVector minorAxis, majorAxis;
3820 matrix.mapVector(0, circleRadius, &minorAxis);
3821 matrix.mapVector(circleRadius, 0, &majorAxis);
3822 SkString mappedArea;
3823 mappedArea.printf("area = %g", mappedRadius * mappedRadius);
3824 canvas->drawString(mappedArea, 145, 250, paint);
3825 canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint);
3826 paint.setColor(SK_ColorRED);
3827 SkString axArea;
3828 axArea.printf("area = %g", majorAxis.length() * minorAxis.length());
3829 paint.setStyle(SkPaint::kFill_Style);
3830 canvas->drawString(axArea, 15, 250, paint);
3831 paint.setStyle(SkPaint::kStroke_Style);
3832 canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint);
3833 paint.setColor(SK_ColorBLACK);
3834 canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint);
3835 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint);
3836 canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint);
3837 canvas->concat(matrix);
3838 canvas->drawCircle(center.fX, center.fY, circleRadius, paint);
3839 paint.setColor(SK_ColorRED);
3840 canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint);
3841 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003842##
3843
Cary Clark154beea2017-10-26 07:58:48 -04003844#SeeAlso mapVector
Cary Clarkbc5697d2017-10-04 14:31:33 -04003845
3846##
3847
3848# ------------------------------------------------------------------------------
Cary Clarkbc5697d2017-10-04 14:31:33 -04003849#Method bool isFixedStepInX() const
Cary Clark4855f782018-02-06 09:41:53 -05003850#In Property
Cary Clark08895c42018-02-01 09:37:32 -05003851#Line # returns if transformation supports fixed step in x ##
Cary Clark154beea2017-10-26 07:58:48 -04003852Returns true if a unit step in x at some y mapped through Matrix can be
3853represented by a constant Vector. Returns true if getType returns kIdentity_Mask,
3854or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003855
Cary Clark154beea2017-10-26 07:58:48 -04003856May return true if getType returns kPerspective_Mask, but only when Matrix
3857does not include rotation or skewing along the y-axis.
3858
3859#Return true if Matrix does not have complex perspective ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003860
3861#Example
Cary Clark154beea2017-10-26 07:58:48 -04003862 SkMatrix matrix;
3863 for (SkScalar px : { 0.0f, 0.1f } ) {
3864 for (SkScalar py : { 0.0f, 0.1f } ) {
3865 for (SkScalar sy : { 1, 2 } ) {
3866 matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1);
3867 matrix.dump();
3868 SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false");
3869 }
3870 }
3871 }
3872#StdOut
3873[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
3874isFixedStepInX: true
3875[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000]
3876isFixedStepInX: true
3877[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000]
3878isFixedStepInX: true
3879[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000]
3880isFixedStepInX: true
3881[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000]
3882isFixedStepInX: false
3883[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000]
3884isFixedStepInX: false
3885[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000]
3886isFixedStepInX: false
3887[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000]
3888isFixedStepInX: false
3889##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003890##
3891
Cary Clark154beea2017-10-26 07:58:48 -04003892#SeeAlso fixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04003893
3894##
3895
3896# ------------------------------------------------------------------------------
3897
3898#Method SkVector fixedStepInX(SkScalar y) const
Cary Clark4855f782018-02-06 09:41:53 -05003899#In Property
Cary Clark08895c42018-02-01 09:37:32 -05003900#Line # returns step in x for a position in y ##
Cary Clark154beea2017-10-26 07:58:48 -04003901Returns Vector representing a unit step in x at y mapped through Matrix.
3902If isFixedStepInX is false, returned value is undefined.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003903
Cary Clark154beea2017-10-26 07:58:48 -04003904#Param y position of line parallel to x-axis ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003905
Cary Clark154beea2017-10-26 07:58:48 -04003906#Return Vector advance of mapped unit step in x ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003907
3908#Example
Cary Clark154beea2017-10-26 07:58:48 -04003909#Image 3
3910 SkMatrix matrix;
3911 const SkPoint center = { 128, 128 };
3912 matrix.setScale(20, 25, center.fX, center.fY);
3913 matrix.postRotate(75, center.fX, center.fY);
3914 {
3915 SkAutoCanvasRestore acr(canvas, true);
3916 canvas->concat(matrix);
3917 canvas->drawBitmap(source, 0, 0);
3918 }
3919 if (matrix.isFixedStepInX()) {
3920 SkPaint paint;
3921 paint.setAntiAlias(true);
3922 SkVector step = matrix.fixedStepInX(128);
3923 SkVector end = center + step;
3924 canvas->drawLine(center, end, paint);
3925 SkVector arrow = { step.fX + step.fY, step.fY - step.fX};
3926 arrow = arrow * .25f;
3927 canvas->drawLine(end, end - arrow, paint);
3928 canvas->drawLine(end, {end.fX + arrow.fY, end.fY - arrow.fX}, paint);
3929 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003930##
3931
Cary Clark154beea2017-10-26 07:58:48 -04003932#SeeAlso isFixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04003933
3934##
3935
3936# ------------------------------------------------------------------------------
3937
3938#Method bool cheapEqualTo(const SkMatrix& m) const
Cary Clark4855f782018-02-06 09:41:53 -05003939#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05003940#Line # compares Matrix pair using memcmp() ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003941Returns true if Matrix equals m, using an efficient comparison.
3942
Cary Clark154beea2017-10-26 07:58:48 -04003943Returns false when the sign of zero values is the different; when one
Cary Clarkbc5697d2017-10-04 14:31:33 -04003944matrix has positive zero value and the other has negative zero value.
3945
Cary Clark154beea2017-10-26 07:58:48 -04003946Returns true even when both Matrices contain NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003947
Cary Clark154beea2017-10-26 07:58:48 -04003948NaN never equals any value, including itself. To improve performance, NaN values
3949are treated as bit patterns that are equal if their bit patterns are equal.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003950
Cary Clark154beea2017-10-26 07:58:48 -04003951#Param m Matrix to compare ##
3952
3953#Return true if m and Matrix are represented by identical bit patterns ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003954
3955#Example
Cary Clark154beea2017-10-26 07:58:48 -04003956 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
3957 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
3958 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
Cary Clarkbc5697d2017-10-04 14:31:33 -04003959 };
Cary Clark154beea2017-10-26 07:58:48 -04003960 SkMatrix a, b;
3961 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
3962 b.setIdentity();
3963 debugster("identity", a, b);
3964 a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1);
3965 debugster("neg zero", a, b);
3966 a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
3967 debugster(" one NaN", a, b);
3968 b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
3969 debugster("both NaN", a, b);
3970#StdOut
3971identity: a == b a.cheapEqualTo(b): true
3972neg zero: a == b a.cheapEqualTo(b): false
3973 one NaN: a != b a.cheapEqualTo(b): false
3974both NaN: a != b a.cheapEqualTo(b): true
3975##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003976##
3977
Cary Clark154beea2017-10-26 07:58:48 -04003978#SeeAlso operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04003979
3980##
3981
3982# ------------------------------------------------------------------------------
3983
Cary Clark154beea2017-10-26 07:58:48 -04003984#Method bool operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04003985
Cary Clark08895c42018-02-01 09:37:32 -05003986#Line # returns true if members are equal ##
Cary Clark154beea2017-10-26 07:58:48 -04003987Compares a and b; returns true if a and b are numerically equal. Returns true
3988even if sign of zero values are different. Returns false if either Matrix
3989contains NaN, even if the other Matrix also contains NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003990
Cary Clark154beea2017-10-26 07:58:48 -04003991#Param a Matrix to compare ##
3992#Param b Matrix to compare ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003993
Cary Clark4855f782018-02-06 09:41:53 -05003994#Return true if Matrix a and Matrix b are numerically equal ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003995
3996#Example
Cary Clark154beea2017-10-26 07:58:48 -04003997 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
3998 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
3999 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
4000 };
4001 SkMatrix a, b;
4002 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
4003 b.setScale(2, 4);
4004 b.postScale(0.5f, 0.25f);
4005 debugster("identity", a, b);
4006#StdOut
4007identity: a == b a.cheapEqualTo(b): true
4008##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004009##
4010
Cary Clark154beea2017-10-26 07:58:48 -04004011#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004012
4013##
4014
4015# ------------------------------------------------------------------------------
4016
Cary Clark154beea2017-10-26 07:58:48 -04004017#Method bool operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004018
Cary Clark08895c42018-02-01 09:37:32 -05004019#Line # returns true if members are unequal ##
Cary Clark154beea2017-10-26 07:58:48 -04004020Compares a and b; returns true if a and b are not numerically equal. Returns false
4021even if sign of zero values are different. Returns true if either Matrix
4022contains NaN, even if the other Matrix also contains NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004023
Cary Clark154beea2017-10-26 07:58:48 -04004024#Param a Matrix to compare ##
4025#Param b Matrix to compare ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004026
Cary Clark4855f782018-02-06 09:41:53 -05004027#Return true if Matrix a and Matrix b are numerically not equal ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004028
4029#Example
Cary Clark154beea2017-10-26 07:58:48 -04004030 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
4031 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
4032 a != b ? '!' : '=', a.cheapEqualTo(b) ? "true" : "false");
4033 };
4034 SkMatrix a, b;
4035 a.setAll(1, 0, 0, 0, 1, 0, 1, 0, 1);
Cary Clark681287e2018-03-16 11:34:15 -04004036 if (a.invert(&b)) {
4037 debugster("identity", a, b);
4038 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04004039##
4040
Cary Clark154beea2017-10-26 07:58:48 -04004041#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004042
4043##
4044
4045# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05004046#Subtopic Utility
4047#Populate
4048#Line # rarely called management functions ##
4049##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004050
4051#Method void dump() const
Cary Clark4855f782018-02-06 09:41:53 -05004052#In Utility
Cary Clark08895c42018-02-01 09:37:32 -05004053#Line # sends text representation using floats to standard output ##
Cary Clark154beea2017-10-26 07:58:48 -04004054Writes text representation of Matrix to standard output. Floating point values
4055are written with limited precision; it may not be possible to reconstruct
4056original Matrix from output.
4057
Cary Clarkbc5697d2017-10-04 14:31:33 -04004058#Example
Cary Clark154beea2017-10-26 07:58:48 -04004059 SkMatrix matrix;
4060 matrix.setRotate(45);
4061 matrix.dump();
4062 SkMatrix nearlyEqual;
4063 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
4064 nearlyEqual.dump();
4065 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
4066#StdOut
4067[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4068[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4069matrix != nearlyEqual
4070##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004071##
4072
Cary Clark154beea2017-10-26 07:58:48 -04004073#SeeAlso toString
Cary Clarkbc5697d2017-10-04 14:31:33 -04004074
4075##
4076
4077# ------------------------------------------------------------------------------
4078
4079#Method void toString(SkString* str) const
Cary Clark4855f782018-02-06 09:41:53 -05004080#In Utility
Cary Clark08895c42018-02-01 09:37:32 -05004081#Line # converts Matrix to machine readable form ##
Cary Clark154beea2017-10-26 07:58:48 -04004082Creates string representation of Matrix. Floating point values
4083are written with limited precision; it may not be possible to reconstruct
4084original Matrix from output.
4085
4086#Param str storage for string representation of Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004087
4088#Example
Cary Clark154beea2017-10-26 07:58:48 -04004089 SkMatrix matrix;
4090 matrix.setRotate(45);
4091 SkString mStr, neStr;
4092 matrix.toString(&mStr);
4093 SkMatrix nearlyEqual;
4094 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
4095 nearlyEqual.toString(&neStr);
4096 SkDebugf("mStr %s\n", mStr.c_str());
4097 SkDebugf("neStr %s\n", neStr.c_str());
4098 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
4099#StdOut
4100mStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4101neStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4102matrix != nearlyEqual
4103##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004104##
4105
Cary Clark154beea2017-10-26 07:58:48 -04004106#SeeAlso dump
Cary Clarkbc5697d2017-10-04 14:31:33 -04004107
4108##
4109
4110# ------------------------------------------------------------------------------
4111
4112#Method SkScalar getMinScale() const
Cary Clark4855f782018-02-06 09:41:53 -05004113#In Property
Cary Clark08895c42018-02-01 09:37:32 -05004114#Line # returns minimum scaling, if possible ##
Cary Clark154beea2017-10-26 07:58:48 -04004115Returns the minimum scaling factor of Matrix by decomposing the scaling and
4116skewing elements.
4117Returns -1 if scale factor overflows or Matrix contains perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004118
4119#Return minimum scale factor
4120##
4121
4122#Example
Cary Clark154beea2017-10-26 07:58:48 -04004123 SkMatrix matrix;
4124 matrix.setScale(42, 24);
4125 SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale());
4126#StdOut
4127matrix.getMinScale() 24
4128##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004129##
4130
Cary Clark154beea2017-10-26 07:58:48 -04004131#SeeAlso getMaxScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04004132
4133##
4134
4135# ------------------------------------------------------------------------------
4136
4137#Method SkScalar getMaxScale() const
Cary Clark4855f782018-02-06 09:41:53 -05004138#In Property
Cary Clark08895c42018-02-01 09:37:32 -05004139#Line # returns maximum scaling, if possible ##
Cary Clark154beea2017-10-26 07:58:48 -04004140Returns the maximum scaling factor of Matrix by decomposing the scaling and
4141skewing elements.
4142Returns -1 if scale factor overflows or Matrix contains perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004143
4144#Return maximum scale factor
4145##
4146
4147#Example
Cary Clark154beea2017-10-26 07:58:48 -04004148 SkMatrix matrix;
4149 matrix.setScale(42, 24);
4150 SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale());
4151#StdOut
4152matrix.getMaxScale() 42
4153##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004154##
4155
Cary Clark154beea2017-10-26 07:58:48 -04004156#SeeAlso getMinScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04004157
4158##
4159
4160# ------------------------------------------------------------------------------
4161
4162#Method bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const
Cary Clark4855f782018-02-06 09:41:53 -05004163#In Property
Cary Clark08895c42018-02-01 09:37:32 -05004164#Line # returns minimum and maximum scaling, if possible ##
Cary Clark154beea2017-10-26 07:58:48 -04004165Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the
4166maximum scaling factor. Scaling factors are computed by decomposing
4167the Matrix scaling and skewing elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004168
Cary Clark154beea2017-10-26 07:58:48 -04004169Returns true if scaleFactors are found; otherwise, returns false and sets
4170scaleFactors to undefined values.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004171
Cary Clark154beea2017-10-26 07:58:48 -04004172#Param scaleFactors storage for minimum and maximum scale factors ##
4173
4174#Return true if scale factors were computed correctly ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004175
4176#Example
Cary Clark154beea2017-10-26 07:58:48 -04004177 SkMatrix matrix;
4178 matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0);
Cary Clark681287e2018-03-16 11:34:15 -04004179 if (matrix.invert(&matrix)) {
4180 SkScalar factor[2] = {2, 2};
4181 bool result = matrix.getMinMaxScales(factor);
4182 SkDebugf("matrix.getMinMaxScales() %s %g %g\n",
4183 result ? "true" : "false", factor[0], factor[1]);
4184 }
Cary Clark154beea2017-10-26 07:58:48 -04004185#StdOut
4186matrix.getMinMaxScales() false 2 2
4187##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004188##
4189
Cary Clark154beea2017-10-26 07:58:48 -04004190#SeeAlso getMinScale getMaxScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04004191
4192##
4193
4194# ------------------------------------------------------------------------------
4195
4196#Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const
Cary Clark4855f782018-02-06 09:41:53 -05004197#In Property
Cary Clark08895c42018-02-01 09:37:32 -05004198#Line # separates scale if possible ##
Cary Clark154beea2017-10-26 07:58:48 -04004199Decomposes Matrix into scale components and whatever remains. Returns false if
4200Matrix could not be decomposed.
4201
4202Sets scale to portion of Matrix that scales in x and y. Sets remaining to Matrix
4203with x and y scaling factored out. remaining may be passed as nullptr
4204to determine if Matrix can be decomposed without computing remainder.
4205
4206Returns true if scale components are found. scale and remaining are
4207unchanged if Matrix contains perspective; scale factors are not finite, or
4208are nearly zero.
4209
4210On success
4211
Cary Clarkbc5697d2017-10-04 14:31:33 -04004212#Formula
Cary Clark154beea2017-10-26 07:58:48 -04004213Matrix = scale * Remaining
Cary Clarkbc5697d2017-10-04 14:31:33 -04004214##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004215
Cary Clark154beea2017-10-26 07:58:48 -04004216#Param scale x and y scaling factors; may be nullptr ##
4217#Param remaining Matrix without scaling; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004218
Cary Clark154beea2017-10-26 07:58:48 -04004219#Return true if scale can be computed ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004220
4221#Example
Cary Clark154beea2017-10-26 07:58:48 -04004222 SkMatrix matrix;
4223 matrix.setRotate(90 * SK_Scalar1);
4224 matrix.postScale(1.f / 4, 1.f / 2);
4225 matrix.dump();
4226 SkSize scale = {SK_ScalarNaN, SK_ScalarNaN};
4227 SkMatrix remaining;
4228 remaining.reset();
4229 bool success = matrix.decomposeScale(&scale, &remaining);
4230 SkDebugf("success: %s ", success ? "true" : "false");
4231 SkDebugf("scale: %g, %g\n", scale.width(), scale.height());
4232 remaining.dump();
4233 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height());
4234 SkMatrix combined = SkMatrix::Concat(scaleMatrix, remaining);
4235 combined.dump();
4236#StdOut
4237[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4238success: true scale: 0.5, 0.25
4239[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4240[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4241##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004242##
4243
Cary Clark154beea2017-10-26 07:58:48 -04004244#SeeAlso setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04004245
4246##
4247
4248# ------------------------------------------------------------------------------
4249
4250#Method static const SkMatrix& I()
Cary Clark4855f782018-02-06 09:41:53 -05004251#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -05004252#Line # returns a reference to a const identity Matrix ##
Cary Clark154beea2017-10-26 07:58:48 -04004253Returns reference to const identity Matrix. Returned Matrix is set to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004254
Cary Clark154beea2017-10-26 07:58:48 -04004255#Code
4256#Literal
4257| 1 0 0 |
4258| 0 1 0 |
4259| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004260##
4261
Cary Clark154beea2017-10-26 07:58:48 -04004262#Return const identity Matrix ##
4263
4264#Example
4265 SkMatrix m1, m2, m3;
4266 m1.reset();
4267 m2.setIdentity();
4268 m3 = SkMatrix::I();
4269 SkDebugf("m1 %c= m2\n", m1 == m2 ? '=' : '!');
4270 SkDebugf("m2 %c= m3\n", m1 == m2 ? '=' : '!');
4271#StdOut
4272m1 == m2
4273m2 == m3
4274##
4275##
4276
4277#SeeAlso reset() setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04004278
4279##
4280
4281# ------------------------------------------------------------------------------
4282
4283#Method static const SkMatrix& InvalidMatrix()
Cary Clark4855f782018-02-06 09:41:53 -05004284#In Constructor
Cary Clark08895c42018-02-01 09:37:32 -05004285#Line # returns a reference to a const invalid Matrix ##
Cary Clark154beea2017-10-26 07:58:48 -04004286Returns reference to a const Matrix with invalid values. Returned Matrix is set
4287to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004288
Cary Clark154beea2017-10-26 07:58:48 -04004289#Code
4290#Literal
4291| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
4292| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
4293| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004294##
4295
Cary Clark154beea2017-10-26 07:58:48 -04004296#Return const invalid Matrix ##
4297
4298#Example
4299 SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX());
4300#StdOut
4301scaleX 3.40282e+38
4302##
4303##
4304
4305#SeeAlso SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04004306
4307##
4308
4309# ------------------------------------------------------------------------------
4310
4311#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b)
Cary Clark4855f782018-02-06 09:41:53 -05004312#In Operator
Cary Clark08895c42018-02-01 09:37:32 -05004313#Line # returns the concatenation of Matrix pair ##
Cary Clark154beea2017-10-26 07:58:48 -04004314Returns Matrix a multiplied by Matrix b.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004315
Cary Clark154beea2017-10-26 07:58:48 -04004316Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004317
Cary Clark154beea2017-10-26 07:58:48 -04004318#Code
4319#Literal
4320 | A B C | | J K L |
4321a = | D E F |, b = | M N O |
4322 | G H I | | P Q R |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004323##
4324
Cary Clark154beea2017-10-26 07:58:48 -04004325sets Matrix to:
4326
4327#Code
4328#Literal
4329 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
4330a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
4331 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
4332##
4333
4334#Param a Matrix on left side of multiply expression ##
4335#Param b Matrix on right side of multiply expression ##
4336
4337#Return Matrix computed from a times b ##
4338
4339#Example
4340#Height 64
4341#Image 4
4342#Description
4343setPolyToPoly creates perspective matrices, one the inverse of the other.
4344Multiplying the matrix by its inverse turns into an identity matrix.
4345##
4346SkMatrix matrix, matrix2;
4347SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
4348SkRect::Make(source.bounds()).toQuad(bitmapBounds);
4349matrix.setPolyToPoly(bitmapBounds, perspect, 4);
4350matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
4351SkMatrix concat = SkMatrix::Concat(matrix, matrix2);
4352canvas->concat(concat);
4353canvas->drawBitmap(source, 0, 0);
4354##
4355
4356#SeeAlso preConcat postConcat
Cary Clarkbc5697d2017-10-04 14:31:33 -04004357
4358##
4359
4360# ------------------------------------------------------------------------------
4361
4362#Method void dirtyMatrixTypeCache()
Cary Clark4855f782018-02-06 09:41:53 -05004363#In Utility
Cary Clark08895c42018-02-01 09:37:32 -05004364#Line # sets internal cache to unknown state ##
Cary Clark154beea2017-10-26 07:58:48 -04004365Sets internal cache to unknown state. Use to force update after repeated
4366modifications to Matrix element reference returned by operator[](int index).
Cary Clarkbc5697d2017-10-04 14:31:33 -04004367
4368#Example
Cary Clark154beea2017-10-26 07:58:48 -04004369SkMatrix matrix;
4370matrix.setIdentity();
4371SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
4372SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
4373skewRef = 0;
4374SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
4375skewRef = 1;
4376SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
4377matrix.dirtyMatrixTypeCache();
4378SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
4379#StdOut
4380with identity matrix: x = 24
4381after skew x mod: x = 24
4382after 2nd skew x mod: x = 24
4383after dirty cache: x = 66
4384##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004385##
4386
Cary Clark154beea2017-10-26 07:58:48 -04004387#SeeAlso operator[](int index) getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04004388
4389##
4390
4391# ------------------------------------------------------------------------------
4392
4393#Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
Cary Clark4855f782018-02-06 09:41:53 -05004394#In Constructor
4395#In Set
Cary Clark08895c42018-02-01 09:37:32 -05004396#Line # sets to scale and translate ##
Cary Clark154beea2017-10-26 07:58:48 -04004397Initializes Matrix with scale and translate elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004398
Cary Clark154beea2017-10-26 07:58:48 -04004399#Code
4400#Literal
4401| sx 0 tx |
4402| 0 sy ty |
4403| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004404##
4405
Cary Clark154beea2017-10-26 07:58:48 -04004406#Param sx horizontal scale factor to store ##
4407#Param sy vertical scale factor to store ##
4408#Param tx horizontal translation to store ##
4409#Param ty vertical translation to store ##
4410
4411#Example
4412SkMatrix matrix;
4413matrix.setScaleTranslate(1, 2, 3, 4);
4414matrix.dump();
4415#StdOut
4416[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000]
4417##
4418##
4419
4420#SeeAlso setScale preTranslate postTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04004421
4422##
4423
4424# ------------------------------------------------------------------------------
4425
4426#Method bool isFinite() const
Cary Clark4855f782018-02-06 09:41:53 -05004427#In Property
Cary Clark08895c42018-02-01 09:37:32 -05004428#Line # returns if all Matrix values are not infinity, NaN ##
Cary Clark154beea2017-10-26 07:58:48 -04004429Returns true if all elements of the matrix are finite. Returns false if any
4430element is infinity, or NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004431
Cary Clark154beea2017-10-26 07:58:48 -04004432#Return true if matrix has only finite elements ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004433
4434#Example
Cary Clark154beea2017-10-26 07:58:48 -04004435SkMatrix matrix = SkMatrix::MakeTrans(SK_ScalarNaN, 0);
4436matrix.dump();
4437SkDebugf("matrix is finite: %s\n", matrix.isFinite() ? "true" : "false");
4438SkDebugf("matrix %c= matrix\n", matrix == matrix ? '=' : '!');
4439#StdOut
4440[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
4441matrix is finite: false
4442matrix != matrix
4443##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004444##
4445
Cary Clark154beea2017-10-26 07:58:48 -04004446#SeeAlso operator==
Cary Clarkbc5697d2017-10-04 14:31:33 -04004447
4448##
4449
4450#Class SkMatrix ##
4451
4452#Topic Matrix ##
Cary Clark4855f782018-02-06 09:41:53 -05004453