blob: d348acb441a5a811319a94db53d3140e69ecb0dd [file] [log] [blame]
Cary Clarkbc5697d2017-10-04 14:31:33 -04001#Topic Matrix
Cary Clark154beea2017-10-26 07:58:48 -04002#Alias Matrices
Cary Clarkbc5697d2017-10-04 14:31:33 -04003#Alias Matrix_Reference
4
5#Class SkMatrix
6
Cary Clark154beea2017-10-26 07:58:48 -04007Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping
8Points and Vectors with translation, scaling, skewing, rotation, and
9perspective.
Cary Clark884dd7d2017-10-11 10:37:52 -040010
Cary Clark154beea2017-10-26 07:58:48 -040011Matrix elements are in row major order. Matrix does not have a constructor,
12so it must be explicitly initialized. setIdentity initializes Matrix
13so it has no effect. setTranslate, setScale, setSkew, setRotate, set9 and setAll
14initializes all Matrix elements with the corresponding mapping.
Cary Clark884dd7d2017-10-11 10:37:52 -040015
Cary Clark154beea2017-10-26 07:58:48 -040016Matrix includes a hidden variable that classifies the type of matrix to
17improve performance. Matrix is not thread safe unless getType is called first.
Cary Clarkbc5697d2017-10-04 14:31:33 -040018
19#Topic Overview
20
21#Subtopic Subtopics
22#ToDo manually add subtopics ##
23#Table
24#Legend
25# topics # description ##
26#Legend ##
27#Table ##
28##
29
Cary Clark5081eed2018-01-22 07:55:48 -050030#Subtopic Constructors
31#Table
32#Legend
33# name # description ##
34#Legend ##
35# MakeAll # Constructs all nine values. ##
36# MakeRectToRect # Constructs from source Rect to destination Rect. ##
37# MakeScale # Constructs from scale in x and y. ##
38# MakeTrans # Constructs from translate in x and y. ##
39#Table ##
40#Subtopic ##
41
Cary Clarkbc5697d2017-10-04 14:31:33 -040042#Subtopic Operators
43#Table
44#Legend
Cary Clark154beea2017-10-26 07:58:48 -040045# function # description ##
Cary Clarkbc5697d2017-10-04 14:31:33 -040046#Legend ##
Cary Clark154beea2017-10-26 07:58:48 -040047# operator!=(const SkMatrix& a, const SkMatrix& b) # Returns true if members are unequal. ##
48# operator==(const SkMatrix& a, const SkMatrix& b) # Returns true if members are equal. ##
Cary Clark154beea2017-10-26 07:58:48 -040049# operator[](int index) # Returns writable reference to Matrix value. ##
Cary Clark5081eed2018-01-22 07:55:48 -050050# operator[](int index)_const # Returns Matrix value. ##
Cary Clarkbc5697d2017-10-04 14:31:33 -040051#Table ##
52#Subtopic ##
53
54#Subtopic Member_Functions
55#Table
56#Legend
Cary Clark154beea2017-10-26 07:58:48 -040057# function # description ##
Cary Clarkbc5697d2017-10-04 14:31:33 -040058#Legend ##
Cary Clark884dd7d2017-10-11 10:37:52 -040059# Concat # Returns the concatenation of Matrix pair. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040060# I # Returns a reference to a const identity Matrix. ##
61# InvalidMatrix # Returns a reference to a const invalid Matrix. ##
Cary Clarkbef063a2017-10-31 15:44:45 -040062# MakeAll # Constructs all nine values. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040063# MakeRectToRect # Constructs from source Rect to destination Rect. ##
64# MakeScale # Constructs from scale in x and y. ##
65# MakeTrans # Constructs from translate in x and y. ##
Cary Clark154beea2017-10-26 07:58:48 -040066# SetAffineIdentity # Sets 3x2 array to identity. ##
67# asAffine # Copies to 3x2 array. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040068# cheapEqualTo # Compares Matrix pair using memcmp(). ##
69# decomposeScale # Separates scale if possible. ##
Cary Clark154beea2017-10-26 07:58:48 -040070# dirtyMatrixTypeCache # Sets internal cache to unknown state. ##
71# dump() # Sends text representation using floats to standard output. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040072# fixedStepInX # Returns step in x for a position in y. ##
Cary Clark154beea2017-10-26 07:58:48 -040073# get() # Returns one of nine Matrix values. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040074# get9 # Returns all nine Matrix values. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040075# getMaxScale # Returns maximum scaling, if possible. ##
76# getMinMaxScales # Returns minimum and maximum scaling, if possible. ##
77# getMinScale # Returns minimum scaling, if possible. ##
Cary Clark154beea2017-10-26 07:58:48 -040078# getPerspX # Returns input x perspective factor. ##
79# getPerspY # Returns input y perspective factor. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040080# getScaleX # Returns horizontal scale factor. ##
Cary Clark154beea2017-10-26 07:58:48 -040081# getScaleY # Returns vertical scale factor. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040082# getSkewX # Returns horizontal skew factor. ##
83# getSkewY # Returns vertical skew factor. ##
Cary Clark154beea2017-10-26 07:58:48 -040084# getTranslateX # Returns horizontal translation. ##
85# getTranslateY # Returns vertical translation. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040086# getType # Returns transform complexity. ##
87# hasPerspective # Returns if transform includes perspective. ##
Cary Clark154beea2017-10-26 07:58:48 -040088# invert() # Returns inverse, if possible. ##
Cary Clark884dd7d2017-10-11 10:37:52 -040089# isFinite # Returns if all Matrix values are not infinity, NaN. ##
90# isFixedStepInX # Returns if transformation supports fixed step in x. ##
91# isIdentity # Returns if matrix equals the identity Matrix .##
92# isScaleTranslate # Returns if transform is limited to scale and translate. ##
93# isSimilarity # Returns if transform is limited to square scale and rotation. ##
94# isTranslate # Returns if transform is limited to translate. ##
Cary Clark154beea2017-10-26 07:58:48 -040095# mapHomogeneousPoints # Maps Point3 array. ##
96# mapPoints # Maps Point array. ##
Cary Clark154beea2017-10-26 07:58:48 -040097# mapRadius # Returns mean radius of mapped Circle. ##
98# mapRect # Returns bounds of mapped Rect. ##
99# mapRectScaleTranslate # Returns bounds of mapped Rect. ##
100# mapRectToQuad # Maps Rect to Point array. ##
101# mapVector # Maps Vector. ##
102# mapVectors # Maps Vector array. ##
103# mapXY # Maps Point. ##
104# postConcat # Post-multiplies Matrix by Matrix parameter. ##
105# postIDiv # Post-multiplies Matrix by inverse scale. ##
106# postRotate # Post-multiplies Matrix by rotation. ##
107# postScale # Post-multiplies Matrix by scale. ##
108# postSkew # Post-multiplies Matrix by skew. ##
109# postTranslate # Post-multiplies Matrix by translation. ##
110# preConcat # Pre-multiplies Matrix by Matrix parameter.##
111# preRotate # Pre-multiplies Matrix by rotation. ##
112# preScale # Pre-multiplies Matrix by scale. ##
113# preSkew # Pre-multiplies Matrix by skew. ##
114# preTranslate # Pre-multiplies Matrix by translation. ##
115# preservesAxisAlignment # Returns if mapping restricts to 90 degree multiples and mirroring. ##
116# preservesRightAngles # Returns if mapped 90 angle remains 90 degrees. ##
117# rectStaysRect # Returns if mapped Rect can be represented by another Rect. ##
118# reset() # Sets Matrix to identity. ##
119# set() # Sets one value. ##
120# set9 # Sets all values from Scalar array. ##
121# setAffine # Sets left two columns. ##
122# setAll # Sets all values from parameters. ##
123# setConcat # Sets to Matrix parameter multiplied by Matrix parameter. ##
124# setIdentity # Sets Matrix to identity. ##
125# setPerspX # Sets input x perspective factor. ##
126# setPerspY # Sets input y perspective factor. ##
127# setPolyToPoly # Sets to map one to four points to an equal array of points. ##
128# setRSXform # Sets to rotate, scale, and translate. ##
129# setRectToRect # Sets to map one Rect to another. ##
130# setRotate # Sets to rotate about a point. ##
131# setScale # Sets to scale about a point. ##
132# setScaleTranslate # Sets to scale and translate. ##
133# setScaleX # Sets horizontal scale factor. ##
134# setScaleY # Sets vertical scale factor ##
135# setSinCos # Sets to rotate and scale about a point. ##
136# setSkew # Sets to skew about a point. ##
137# setSkewX # Sets horizontal skew factor. ##
138# setSkewY # Sets vertical skew factor. ##
139# setTranslate # Sets to translate in x and y. ##
140# setTranslateX # Sets horizontal translation. ##
141# setTranslateY # Sets vertical translation. ##
142# toString # Converts Matrix to machine readable form. ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400143#Table ##
144#Subtopic ##
145
146#Topic ##
147
148# ------------------------------------------------------------------------------
149
150#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy)
151
Cary Clark154beea2017-10-26 07:58:48 -0400152Sets Matrix to scale by (sx, sy). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400153
Cary Clark154beea2017-10-26 07:58:48 -0400154#Code
155#Literal
156| sx 0 0 |
157| 0 sy 0 |
158| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400159##
160
Cary Clark154beea2017-10-26 07:58:48 -0400161#Param sx horizontal scale factor ##
162#Param sy vertical scale factor ##
163
164#Return Matrix with scale ##
165
166#Example
167#Image 4
168canvas->concat(SkMatrix::MakeScale(4, 3));
169canvas->drawBitmap(source, 0, 0);
170##
171
172#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400173
174##
175
176# ------------------------------------------------------------------------------
177
178#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale)
179
Cary Clark154beea2017-10-26 07:58:48 -0400180Sets Matrix to scale by (scale, scale). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400181
Cary Clark154beea2017-10-26 07:58:48 -0400182#Code
183#Literal
184| scale 0 0 |
185| 0 scale 0 |
186| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400187##
188
Cary Clark154beea2017-10-26 07:58:48 -0400189#Param scale horizontal and vertical scale factor ##
190
191#Return Matrix with scale ##
192
193#Example
194#Image 4
195canvas->concat(SkMatrix::MakeScale(4));
196canvas->drawBitmap(source, 0, 0);
197##
198
199#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400200
201##
202
203# ------------------------------------------------------------------------------
204
205#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy)
206
Cary Clark154beea2017-10-26 07:58:48 -0400207Sets Matrix to translate by (dx, dy). Returned matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400208
Cary Clark154beea2017-10-26 07:58:48 -0400209#Code
210#Literal
Cary Clarkcfee6ec2017-10-26 10:34:05 -0400211| 1 0 dx |
212| 0 1 dy |
213| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400214##
215
Cary Clark154beea2017-10-26 07:58:48 -0400216#Param dx horizontal translation ##
217#Param dy vertical translation ##
218
219#Return Matrix with translation ##
220
221#Example
222#Image 4
223SkMatrix matrix = SkMatrix::MakeTrans(64, 48);
224for (int i = 0; i < 4; ++i) {
225 canvas->drawBitmap(source, 0, 0);
226 canvas->concat(matrix);
227}
228##
229
230#SeeAlso setTranslate postTranslate preTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400231
232##
233
234# ------------------------------------------------------------------------------
235
Cary Clarkbef063a2017-10-31 15:44:45 -0400236#Method static SkMatrix SK_WARN_UNUSED_RESULT MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
237 SkScalar skewY, SkScalar scaleY, SkScalar transY,
238 SkScalar pers0, SkScalar pers1, SkScalar pers2)
239
240
241Sets Matrix to:
242
243#Code
244#Literal
245| scaleX skewX transX |
246| skewY scaleY transY |
247| pers0 pers1 pers2 |
248##
249
250#Param scaleX horizontal scale factor ##
251#Param skewX horizontal skew factor ##
252#Param transX horizontal translation ##
253#Param skewY vertical skew factor ##
254#Param scaleY vertical scale factor ##
255#Param transY vertical translation ##
256#Param pers0 input x perspective factor ##
257#Param pers1 input y perspective factor ##
258#Param pers2 perspective scale factor ##
259
260#Return Matrix constructed from parameters ##
261
262#Example
263 SkPaint p;
264 p.setAntiAlias(true);
265 p.setTextSize(64);
266 for (SkScalar sx : { -1, 1 } ) {
267 for (SkScalar sy : { -1, 1 } ) {
268 SkAutoCanvasRestore autoRestore(canvas, true);
269 SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1);
270 canvas->concat(m);
271 canvas->drawString("K", 0, 0, p);
272 }
273 }
274##
275
276#SeeAlso setAll set9 postConcat preConcat
277
278##
279
280
281# ------------------------------------------------------------------------------
282
Cary Clarkbc5697d2017-10-04 14:31:33 -0400283#Enum TypeMask
284
285#Code
286 enum TypeMask {
287 kIdentity_Mask = 0,
288 kTranslate_Mask = 0x01,
289 kScale_Mask = 0x02,
290 kAffine_Mask = 0x04,
291 kPerspective_Mask = 0x08,
292 };
293##
294
Cary Clark154beea2017-10-26 07:58:48 -0400295Enum of bit fields for mask returned by getType.
296Used to identify the complexity of Matrix, to optimize performance.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400297
Cary Clark154beea2017-10-26 07:58:48 -0400298#Const kIdentity_Mask 0
299all bits clear if Matrix is identity
Cary Clarkbc5697d2017-10-04 14:31:33 -0400300##
Cary Clark154beea2017-10-26 07:58:48 -0400301#Const kTranslate_Mask 1
302set if Matrix has translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400303##
Cary Clark154beea2017-10-26 07:58:48 -0400304#Const kScale_Mask 2
305set if Matrix has x or y scale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400306##
Cary Clark154beea2017-10-26 07:58:48 -0400307#Const kAffine_Mask 4
308set if Matrix skews or rotates
Cary Clarkbc5697d2017-10-04 14:31:33 -0400309##
Cary Clark154beea2017-10-26 07:58:48 -0400310#Const kPerspective_Mask 8
311set if Matrix has perspective
Cary Clarkbc5697d2017-10-04 14:31:33 -0400312##
313
314#Example
Cary Clark154beea2017-10-26 07:58:48 -0400315 auto debugster = [](const char* prefix, const SkMatrix& matrix) -> void {
316 SkString typeMask;
317 typeMask += SkMatrix::kIdentity_Mask == matrix.getType() ? "kIdentity_Mask " : "";
318 typeMask += SkMatrix::kTranslate_Mask & matrix.getType() ? "kTranslate_Mask " : "";
319 typeMask += SkMatrix::kScale_Mask & matrix.getType() ? "kScale_Mask " : "";
320 typeMask += SkMatrix::kAffine_Mask & matrix.getType() ? "kAffine_Mask " : "";
321 typeMask += SkMatrix::kPerspective_Mask & matrix.getType() ? "kPerspective_Mask" : "";
322 SkDebugf("after %s: %s\n", prefix, typeMask.c_str());
323 };
324SkMatrix matrix;
325matrix.reset();
326debugster("reset", matrix);
327matrix.postTranslate(1, 0);
328debugster("postTranslate", matrix);
329matrix.postScale(2, 1);
330debugster("postScale", matrix);
331matrix.postRotate(45);
332debugster("postScale", matrix);
333SkPoint polys[][4] = {{{0, 0}, {0, 1}, {1, 1}, {1, 0}}, {{0, 0}, {0, 1}, {2, 1}, {1, 0}}};
334matrix.setPolyToPoly(polys[0], polys[1], 4);
335debugster("setPolyToPoly", matrix);
336#StdOut
337after reset: kIdentity_Mask
338after postTranslate: kTranslate_Mask
339after postScale: kTranslate_Mask kScale_Mask
340after postScale: kTranslate_Mask kScale_Mask kAffine_Mask
341after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask
342##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400343##
344
Cary Clark154beea2017-10-26 07:58:48 -0400345#SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400346
347##
348
349# ------------------------------------------------------------------------------
350
351#Method TypeMask getType() const
352
353Returns a bit field describing the transformations the matrix may
354perform. The bit field is computed conservatively, so it may include
Cary Clark154beea2017-10-26 07:58:48 -0400355false positives. For example, when kPerspective_Mask is set, all
356other bits are set.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400357
Cary Clark154beea2017-10-26 07:58:48 -0400358#Return kIdentity_Mask, or combinations of: kTranslate_Mask, kScale_Mask,
359 kAffine_Mask, kPerspective_Mask
Cary Clarkbc5697d2017-10-04 14:31:33 -0400360##
361
Cary Clark154beea2017-10-26 07:58:48 -0400362#Example
363SkMatrix matrix;
364matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
365SkDebugf("identity flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
366matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, .5f);
367SkDebugf("set all flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
368#StdOut
369identity flags hex: 0 decimal: 0
370set all flags hex: f decimal: 15
371##
372##
373
374#SeeAlso TypeMask
Cary Clarkbc5697d2017-10-04 14:31:33 -0400375
376##
377
378# ------------------------------------------------------------------------------
379
380#Method bool isIdentity() const
381
Cary Clark154beea2017-10-26 07:58:48 -0400382Returns true if Matrix is identity. Identity matrix is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400383
Cary Clark154beea2017-10-26 07:58:48 -0400384#Code
385#Literal
386| 1 0 0 |
387| 0 1 0 |
388| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400389##
390
Cary Clark154beea2017-10-26 07:58:48 -0400391#Return true if Matrix has no effect ##
392
393#Example
394SkMatrix matrix;
395matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
396SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
397matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 2);
398SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
399#StdOut
400is identity: true
401is identity: false
402##
403##
404
405#SeeAlso reset() setIdentity getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400406
407##
408
409# ------------------------------------------------------------------------------
410
411#Method bool isScaleTranslate() const
412
Cary Clark154beea2017-10-26 07:58:48 -0400413Returns true if Matrix at most scales and translates. Matrix may be identity,
414contain only scale elements, only translate elements, or both. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400415
Cary Clark154beea2017-10-26 07:58:48 -0400416#Code
417#Literal
418| scale-x 0 translate-x |
419| 0 scale-y translate-y |
420| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400421##
422
Cary Clark154beea2017-10-26 07:58:48 -0400423#Return true if Matrix is identity; or scales, translates, or both ##
424
425#Example
426SkMatrix matrix;
427for (SkScalar scaleX : { 1, 2 } ) {
428 for (SkScalar translateX : { 0, 20 } ) {
429 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
430 SkDebugf("is scale-translate: %s\n", matrix.isScaleTranslate() ? "true" : "false");
431 }
432}
433#StdOut
434is scale-translate: true
435is scale-translate: true
436is scale-translate: true
437is scale-translate: true
438##
439##
440
441#SeeAlso setScale isTranslate setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400442
443##
444
445# ------------------------------------------------------------------------------
446
447#Method bool isTranslate() const
448
Cary Clark154beea2017-10-26 07:58:48 -0400449Returns true if Matrix is identity, or translates. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400450
Cary Clark154beea2017-10-26 07:58:48 -0400451#Code
452#Literal
453| 1 0 translate-x |
454| 0 1 translate-y |
455| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400456##
457
Cary Clark154beea2017-10-26 07:58:48 -0400458#Return true if Matrix is identity, or translates ##
459
460#Example
461SkMatrix matrix;
462for (SkScalar scaleX : { 1, 2 } ) {
463 for (SkScalar translateX : { 0, 20 } ) {
464 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
465 SkDebugf("is translate: %s\n", matrix.isTranslate() ? "true" : "false");
466 }
467}
468#StdOut
469is translate: true
470is translate: true
471is translate: false
472is translate: false
473##
474##
475
476#SeeAlso setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400477
478##
479
480# ------------------------------------------------------------------------------
481
482#Method bool rectStaysRect() const
483
Cary Clark154beea2017-10-26 07:58:48 -0400484Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
485or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
486cases, Matrix may also have translation. Matrix form is either:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400487
Cary Clark154beea2017-10-26 07:58:48 -0400488#Code
489#Literal
490| scale-x 0 translate-x |
491| 0 scale-y translate-y |
492| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400493##
494
Cary Clark154beea2017-10-26 07:58:48 -0400495or
496
497#Code
498#Literal
499| 0 rotate-x translate-x |
500| rotate-y 0 translate-y |
501| 0 0 1 |
502##
503
504for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
505
506Also called preservesAxisAlignment; use the one that provides better inline
507documentation.
508
509#Return true if Matrix maps one Rect into another ##
510
511#Example
512SkMatrix matrix;
513for (SkScalar angle: { 0, 90, 180, 270 } ) {
514 matrix.setRotate(angle);
515 SkDebugf("rectStaysRect: %s\n", matrix.rectStaysRect() ? "true" : "false");
516}
517#StdOut
518rectStaysRect: true
519rectStaysRect: true
520rectStaysRect: true
521rectStaysRect: true
522##
523##
524
525#SeeAlso preservesAxisAlignment preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400526
527##
528
529# ------------------------------------------------------------------------------
530
531#Method bool preservesAxisAlignment() const
532
Cary Clarkbc5697d2017-10-04 14:31:33 -0400533
Cary Clark154beea2017-10-26 07:58:48 -0400534Returns true Matrix maps Rect to another Rect. If true, Matrix is identity,
535or scales, or rotates a multiple of 90 degrees, or mirrors in x or y. In all
536cases, Matrix may also have translation. Matrix form is either:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400537
Cary Clark154beea2017-10-26 07:58:48 -0400538#Code
539#Literal
540| scale-x 0 translate-x |
541| 0 scale-y translate-y |
542| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400543##
544
Cary Clark154beea2017-10-26 07:58:48 -0400545or
546
547#Code
548#Literal
549| 0 rotate-x translate-x |
550| rotate-y 0 translate-y |
551| 0 0 1 |
552##
553
554for non-zero values of scale-x, scale-y, rotate-x, and rotate-y.
555
556Also called rectStaysRect; use the one that provides better inline
557documentation.
558
559#Return true if Matrix maps one Rect into another ##
560
561#Example
562SkMatrix matrix;
563for (SkScalar angle: { 0, 90, 180, 270 } ) {
564 matrix.setRotate(angle);
565 SkDebugf("preservesAxisAlignment: %s\n", matrix.preservesAxisAlignment() ? "true" : "false");
566}
567#StdOut
568preservesAxisAlignment: true
569preservesAxisAlignment: true
570preservesAxisAlignment: true
571preservesAxisAlignment: true
572##
573##
574
575#SeeAlso rectStaysRect preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400576
577##
578
579# ------------------------------------------------------------------------------
580
581#Method bool hasPerspective() const
582
Cary Clark154beea2017-10-26 07:58:48 -0400583Returns true if the matrix contains perspective elements. Matrix form is:
Cary Clarkbc5697d2017-10-04 14:31:33 -0400584
Cary Clark154beea2017-10-26 07:58:48 -0400585#Code
586#Literal
587| -- -- -- |
588| -- -- -- |
589| perspective-x perspective-y perspective-scale |
Cary Clarkbc5697d2017-10-04 14:31:33 -0400590##
591
Cary Clark154beea2017-10-26 07:58:48 -0400592where perspective-x or perspective-y is non-zero, or perspective-scale is
593not one. All other elements may have any value.
594
595#Return true if Matrix is in most general form ##
596
597#Example
598#Image 4
599SkMatrix matrix;
600SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
601SkRect::Make(source.bounds()).toQuad(bitmapBounds);
602matrix.setPolyToPoly(bitmapBounds, perspect, 4);
603canvas->concat(matrix);
604SkString string;
605string.printf("hasPerspective %s", matrix.hasPerspective() ? "true" : "false");
606canvas->drawBitmap(source, 0, 0);
607SkPaint paint;
608paint.setAntiAlias(true);
609paint.setTextSize(48);
610canvas->drawString(string, 0, source.bounds().height() + 48, paint);
611##
612
Cary Clarkbef063a2017-10-31 15:44:45 -0400613#SeeAlso setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -0400614
615##
616
617# ------------------------------------------------------------------------------
618
619#Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const
620
Cary Clark154beea2017-10-26 07:58:48 -0400621Returns true if Matrix contains only translation, rotation, reflection, and
622uniform scale.
623Returns false if Matrix contains different scales, skewing, perspective, or
624degenerate forms that collapse to a line or point.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400625
Cary Clark154beea2017-10-26 07:58:48 -0400626Describes that the Matrix makes rendering with and without the matrix are
627visually alike; a transformed circle remains a circle. Mathematically, this is
Cary Clarka560c472017-11-27 10:44:06 -0500628referred to as similarity of a Euclidean_Space, or a similarity transformation.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400629
Cary Clark154beea2017-10-26 07:58:48 -0400630Preserves right angles, keeping the arms of the angle equal lengths.
631
632#Param tol to be deprecated ##
633
634#Return true if Matrix only rotates, uniformly scales, translates ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400635
636#Example
Cary Clark154beea2017-10-26 07:58:48 -0400637#Description
638String is drawn four times through but only two are visible. Drawing the pair
639with isSimilarity false reveals the pair not visible through the matrix.
640##
641 SkPaint p;
642 p.setAntiAlias(true);
643 SkMatrix m;
644 int below = 175;
645 for (SkScalar sx : { -1, 1 } ) {
646 for (SkScalar sy : { -1, 1 } ) {
647 m.setAll(sx, 1, 128, 1, sy, 32, 0, 0, 1);
648 bool isSimilarity = m.isSimilarity();
649 SkString str;
650 str.printf("sx: %g sy: %g sim: %s", sx, sy, isSimilarity ? "true" : "false");
651 {
652 SkAutoCanvasRestore autoRestore(canvas, true);
653 canvas->concat(m);
654 canvas->drawString(str, 0, 0, p);
655 }
656 if (!isSimilarity) {
657 canvas->drawString(str, 40, below, p);
658 below += 20;
659 }
660 }
661 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400662##
663
Cary Clark154beea2017-10-26 07:58:48 -0400664#SeeAlso isScaleTranslate preservesRightAngles rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400665
666##
667
668# ------------------------------------------------------------------------------
669
670#Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const
671
Cary Clark154beea2017-10-26 07:58:48 -0400672Returns true if Matrix contains only translation, rotation, reflection, and
673scale. Scale may differ along rotated axes.
674Returns false if Matrix skewing, perspective, or degenerate forms that collapse
675to a line or point.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400676
Cary Clark154beea2017-10-26 07:58:48 -0400677Preserves right angles, but not requiring that the arms of the angle
678retain equal lengths.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400679
Cary Clark154beea2017-10-26 07:58:48 -0400680#Param tol to be deprecated ##
681
682#Return true if Matrix only rotates, scales, translates ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400683
684#Example
Cary Clark154beea2017-10-26 07:58:48 -0400685#Height 128
686#Description
687Equal scale is both similar and preserves right angles.
688Unequal scale is not similar but preserves right angles.
689Skews are not similar and do not preserve right angles.
690##
691SkPaint p;
692p.setAntiAlias(true);
693SkMatrix m;
694int pos = 0;
695for (SkScalar sx : { 1, 2 } ) {
696 for (SkScalar kx : { 0, 1 } ) {
697 m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1);
698 bool isSimilarity = m.isSimilarity();
699 bool preservesRightAngles = m.preservesRightAngles();
700 SkString str;
701 str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "",
702 preservesRightAngles ? "right" : "");
703 SkAutoCanvasRestore autoRestore(canvas, true);
704 canvas->concat(m);
705 canvas->drawString(str, 0, pos, p);
706 pos += 20;
707 }
708}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400709##
710
Cary Clark154beea2017-10-26 07:58:48 -0400711#SeeAlso isScaleTranslate isSimilarity rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400712
713##
714
715# ------------------------------------------------------------------------------
716
Cary Clark154beea2017-10-26 07:58:48 -0400717#Enum
Cary Clarkbc5697d2017-10-04 14:31:33 -0400718
719#Code
720 enum {
721 kMScaleX,
722 kMSkewX,
723 kMTransX,
724 kMSkewY,
725 kMScaleY,
726 kMTransY,
727 kMPersp0,
728 kMPersp1,
729 kMPersp2,
730 };
731##
732
Cary Clark154beea2017-10-26 07:58:48 -0400733Matrix organizes its values in row order. These members correspond to
734each value in Matrix.
735
Cary Clarkbc5697d2017-10-04 14:31:33 -0400736#Const kMScaleX 0
Cary Clark154beea2017-10-26 07:58:48 -0400737horizontal scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400738##
739#Const kMSkewX 1
Cary Clark154beea2017-10-26 07:58:48 -0400740horizontal skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400741##
742#Const kMTransX 2
Cary Clark154beea2017-10-26 07:58:48 -0400743horizontal translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400744##
745#Const kMSkewY 3
Cary Clark154beea2017-10-26 07:58:48 -0400746vertical skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400747##
748#Const kMScaleY 4
Cary Clark154beea2017-10-26 07:58:48 -0400749vertical scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400750##
751#Const kMTransY 5
Cary Clark154beea2017-10-26 07:58:48 -0400752vertical translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400753##
754#Const kMPersp0 6
Cary Clark154beea2017-10-26 07:58:48 -0400755input x perspective factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400756##
757#Const kMPersp1 7
Cary Clark154beea2017-10-26 07:58:48 -0400758input y perspective factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400759##
760#Const kMPersp2 8
Cary Clark154beea2017-10-26 07:58:48 -0400761perspective bias
Cary Clarkbc5697d2017-10-04 14:31:33 -0400762##
763
764#Example
Cary Clark154beea2017-10-26 07:58:48 -0400765SkPaint black;
766black.setAntiAlias(true);
767black.setTextSize(48);
768SkPaint gray = black;
769gray.setColor(0xFF9f9f9f);
770SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 };
771for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX,
772 SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY,
773 SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) {
774 SkMatrix m;
775 m.setIdentity();
776 m.set(i, offset[i]);
777 SkAutoCanvasRestore autoRestore(canvas, true);
778 canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88);
779 canvas->drawString("&", 0, 0, gray);
780 canvas->concat(m);
781 canvas->drawString("&", 0, 0, black);
782}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400783##
784
Cary Clark154beea2017-10-26 07:58:48 -0400785#SeeAlso get() set()
Cary Clarkbc5697d2017-10-04 14:31:33 -0400786
787##
788
789# ------------------------------------------------------------------------------
790
Cary Clark154beea2017-10-26 07:58:48 -0400791#Enum
Cary Clarkbc5697d2017-10-04 14:31:33 -0400792
793#Code
794 enum {
795 kAScaleX,
796 kASkewY,
797 kASkewX,
798 kAScaleY,
799 kATransX,
800 kATransY,
801 };
802##
803
Cary Clark154beea2017-10-26 07:58:48 -0400804Affine arrays are in column major order to match the matrix used by
805PDF and XPS.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400806
807#Const kAScaleX 0
Cary Clark154beea2017-10-26 07:58:48 -0400808horizontal scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400809##
810#Const kASkewY 1
Cary Clark154beea2017-10-26 07:58:48 -0400811vertical skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400812##
813#Const kASkewX 2
Cary Clark154beea2017-10-26 07:58:48 -0400814horizontal skew factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400815##
816#Const kAScaleY 3
Cary Clark154beea2017-10-26 07:58:48 -0400817vertical scale factor
Cary Clarkbc5697d2017-10-04 14:31:33 -0400818##
819#Const kATransX 4
Cary Clark154beea2017-10-26 07:58:48 -0400820horizontal translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400821##
822#Const kATransY 5
Cary Clark154beea2017-10-26 07:58:48 -0400823vertical translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400824##
825
Cary Clark154beea2017-10-26 07:58:48 -0400826#NoExample
Cary Clarkbc5697d2017-10-04 14:31:33 -0400827##
828
Cary Clark154beea2017-10-26 07:58:48 -0400829#SeeAlso SetAffineIdentity asAffine setAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -0400830
831##
832
833# ------------------------------------------------------------------------------
834
Cary Clarka560c472017-11-27 10:44:06 -0500835#Method SkScalar operator[](int index)_const
Cary Clarkbc5697d2017-10-04 14:31:33 -0400836
Cary Clark154beea2017-10-26 07:58:48 -0400837Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
838defined.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400839
Cary Clark154beea2017-10-26 07:58:48 -0400840#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
841 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -0400842##
843
Cary Clark154beea2017-10-26 07:58:48 -0400844#Return value corresponding to index ##
845
846#Example
847SkMatrix matrix;
848matrix.setScale(42, 24);
849SkDebugf("matrix[SkMatrix::kMScaleX] %c= 42\n", matrix[SkMatrix::kMScaleX] == 42 ? '=' : '!');
850SkDebugf("matrix[SkMatrix::kMScaleY] %c= 24\n", matrix[SkMatrix::kMScaleY] == 24 ? '=' : '!');
851#StdOut
852matrix[SkMatrix::kMScaleX] == 42
853matrix[SkMatrix::kMScaleY] == 24
854##
855##
856
857#SeeAlso get set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400858
859##
860
861# ------------------------------------------------------------------------------
862
863#Method SkScalar get(int index) const
864
Cary Clark154beea2017-10-26 07:58:48 -0400865Returns one matrix value. Asserts if index is out of range and SK_DEBUG is
866defined.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400867
Cary Clark154beea2017-10-26 07:58:48 -0400868#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
869 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -0400870##
871
Cary Clark154beea2017-10-26 07:58:48 -0400872#Return value corresponding to index ##
873
874#Example
875SkMatrix matrix;
876matrix.setSkew(42, 24);
877SkDebugf("matrix.get(SkMatrix::kMSkewX) %c= 42\n",
878 matrix.get(SkMatrix::kMSkewX) == 42 ? '=' : '!');
879SkDebugf("matrix.get(SkMatrix::kMSkewY) %c= 24\n",
880 matrix.get(SkMatrix::kMSkewY) == 24 ? '=' : '!');
881#StdOut
882matrix.get(SkMatrix::kMSkewX) == 42
883matrix.get(SkMatrix::kMSkewY) == 24
884##
885##
886
887#SeeAlso operator[](int index) set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400888
889##
890
891# ------------------------------------------------------------------------------
892
893#Method SkScalar getScaleX() const
894
Cary Clark154beea2017-10-26 07:58:48 -0400895Returns scale factor multiplied by x input, contributing to x output.
896With mapPoints, scales Points along the x-axis.
897
898#Return horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400899
900#Example
Cary Clark154beea2017-10-26 07:58:48 -0400901SkMatrix matrix;
902matrix.setScale(42, 24);
903SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!');
904#StdOut
905matrix.getScaleX() == 42
906##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400907##
908
Cary Clark154beea2017-10-26 07:58:48 -0400909#SeeAlso get getScaleY setScaleX setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400910
911##
912
913# ------------------------------------------------------------------------------
914
915#Method SkScalar getScaleY() const
916
Cary Clark154beea2017-10-26 07:58:48 -0400917Returns scale factor multiplied by y input, contributing to y output.
918With mapPoints, scales Points along the y-axis.
919
920#Return vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400921
922#Example
Cary Clark154beea2017-10-26 07:58:48 -0400923SkMatrix matrix;
924matrix.setScale(42, 24);
925SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!');
926#StdOut
927matrix.getScaleY() == 24
928##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400929##
930
Cary Clark154beea2017-10-26 07:58:48 -0400931#SeeAlso get getScaleX setScaleY setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400932
933##
934
935# ------------------------------------------------------------------------------
936
937#Method SkScalar getSkewY() const
938
Cary Clark154beea2017-10-26 07:58:48 -0400939Returns scale factor multiplied by x input, contributing to y output.
940With mapPoints, skews Points along the y-axis.
941Skew x and y together can rotate Points.
942
943#Return vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400944
945#Example
Cary Clark154beea2017-10-26 07:58:48 -0400946SkMatrix matrix;
947matrix.setSkew(42, 24);
948SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!');
949#StdOut
950matrix.getSkewY() == 24
951##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400952##
953
Cary Clark154beea2017-10-26 07:58:48 -0400954#SeeAlso get getSkewX setSkewY setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400955
956##
957
958# ------------------------------------------------------------------------------
959
960#Method SkScalar getSkewX() const
961
Cary Clark154beea2017-10-26 07:58:48 -0400962Returns scale factor multiplied by y input, contributing to x output.
963With mapPoints, skews Points along the x-axis.
964Skew x and y together can rotate Points.
965
966#Return horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400967
968#Example
Cary Clark154beea2017-10-26 07:58:48 -0400969SkMatrix matrix;
970matrix.setSkew(42, 24);
971SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!');
972#StdOut
973matrix.getSkewX() == 42
974##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400975##
976
Cary Clark154beea2017-10-26 07:58:48 -0400977#SeeAlso get getSkewY setSkewX setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400978
979##
980
981# ------------------------------------------------------------------------------
982
983#Method SkScalar getTranslateX() const
984
Cary Clark154beea2017-10-26 07:58:48 -0400985Returns translation contributing to x output.
986With mapPoints, moves Points along the x-axis.
987
988#Return horizontal translation factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400989
990#Example
Cary Clark154beea2017-10-26 07:58:48 -0400991SkMatrix matrix;
992matrix.setTranslate(42, 24);
993SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!');
994#StdOut
995matrix.getTranslateX() == 42
996##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400997##
998
Cary Clark154beea2017-10-26 07:58:48 -0400999#SeeAlso get getTranslateY setTranslateX setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001000
1001##
1002
1003# ------------------------------------------------------------------------------
1004
1005#Method SkScalar getTranslateY() const
1006
Cary Clark154beea2017-10-26 07:58:48 -04001007Returns translation contributing to y output.
1008With mapPoints, moves Points along the y-axis.
1009
1010#Return vertical translation factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001011
1012#Example
Cary Clark154beea2017-10-26 07:58:48 -04001013SkMatrix matrix;
1014matrix.setTranslate(42, 24);
1015SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!');
1016#StdOut
1017matrix.getTranslateY() == 24
1018##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001019##
1020
Cary Clark154beea2017-10-26 07:58:48 -04001021#SeeAlso get getTranslateX setTranslateY setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001022
1023##
1024
1025# ------------------------------------------------------------------------------
1026
1027#Method SkScalar getPerspX() const
1028
Cary Clark154beea2017-10-26 07:58:48 -04001029Returns factor scaling input x relative to input y.
1030
1031#Return input x perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001032
1033#Example
Cary Clark154beea2017-10-26 07:58:48 -04001034 SkMatrix m;
1035 m.setIdentity();
1036 m.set(SkMatrix::kMPersp0, -0.004f);
1037 SkAutoCanvasRestore autoRestore(canvas, true);
1038 canvas->translate(22, 144);
1039 SkPaint black;
1040 black.setAntiAlias(true);
1041 black.setTextSize(24);
1042 SkPaint gray = black;
1043 gray.setColor(0xFF9f9f9f);
1044 SkString string;
1045 string.appendScalar(m.getPerspX());
1046 canvas->drawString(string, 0, -72, gray);
1047 canvas->concat(m);
1048 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001049##
1050
Cary Clark154beea2017-10-26 07:58:48 -04001051#SeeAlso kMPersp0 getPerspY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001052
1053##
1054
1055# ------------------------------------------------------------------------------
1056
1057#Method SkScalar getPerspY() const
1058
Cary Clark154beea2017-10-26 07:58:48 -04001059
1060Returns factor scaling input y relative to input x.
1061
1062#Return input y perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001063
1064#Example
Cary Clark154beea2017-10-26 07:58:48 -04001065 SkMatrix m;
1066 m.setIdentity();
1067 m.set(SkMatrix::kMPersp1, -0.004f);
1068 SkAutoCanvasRestore autoRestore(canvas, true);
1069 canvas->translate(22, 144);
1070 SkPaint black;
1071 black.setAntiAlias(true);
1072 black.setTextSize(24);
1073 SkPaint gray = black;
1074 gray.setColor(0xFF9f9f9f);
1075 SkString string;
1076 string.appendScalar(m.getPerspY());
1077 canvas->drawString(string, 0, -72, gray);
1078 canvas->concat(m);
1079 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001080##
1081
Cary Clark154beea2017-10-26 07:58:48 -04001082#SeeAlso kMPersp1 getPerspX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001083
1084##
1085
1086# ------------------------------------------------------------------------------
1087
Cary Clark154beea2017-10-26 07:58:48 -04001088#Method SkScalar& operator[](int index)
Cary Clarkbc5697d2017-10-04 14:31:33 -04001089
Cary Clark154beea2017-10-26 07:58:48 -04001090Returns writable Matrix value. Asserts if index is out of range and SK_DEBUG is
1091defined. Clears internal cache anticipating that caller will change Matrix value.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001092
Cary Clark154beea2017-10-26 07:58:48 -04001093Next call to read Matrix state may recompute cache; subsequent writes to Matrix
1094value must be followed by dirtyMatrixTypeCache.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001095
Cary Clark154beea2017-10-26 07:58:48 -04001096#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1097 kMPersp0, kMPersp1, kMPersp2
Cary Clarkbc5697d2017-10-04 14:31:33 -04001098##
1099
Cary Clark154beea2017-10-26 07:58:48 -04001100#Return writable value corresponding to index ##
1101
1102#Example
1103SkMatrix matrix;
1104matrix.setIdentity();
1105SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
1106SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
1107skewRef = 0;
1108SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1109skewRef = 1;
1110SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1111matrix.dirtyMatrixTypeCache();
1112SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
1113#StdOut
1114with identity matrix: x = 24
1115after skew x mod: x = 24
1116after 2nd skew x mod: x = 24
1117after dirty cache: x = 66
1118##
1119##
1120
1121#SeeAlso get dirtyMatrixTypeCache set
Cary Clarkbc5697d2017-10-04 14:31:33 -04001122
1123##
1124
1125# ------------------------------------------------------------------------------
1126
1127#Method void set(int index, SkScalar value)
1128
Cary Clark154beea2017-10-26 07:58:48 -04001129Sets Matrix value. Asserts if index is out of range and SK_DEBUG is
1130defined. Safer than operator[]; internal cache is always maintained.
1131
1132#Param index one of: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1133 kMPersp0, kMPersp1, kMPersp2
1134##
1135#Param value Scalar to store in Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001136
1137#Example
Cary Clark154beea2017-10-26 07:58:48 -04001138SkMatrix matrix;
1139matrix.setIdentity();
1140SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
1141matrix.set(SkMatrix::kMSkewX, 0);
1142SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1143matrix.set(SkMatrix::kMSkewX, 1);
1144SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
1145#StdOut
1146with identity matrix: x = 24
1147after skew x mod: x = 24
1148after 2nd skew x mod: x = 66
1149##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001150##
1151
Cary Clark154beea2017-10-26 07:58:48 -04001152#SeeAlso operator[] get
Cary Clarkbc5697d2017-10-04 14:31:33 -04001153
Cary Clark154beea2017-10-26 07:58:48 -04001154#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001155
1156# ------------------------------------------------------------------------------
1157
1158#Method void setScaleX(SkScalar v)
1159
Cary Clark154beea2017-10-26 07:58:48 -04001160Sets horizontal scale factor.
1161
1162#Param v horizontal scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001163
1164#Example
Cary Clark154beea2017-10-26 07:58:48 -04001165#Height 64
1166SkPaint paint;
1167paint.setAntiAlias(true);
1168paint.setTextSize(24);
1169canvas->drawString("normal", 12, 24, paint);
1170SkMatrix matrix;
1171matrix.setIdentity();
1172matrix.setScaleX(3);
1173canvas->concat(matrix);
1174canvas->drawString("x scale", 0, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001175##
1176
Cary Clark154beea2017-10-26 07:58:48 -04001177#SeeAlso set setScale setScaleY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001178
Cary Clark154beea2017-10-26 07:58:48 -04001179#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001180
1181# ------------------------------------------------------------------------------
1182
1183#Method void setScaleY(SkScalar v)
1184
Cary Clark154beea2017-10-26 07:58:48 -04001185Sets vertical scale factor.
1186
1187#Param v vertical scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001188
1189#Example
Cary Clark154beea2017-10-26 07:58:48 -04001190#Height 192
1191SkPaint paint;
1192paint.setAntiAlias(true);
1193paint.setTextSize(24);
1194canvas->drawString("normal", 12, 24, paint);
1195SkMatrix matrix;
1196matrix.setIdentity();
1197matrix.setScaleY(3);
1198canvas->concat(matrix);
1199canvas->drawString("y scale", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001200##
1201
Cary Clark154beea2017-10-26 07:58:48 -04001202#SeeAlso set setScale setScaleX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001203
Cary Clark154beea2017-10-26 07:58:48 -04001204#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001205
1206# ------------------------------------------------------------------------------
1207
1208#Method void setSkewY(SkScalar v)
1209
Cary Clark154beea2017-10-26 07:58:48 -04001210Sets vertical skew factor.
1211
1212#Param v vertical skew factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001213
1214#Example
Cary Clark154beea2017-10-26 07:58:48 -04001215#Height 96
1216SkPaint paint;
1217paint.setAntiAlias(true);
1218paint.setTextSize(24);
1219canvas->drawString("normal", 12, 24, paint);
1220SkMatrix matrix;
1221matrix.setIdentity();
1222matrix.setSkewY(.3f);
1223canvas->concat(matrix);
1224canvas->drawString("y skew", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001225##
1226
Cary Clark154beea2017-10-26 07:58:48 -04001227#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001228
Cary Clark154beea2017-10-26 07:58:48 -04001229#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001230
1231# ------------------------------------------------------------------------------
1232
1233#Method void setSkewX(SkScalar v)
1234
Cary Clark154beea2017-10-26 07:58:48 -04001235Sets horizontal skew factor.
1236
1237#Param v horizontal skew factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001238
1239#Example
Cary Clark154beea2017-10-26 07:58:48 -04001240#Height 64
1241SkPaint paint;
1242paint.setAntiAlias(true);
1243paint.setTextSize(24);
1244canvas->drawString("normal", 12, 24, paint);
1245SkMatrix matrix;
1246matrix.setIdentity();
1247matrix.setSkewX(-.7f);
1248canvas->concat(matrix);
1249canvas->drawString("x skew", 36, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001250##
1251
Cary Clark154beea2017-10-26 07:58:48 -04001252#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001253
Cary Clark154beea2017-10-26 07:58:48 -04001254#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001255
1256# ------------------------------------------------------------------------------
1257
1258#Method void setTranslateX(SkScalar v)
1259
Cary Clark154beea2017-10-26 07:58:48 -04001260Sets horizontal translation.
1261
1262#Param v horizontal translation to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001263
1264#Example
Cary Clark154beea2017-10-26 07:58:48 -04001265#Height 48
1266SkPaint paint;
1267paint.setAntiAlias(true);
1268paint.setTextSize(24);
1269canvas->drawString("normal", 8, 24, paint);
1270SkMatrix matrix;
1271matrix.setIdentity();
1272matrix.setTranslateX(96);
1273canvas->concat(matrix);
1274canvas->drawString("x translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001275##
1276
Cary Clark154beea2017-10-26 07:58:48 -04001277#SeeAlso set setTranslate setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001278
Cary Clark154beea2017-10-26 07:58:48 -04001279#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001280
1281# ------------------------------------------------------------------------------
1282
1283#Method void setTranslateY(SkScalar v)
1284
Cary Clark154beea2017-10-26 07:58:48 -04001285Sets vertical translation.
1286
1287#Param v vertical translation to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001288
1289#Example
Cary Clark154beea2017-10-26 07:58:48 -04001290#Height 64
1291SkPaint paint;
1292paint.setAntiAlias(true);
1293paint.setTextSize(24);
1294canvas->drawString("normal", 8, 24, paint);
1295SkMatrix matrix;
1296matrix.setIdentity();
1297matrix.setTranslateY(24);
1298canvas->concat(matrix);
1299canvas->drawString("y translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001300##
1301
Cary Clark154beea2017-10-26 07:58:48 -04001302#SeeAlso set setTranslate setTranslateX
Cary Clarkbc5697d2017-10-04 14:31:33 -04001303
Cary Clark154beea2017-10-26 07:58:48 -04001304#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001305
1306# ------------------------------------------------------------------------------
1307
1308#Method void setPerspX(SkScalar v)
1309
Cary Clark154beea2017-10-26 07:58:48 -04001310Sets input x perspective factor, which causes mapXY to vary input x inversely
1311proportional to input y.
1312
1313#Param v perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001314
1315#Example
Cary Clark154beea2017-10-26 07:58:48 -04001316#Image 4
1317for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
1318 SkMatrix matrix;
1319 matrix.setIdentity();
1320 matrix.setPerspX(perspX);
1321 canvas->save();
1322 canvas->concat(matrix);
1323 canvas->drawBitmap(source, 0, 0);
1324 canvas->restore();
1325 canvas->translate(64, 64);
1326}
Cary Clarkbc5697d2017-10-04 14:31:33 -04001327##
1328
Cary Clarkbef063a2017-10-31 15:44:45 -04001329#SeeAlso getPerspX set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001330
Cary Clark154beea2017-10-26 07:58:48 -04001331#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001332
1333# ------------------------------------------------------------------------------
1334
1335#Method void setPerspY(SkScalar v)
1336
Cary Clark154beea2017-10-26 07:58:48 -04001337Sets input y perspective factor, which causes mapXY to vary input y inversely
1338proportional to input x.
1339
1340#Param v perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001341
1342#Example
Cary Clark154beea2017-10-26 07:58:48 -04001343#Image 4
1344for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
1345 SkMatrix matrix;
1346 matrix.setIdentity();
1347 matrix.setPerspY(perspX);
1348 canvas->save();
1349 canvas->concat(matrix);
1350 canvas->drawBitmap(source, 0, 0);
1351 canvas->restore();
1352 canvas->translate(64, 64);
1353}
Cary Clarkbc5697d2017-10-04 14:31:33 -04001354##
1355
Cary Clarkbef063a2017-10-31 15:44:45 -04001356#SeeAlso getPerspY set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001357
Cary Clark154beea2017-10-26 07:58:48 -04001358#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001359
1360# ------------------------------------------------------------------------------
1361
1362#Method void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
1363 SkScalar skewY, SkScalar scaleY, SkScalar transY,
1364 SkScalar persp0, SkScalar persp1, SkScalar persp2)
1365
Cary Clark154beea2017-10-26 07:58:48 -04001366Sets all values from parameters. Sets matrix to:
1367
1368#Code
1369#Literal
1370| scaleX skewX transX |
1371| skewY scaleY transY |
1372| persp0 persp1 persp2 |
1373##
1374
1375#Param scaleX horizontal scale factor to store ##
1376#Param skewX horizontal skew factor to store ##
1377#Param transX horizontal translation to store ##
1378#Param skewY vertical skew factor to store ##
1379#Param scaleY vertical scale factor to store ##
1380#Param transY vertical translation to store ##
1381#Param persp0 input x perspective factor to store ##
1382#Param persp1 input y perspective factor to store ##
1383#Param persp2 perspective scale factor to store ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001384
1385#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001386#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001387 SkPaint p;
1388 p.setAntiAlias(true);
1389 p.setTextSize(64);
1390 SkMatrix m;
1391 for (SkScalar sx : { -1, 1 } ) {
1392 for (SkScalar sy : { -1, 1 } ) {
1393 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001394 m.setAll(sx, 1, 128, 0, sy, 64, 0, 0, 1);
Cary Clark154beea2017-10-26 07:58:48 -04001395 canvas->concat(m);
1396 canvas->drawString("K", 0, 0, p);
1397 }
1398 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001399##
1400
Cary Clarkbef063a2017-10-31 15:44:45 -04001401#SeeAlso set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001402
Cary Clark154beea2017-10-26 07:58:48 -04001403#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001404
1405# ------------------------------------------------------------------------------
1406
1407#Method void get9(SkScalar buffer[9]) const
1408
Cary Clark154beea2017-10-26 07:58:48 -04001409Copies nine Scalar values contained by Matrix into buffer, in member value
1410ascending order: kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY,
1411kMPersp0, kMPersp1, kMPersp2.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001412
Cary Clark154beea2017-10-26 07:58:48 -04001413#Param buffer storage for nine Scalar values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001414
1415#Example
Cary Clark154beea2017-10-26 07:58:48 -04001416SkMatrix matrix = SkMatrix::MakeRectToRect({0, 0, 1, 1}, {3, 4, 7, 9},
1417 SkMatrix::kFill_ScaleToFit);
1418SkScalar b[9];
1419matrix.get9(b);
1420SkDebugf("{%g, %g, %g},\n{%g, %g, %g},\n{%g, %g, %g}\n", b[0], b[1], b[2],
1421 b[3], b[4], b[5], b[6], b[7], b[8]);
1422#StdOut
1423{4, 0, 3},
1424{0, 5, 4},
1425{0, 0, 1}
1426##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001427##
1428
Cary Clark154beea2017-10-26 07:58:48 -04001429#SeeAlso set9
Cary Clarkbc5697d2017-10-04 14:31:33 -04001430
Cary Clark154beea2017-10-26 07:58:48 -04001431#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001432
1433# ------------------------------------------------------------------------------
1434
1435#Method void set9(const SkScalar buffer[9])
1436
Cary Clark154beea2017-10-26 07:58:48 -04001437Sets Matrix to nine Scalar values in buffer, in member value ascending order:
1438kMScaleX, kMSkewX, kMTransX, kMSkewY, kMScaleY, kMTransY, kMPersp0, kMPersp1,
1439kMPersp2.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001440
Cary Clark154beea2017-10-26 07:58:48 -04001441Sets matrix to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04001442
Cary Clark154beea2017-10-26 07:58:48 -04001443#Code
1444#Literal
1445| buffer[0] buffer[1] buffer[2] |
1446| buffer[3] buffer[4] buffer[5] |
1447| buffer[6] buffer[7] buffer[8] |
1448##
1449
1450In the future, set9 followed by get9 may not return the same values. Since Matrix
1451maps non-homogeneous coordinates, scaling all nine values produces an equivalent
1452transformation, possibly improving precision.
1453
1454#Param buffer nine Scalar values ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001455
1456#Example
Cary Clark154beea2017-10-26 07:58:48 -04001457#Image 4
1458SkMatrix m;
1459SkScalar buffer[9] = {4, 0, 3, 0, 5, 4, 0, 0, 1};
1460m.set9(buffer);
1461canvas->concat(m);
1462canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001463##
1464
Cary Clarkbef063a2017-10-31 15:44:45 -04001465#SeeAlso setAll get9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001466
Cary Clark154beea2017-10-26 07:58:48 -04001467#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001468
1469# ------------------------------------------------------------------------------
1470
1471#Method void reset()
1472
Cary Clark154beea2017-10-26 07:58:48 -04001473Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
1474
1475#Code
1476#Literal
1477| 1 0 0 |
1478| 0 1 0 |
1479| 0 0 1 |
1480##
1481
1482Also called setIdentity(); use the one that provides better inline
1483documentation.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001484
1485#Example
Cary Clark154beea2017-10-26 07:58:48 -04001486SkMatrix m;
1487m.reset();
1488SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1489#StdOut
1490m.isIdentity(): true
1491##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001492##
1493
Cary Clark154beea2017-10-26 07:58:48 -04001494#SeeAlso isIdentity setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04001495
Cary Clark154beea2017-10-26 07:58:48 -04001496#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001497
1498# ------------------------------------------------------------------------------
1499
1500#Method void setIdentity()
1501
Cary Clark154beea2017-10-26 07:58:48 -04001502Sets Matrix to identity; which has no effect on mapped Points. Sets Matrix to:
1503
1504#Code
1505#Literal
1506| 1 0 0 |
1507| 0 1 0 |
1508| 0 0 1 |
1509##
1510
1511Also called reset(); use the one that provides better inline
1512documentation.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001513
1514#Example
Cary Clark154beea2017-10-26 07:58:48 -04001515SkMatrix m;
1516m.setIdentity();
1517SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1518#StdOut
1519m.isIdentity(): true
1520##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001521##
1522
Cary Clark154beea2017-10-26 07:58:48 -04001523#SeeAlso isIdentity reset
Cary Clarkbc5697d2017-10-04 14:31:33 -04001524
Cary Clark154beea2017-10-26 07:58:48 -04001525#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001526
1527# ------------------------------------------------------------------------------
1528
1529#Method void setTranslate(SkScalar dx, SkScalar dy)
1530
Cary Clark154beea2017-10-26 07:58:48 -04001531Sets Matrix to translate by (dx, dy).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001532
Cary Clark154beea2017-10-26 07:58:48 -04001533#Param dx horizontal translation ##
1534#Param dy vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001535
1536#Example
Cary Clark154beea2017-10-26 07:58:48 -04001537#Height 64
1538SkPaint paint;
1539paint.setAntiAlias(true);
1540paint.setTextSize(24);
1541canvas->drawString("normal", 8, 24, paint);
1542SkMatrix matrix;
1543matrix.setTranslate(96, 24);
1544canvas->concat(matrix);
1545canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001546##
1547
Cary Clark154beea2017-10-26 07:58:48 -04001548#SeeAlso setTranslateX setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001549
Cary Clark154beea2017-10-26 07:58:48 -04001550#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001551
1552# ------------------------------------------------------------------------------
1553
1554#Method void setTranslate(const SkVector& v)
1555
Cary Clark154beea2017-10-26 07:58:48 -04001556Sets Matrix to translate by (v.fX, v.fY).
1557
1558#Param v Vector containing horizontal and vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001559
1560#Example
Cary Clark154beea2017-10-26 07:58:48 -04001561#Height 64
1562SkPaint paint;
1563paint.setAntiAlias(true);
1564paint.setTextSize(24);
1565canvas->drawString("normal", 8, 24, paint);
1566SkMatrix matrix;
1567matrix.setTranslate({96, 24});
1568canvas->concat(matrix);
1569canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001570##
1571
Cary Clark154beea2017-10-26 07:58:48 -04001572#SeeAlso setTranslateX setTranslateY MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001573
Cary Clark154beea2017-10-26 07:58:48 -04001574#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001575
1576# ------------------------------------------------------------------------------
1577
1578#Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
1579
Cary Clark154beea2017-10-26 07:58:48 -04001580Sets Matrix to scale by sx and sy, about a pivot point at (px, py).
1581The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001582
Cary Clark154beea2017-10-26 07:58:48 -04001583#Param sx horizontal scale factor ##
1584#Param sy vertical scale factor ##
1585#Param px pivot x ##
1586#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001587
1588#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001589#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001590 SkPaint p;
1591 p.setAntiAlias(true);
1592 p.setTextSize(64);
1593 SkMatrix m;
1594 for (SkScalar sx : { -1, 1 } ) {
1595 for (SkScalar sy : { -1, 1 } ) {
1596 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001597 m.setScale(sx, sy, 128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001598 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001599 canvas->drawString("%", 128, 64, p);
Cary Clark154beea2017-10-26 07:58:48 -04001600 }
1601 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001602##
1603
Cary Clark154beea2017-10-26 07:58:48 -04001604#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001605
Cary Clark154beea2017-10-26 07:58:48 -04001606#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001607
1608# ------------------------------------------------------------------------------
1609
1610#Method void setScale(SkScalar sx, SkScalar sy)
1611
Cary Clark154beea2017-10-26 07:58:48 -04001612Sets Matrix to scale by sx and sy about at pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001613
Cary Clark154beea2017-10-26 07:58:48 -04001614#Param sx horizontal scale factor ##
1615#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001616
1617#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001618#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001619 SkPaint p;
1620 p.setAntiAlias(true);
1621 p.setTextSize(64);
1622 SkMatrix m;
1623 for (SkScalar sx : { -1, 1 } ) {
1624 for (SkScalar sy : { -1, 1 } ) {
1625 SkAutoCanvasRestore autoRestore(canvas, true);
1626 m.setScale(sx, sy);
Cary Clark2ade9972017-11-02 17:49:34 -04001627 m.postTranslate(128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001628 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001629 canvas->drawString("@", 0, 0, p);
Cary Clark154beea2017-10-26 07:58:48 -04001630 }
1631 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001632##
1633
Cary Clark154beea2017-10-26 07:58:48 -04001634#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001635
Cary Clark154beea2017-10-26 07:58:48 -04001636#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001637
1638# ------------------------------------------------------------------------------
1639
1640#Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py)
1641
Cary Clark154beea2017-10-26 07:58:48 -04001642Sets Matrix to rotate by degrees about a pivot point at (px, py).
1643The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001644
Cary Clark154beea2017-10-26 07:58:48 -04001645Positive degrees rotates clockwise.
1646
1647#Param degrees angle of axes relative to upright axes ##
1648#Param px pivot x ##
1649#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001650
1651#Example
Cary Clark154beea2017-10-26 07:58:48 -04001652#Height 128
1653 SkPaint paint;
1654 paint.setColor(SK_ColorGRAY);
1655 paint.setAntiAlias(true);
1656 SkRect rect = {20, 20, 100, 100};
1657 canvas->drawRect(rect, paint);
1658 paint.setColor(SK_ColorRED);
1659 SkMatrix matrix;
1660 matrix.setRotate(25, rect.centerX(), rect.centerY());
1661 canvas->concat(matrix);
1662 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001663##
1664
Cary Clark154beea2017-10-26 07:58:48 -04001665#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001666
Cary Clark154beea2017-10-26 07:58:48 -04001667#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001668
1669# ------------------------------------------------------------------------------
1670
1671#Method void setRotate(SkScalar degrees)
1672
Cary Clark154beea2017-10-26 07:58:48 -04001673Sets Matrix to rotate by degrees about a pivot point at (0, 0).
1674Positive degrees rotates clockwise.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001675
Cary Clark154beea2017-10-26 07:58:48 -04001676#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001677
1678#Example
Cary Clark154beea2017-10-26 07:58:48 -04001679#Height 128
1680 SkPaint paint;
1681 paint.setColor(SK_ColorGRAY);
1682 paint.setAntiAlias(true);
1683 SkRect rect = {20, 20, 100, 100};
1684 canvas->drawRect(rect, paint);
1685 paint.setColor(SK_ColorRED);
1686 SkMatrix matrix;
1687 matrix.setRotate(25);
1688 canvas->translate(rect.centerX(), rect.centerY());
1689 canvas->concat(matrix);
1690 canvas->translate(-rect.centerX(), -rect.centerY());
1691 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001692##
1693
Cary Clark154beea2017-10-26 07:58:48 -04001694#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001695
Cary Clark154beea2017-10-26 07:58:48 -04001696#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001697
1698# ------------------------------------------------------------------------------
1699
1700#Method void setSinCos(SkScalar sinValue, SkScalar cosValue,
1701 SkScalar px, SkScalar py)
1702
Cary Clark154beea2017-10-26 07:58:48 -04001703Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (px, py).
1704The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001705
Cary Clark154beea2017-10-26 07:58:48 -04001706Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
1707Vector length specifies scale.
1708
1709#Param sinValue rotation vector x component ##
1710#Param cosValue rotation vector y component ##
1711#Param px pivot x ##
1712#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001713
1714#Example
Cary Clark154beea2017-10-26 07:58:48 -04001715#Height 128
1716 SkPaint paint;
1717 paint.setColor(SK_ColorGRAY);
1718 paint.setAntiAlias(true);
1719 SkRect rect = {20, 20, 100, 100};
1720 canvas->drawRect(rect, paint);
1721 paint.setColor(SK_ColorRED);
1722 SkMatrix matrix;
1723 matrix.setSinCos(.25f, .85f, rect.centerX(), rect.centerY());
1724 canvas->concat(matrix);
1725 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001726##
1727
Cary Clark154beea2017-10-26 07:58:48 -04001728#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001729
Cary Clark154beea2017-10-26 07:58:48 -04001730#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001731
1732# ------------------------------------------------------------------------------
1733
1734#Method void setSinCos(SkScalar sinValue, SkScalar cosValue)
1735
Cary Clark154beea2017-10-26 07:58:48 -04001736Sets Matrix to rotate by sinValue and cosValue, about a pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001737
Cary Clark154beea2017-10-26 07:58:48 -04001738Vector (sinValue, cosValue) describes the angle of rotation relative to (0, 1).
1739Vector length specifies scale.
1740
1741#Param sinValue rotation vector x component ##
1742#Param cosValue rotation vector y component ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001743
1744#Example
Cary Clark154beea2017-10-26 07:58:48 -04001745#Description
1746Canvas needs offset after applying Matrix to pivot about Rect center.
1747##
1748#Height 128
1749 SkPaint paint;
1750 paint.setColor(SK_ColorGRAY);
1751 paint.setAntiAlias(true);
1752 SkRect rect = {20, 20, 100, 100};
1753 canvas->drawRect(rect, paint);
1754 paint.setColor(SK_ColorRED);
1755 SkMatrix matrix;
1756 matrix.setSinCos(.25f, .85f);
1757 matrix.postTranslate(rect.centerX(), rect.centerY());
1758 canvas->concat(matrix);
1759 canvas->translate(-rect.centerX(), -rect.centerY());
1760 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001761##
1762
Cary Clark154beea2017-10-26 07:58:48 -04001763#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001764
Cary Clark154beea2017-10-26 07:58:48 -04001765#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001766
1767# ------------------------------------------------------------------------------
1768
1769#Method SkMatrix& setRSXform(const SkRSXform& rsxForm)
1770
Cary Clark154beea2017-10-26 07:58:48 -04001771Sets Matrix to rotate, scale, and translate using a compressed matrix form.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001772
Cary Clark154beea2017-10-26 07:58:48 -04001773Vector (rsxForm.fSSin, rsxForm.fSCos) describes the angle of rotation relative
1774to (0, 1). Vector length specifies scale. Mapped point is rotated and scaled
1775by Vector, then translated by (rsxForm.fTx, rsxForm.fTy).
1776
1777#Param rsxForm compressed RSXform matrix ##
1778
1779#Return reference to Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001780
1781#Example
Cary Clark154beea2017-10-26 07:58:48 -04001782#Description
1783Canvas needs offset after applying Matrix to pivot about Rect center.
1784##
1785#Height 128
1786 SkPaint paint;
1787 paint.setColor(SK_ColorGRAY);
1788 paint.setAntiAlias(true);
1789 SkRect rect = {20, 20, 100, 100};
1790 canvas->drawRect(rect, paint);
1791 paint.setColor(SK_ColorRED);
1792 SkMatrix matrix;
1793 matrix.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY()));
1794 canvas->concat(matrix);
1795 canvas->translate(-rect.centerX(), -rect.centerY());
1796 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001797##
1798
Cary Clark154beea2017-10-26 07:58:48 -04001799#SeeAlso setSinCos setScale setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001800
Cary Clark154beea2017-10-26 07:58:48 -04001801#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001802
1803# ------------------------------------------------------------------------------
1804
1805#Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
1806
Cary Clark154beea2017-10-26 07:58:48 -04001807Sets Matrix to skew by kx and ky, about a pivot point at (px, py).
1808The pivot point is unchanged when mapped with Matrix.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001809
Cary Clark154beea2017-10-26 07:58:48 -04001810#Param kx horizontal skew factor ##
1811#Param ky vertical skew factor ##
1812#Param px pivot x ##
1813#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001814
1815#Example
Cary Clark154beea2017-10-26 07:58:48 -04001816 SkPaint p;
1817 p.setAntiAlias(true);
1818 p.setTextSize(48);
1819 SkMatrix m;
1820 for (SkScalar sx : { -1, 0, 1 } ) {
1821 for (SkScalar sy : { -1, 0, 1 } ) {
1822 SkAutoCanvasRestore autoRestore(canvas, true);
1823 m.setSkew(sx, sy, 96 + 64 * sx, 128 + 48 * sy);
1824 canvas->concat(m);
1825 canvas->drawString("K", 96 + 64 * sx, 128 + 48 * sy, p);
1826 }
1827 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001828##
1829
Cary Clark154beea2017-10-26 07:58:48 -04001830#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001831
Cary Clark154beea2017-10-26 07:58:48 -04001832#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001833
1834# ------------------------------------------------------------------------------
1835
1836#Method void setSkew(SkScalar kx, SkScalar ky)
1837
Cary Clark154beea2017-10-26 07:58:48 -04001838Sets Matrix to skew by kx and ky, about a pivot point at (0, 0).
Cary Clarkbc5697d2017-10-04 14:31:33 -04001839
Cary Clark154beea2017-10-26 07:58:48 -04001840#Param kx horizontal skew factor ##
1841#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001842
1843#Example
Cary Clark154beea2017-10-26 07:58:48 -04001844 SkPaint p;
1845 p.setAntiAlias(true);
1846 p.setTextSize(48);
1847 SkMatrix m;
1848 for (SkScalar sx : { -1, 0, 1 } ) {
1849 for (SkScalar sy : { -1, 0, 1 } ) {
1850 SkAutoCanvasRestore autoRestore(canvas, true);
1851 m.setSkew(sx, sy);
1852 m.postTranslate(96 + 64 * sx, 128 + 48 * sy);
1853 canvas->concat(m);
1854 canvas->drawString("K", 0, 0, p);
1855 }
1856 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001857##
1858
Cary Clark154beea2017-10-26 07:58:48 -04001859#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001860
Cary Clark154beea2017-10-26 07:58:48 -04001861#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001862
1863# ------------------------------------------------------------------------------
1864
1865#Method void setConcat(const SkMatrix& a, const SkMatrix& b)
1866
Cary Clark154beea2017-10-26 07:58:48 -04001867Sets Matrix to Matrix a multiplied by Matrix b. Either a or b may be this.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001868
Cary Clark154beea2017-10-26 07:58:48 -04001869Given:
1870
1871#Code
1872#Literal
1873 | A B C | | J K L |
1874a = | D E F |, b = | M N O |
1875 | G H I | | P Q R |
1876##
1877
1878sets Matrix to:
1879
1880#Code
1881#Literal
1882 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
1883a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
1884 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
1885##
1886
1887#Param a Matrix on left side of multiply expression ##
1888#Param b Matrix on right side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001889
1890#Example
Cary Clark154beea2017-10-26 07:58:48 -04001891#Image 3
1892#Description
1893setPolyToPoly creates perspective matrices, one the inverse of the other.
1894Multiplying the matrix by its inverse turns into an identity matrix.
1895##
1896SkMatrix matrix, matrix2;
1897SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1898SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1899matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1900matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
1901matrix.setConcat(matrix, matrix2);
1902canvas->concat(matrix);
1903canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001904##
1905
Cary Clark154beea2017-10-26 07:58:48 -04001906#SeeAlso Concat preConcat postConcat SkCanvas::concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04001907
Cary Clark154beea2017-10-26 07:58:48 -04001908#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001909
1910# ------------------------------------------------------------------------------
1911
1912#Method void preTranslate(SkScalar dx, SkScalar dy)
1913
Cary Clark154beea2017-10-26 07:58:48 -04001914Sets Matrix to Matrix multiplied by Matrix constructed from translation (dx, dy).
1915This can be thought of as moving the point to be mapped before applying Matrix.
1916
1917Given:
1918
1919#Code
1920#Literal
1921 | A B C | | 1 0 dx |
1922Matrix = | D E F |, T(dx, dy) = | 0 1 dy |
1923 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001924##
1925
Cary Clark154beea2017-10-26 07:58:48 -04001926sets Matrix to:
1927
1928#Code
1929#Literal
1930 | A B C | | 1 0 dx | | A B A*dx+B*dy+C |
1931Matrix * T(dx, dy) = | D E F | | 0 1 dy | = | D E D*dx+E*dy+F |
1932 | G H I | | 0 0 1 | | G H G*dx+H*dy+I |
1933##
1934
1935#Param dx x translation before applying Matrix ##
1936#Param dy y translation before applying Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001937
1938#Example
Cary Clark154beea2017-10-26 07:58:48 -04001939#Height 160
1940 SkPaint paint;
1941 paint.setAntiAlias(true);
1942 SkRect rect = {20, 20, 100, 100};
1943 for (int i = 0; i < 2; ++i ) {
1944 SkMatrix matrix;
1945 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
1946 {
1947 SkAutoCanvasRestore acr(canvas, true);
1948 canvas->concat(matrix);
1949 paint.setColor(SK_ColorGRAY);
1950 canvas->drawRect(rect, paint);
1951 }
1952 paint.setColor(SK_ColorRED);
1953 for (int j = 0; j < 2; ++j ) {
1954 SkAutoCanvasRestore acr(canvas, true);
1955 matrix.preTranslate(40, 40);
1956 canvas->concat(matrix);
1957 canvas->drawCircle(0, 0, 3, paint);
1958 }
1959 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001960##
1961
Cary Clark154beea2017-10-26 07:58:48 -04001962#SeeAlso postTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001963
Cary Clark154beea2017-10-26 07:58:48 -04001964#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001965
1966# ------------------------------------------------------------------------------
1967
1968#Method void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
1969
Cary Clark154beea2017-10-26 07:58:48 -04001970Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
1971about pivot point (px, py).
1972This can be thought of as scaling about a pivot point before applying Matrix.
1973
1974Given:
1975
1976#Code
1977#Literal
1978 | A B C | | sx 0 dx |
1979Matrix = | D E F |, S(sx, sy, px, py) = | 0 sy dy |
1980 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001981##
1982
Cary Clark154beea2017-10-26 07:58:48 -04001983where
1984
1985#Code
1986#Literal
1987dx = px - sx * px
1988dy = py - sy * py
1989##
1990
1991sets Matrix to:
1992
1993#Code
1994#Literal
1995 | A B C | | sx 0 dx | | A*sx B*sy A*dx+B*dy+C |
1996Matrix * S(sx, sy, px, py) = | D E F | | 0 sy dy | = | D*sx E*sy D*dx+E*dy+F |
1997 | G H I | | 0 0 1 | | G*sx H*sy G*dx+H*dy+I |
1998##
1999
2000#Param sx horizontal scale factor ##
2001#Param sy vertical scale factor ##
2002#Param px pivot x ##
2003#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002004
2005#Example
Cary Clark154beea2017-10-26 07:58:48 -04002006#Image 3
2007SkMatrix matrix;
2008SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2009SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2010matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2011matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
2012canvas->concat(matrix);
2013canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002014##
2015
Cary Clark154beea2017-10-26 07:58:48 -04002016#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002017
Cary Clark154beea2017-10-26 07:58:48 -04002018#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002019
2020# ------------------------------------------------------------------------------
2021
2022#Method void preScale(SkScalar sx, SkScalar sy)
2023
Cary Clark154beea2017-10-26 07:58:48 -04002024Sets Matrix to Matrix multiplied by Matrix constructed from scaling by (sx, sy)
2025about pivot point (0, 0).
2026This can be thought of as scaling about the origin before applying Matrix.
2027
2028Given:
2029
2030#Code
2031#Literal
2032 | A B C | | sx 0 0 |
2033Matrix = | D E F |, S(sx, sy) = | 0 sy 0 |
2034 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002035##
2036
Cary Clark154beea2017-10-26 07:58:48 -04002037sets Matrix to:
2038
2039#Code
2040#Literal
2041 | A B C | | sx 0 0 | | A*sx B*sy C |
2042Matrix * S(sx, sy) = | D E F | | 0 sy 0 | = | D*sx E*sy F |
2043 | G H I | | 0 0 1 | | G*sx H*sy I |
2044##
2045
2046#Param sx horizontal scale factor ##
2047#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002048
2049#Example
Cary Clark154beea2017-10-26 07:58:48 -04002050#Image 3
2051SkMatrix matrix;
2052SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2053SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2054matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2055matrix.preScale(.75f, 1.5f);
2056canvas->concat(matrix);
2057canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002058##
2059
Cary Clark154beea2017-10-26 07:58:48 -04002060#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002061
Cary Clark154beea2017-10-26 07:58:48 -04002062#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002063
2064# ------------------------------------------------------------------------------
2065
2066#Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py)
2067
Cary Clark154beea2017-10-26 07:58:48 -04002068Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
2069about pivot point (px, py).
2070This can be thought of as rotating about a pivot point before applying Matrix.
2071
2072Positive degrees rotates clockwise.
2073
2074Given:
2075
2076#Code
2077#Literal
2078 | A B C | | c -s dx |
2079Matrix = | D E F |, R(degrees, px, py) = | s c dy |
2080 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002081##
2082
Cary Clark154beea2017-10-26 07:58:48 -04002083where
2084
2085#Code
2086#Literal
2087c = cos(degrees)
2088s = sin(degrees)
2089dx = s * py + (1 - c) * px
2090dy = -s * px + (1 - c) * py
2091##
2092
2093sets Matrix to:
2094
2095#Code
2096#Literal
2097 | A B C | | c -s dx | | Ac+Bs -As+Bc A*dx+B*dy+C |
2098Matrix * R(degrees, px, py) = | D E F | | s c dy | = | Dc+Es -Ds+Ec D*dx+E*dy+F |
2099 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc G*dx+H*dy+I |
2100##
2101
2102#Param degrees angle of axes relative to upright axes ##
2103#Param px pivot x ##
2104#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002105
2106#Example
Cary Clark154beea2017-10-26 07:58:48 -04002107#Image 3
2108SkMatrix matrix;
2109SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2110SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2111matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2112matrix.preRotate(45, source.width() / 2, source.height() / 2);
2113canvas->concat(matrix);
2114canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002115##
2116
Cary Clark154beea2017-10-26 07:58:48 -04002117#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002118
Cary Clark154beea2017-10-26 07:58:48 -04002119#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002120
2121# ------------------------------------------------------------------------------
2122
2123#Method void preRotate(SkScalar degrees)
2124
Cary Clark154beea2017-10-26 07:58:48 -04002125Sets Matrix to Matrix multiplied by Matrix constructed from rotating by degrees
2126about pivot point (0, 0).
2127This can be thought of as rotating about the origin before applying Matrix.
2128
2129Positive degrees rotates clockwise.
2130
2131Given:
2132
2133#Code
2134#Literal
2135 | A B C | | c -s 0 |
2136Matrix = | D E F |, R(degrees, px, py) = | s c 0 |
2137 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002138##
2139
Cary Clark154beea2017-10-26 07:58:48 -04002140where
2141
2142#Code
2143#Literal
2144c = cos(degrees)
2145s = sin(degrees)
2146##
2147
2148sets Matrix to:
2149
2150#Code
2151#Literal
2152 | A B C | | c -s 0 | | Ac+Bs -As+Bc C |
2153Matrix * R(degrees, px, py) = | D E F | | s c 0 | = | Dc+Es -Ds+Ec F |
2154 | G H I | | 0 0 1 | | Gc+Hs -Gs+Hc I |
2155##
2156
2157#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002158
2159#Example
Cary Clark154beea2017-10-26 07:58:48 -04002160#Image 3
2161SkMatrix matrix;
2162SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2163SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2164matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2165matrix.preRotate(45);
2166canvas->concat(matrix);
2167canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002168##
2169
Cary Clark154beea2017-10-26 07:58:48 -04002170#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002171
Cary Clark154beea2017-10-26 07:58:48 -04002172#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002173
2174# ------------------------------------------------------------------------------
2175
2176#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
2177
Cary Clark154beea2017-10-26 07:58:48 -04002178Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
2179about pivot point (px, py).
2180This can be thought of as skewing about a pivot point before applying Matrix.
2181
2182Given:
2183
2184#Code
2185#Literal
2186 | A B C | | 1 kx dx |
2187Matrix = | D E F |, K(kx, ky, px, py) = | ky 1 dy |
2188 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002189##
2190
Cary Clark154beea2017-10-26 07:58:48 -04002191where
2192
2193#Code
2194#Literal
2195dx = -kx * py
2196dy = -ky * px
2197##
2198
2199sets Matrix to:
2200
2201#Code
2202#Literal
2203 | A B C | | 1 kx dx | | A+B*ky A*kx+B A*dx+B*dy+C |
2204Matrix * K(kx, ky, px, py) = | D E F | | ky 1 dy | = | D+E*ky D*kx+E D*dx+E*dy+F |
2205 | G H I | | 0 0 1 | | G+H*ky G*kx+H G*dx+H*dy+I |
2206##
2207
2208#Param kx horizontal skew factor ##
2209#Param ky vertical skew factor ##
2210#Param px pivot x ##
2211#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002212
2213#Example
Cary Clark154beea2017-10-26 07:58:48 -04002214#Image 3
2215SkMatrix matrix;
2216SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2217SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2218matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2219matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2);
2220canvas->concat(matrix);
2221canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002222##
2223
Cary Clark154beea2017-10-26 07:58:48 -04002224#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002225
Cary Clark154beea2017-10-26 07:58:48 -04002226#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002227
2228# ------------------------------------------------------------------------------
2229
2230#Method void preSkew(SkScalar kx, SkScalar ky)
2231
Cary Clark154beea2017-10-26 07:58:48 -04002232Sets Matrix to Matrix multiplied by Matrix constructed from skewing by (kx, ky)
2233about pivot point (0, 0).
2234This can be thought of as skewing about the origin before applying Matrix.
2235
2236Given:
2237
2238#Code
2239#Literal
2240 | A B C | | 1 kx 0 |
2241Matrix = | D E F |, K(kx, ky) = | ky 1 0 |
2242 | G H I | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002243##
2244
Cary Clark154beea2017-10-26 07:58:48 -04002245sets Matrix to:
2246
2247#Code
2248#Literal
2249 | A B C | | 1 kx 0 | | A+B*ky A*kx+B C |
2250Matrix * K(kx, ky) = | D E F | | ky 1 0 | = | D+E*ky D*kx+E F |
2251 | G H I | | 0 0 1 | | G+H*ky G*kx+H I |
2252##
2253
2254#Param kx horizontal skew factor ##
2255#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002256
2257#Example
Cary Clark154beea2017-10-26 07:58:48 -04002258#Image 3
2259SkMatrix matrix;
2260SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2261SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2262matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2263matrix.preSkew(.5f, 0);
2264canvas->concat(matrix);
2265canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002266##
2267
Cary Clark154beea2017-10-26 07:58:48 -04002268#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002269
Cary Clark154beea2017-10-26 07:58:48 -04002270#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002271
2272# ------------------------------------------------------------------------------
2273
2274#Method void preConcat(const SkMatrix& other)
2275
Cary Clark154beea2017-10-26 07:58:48 -04002276Sets Matrix to Matrix multiplied by Matrix other.
2277This can be thought of mapping by other before applying Matrix.
2278
2279Given:
2280
2281#Code
2282#Literal
2283 | A B C | | J K L |
2284Matrix = | D E F |, other = | M N O |
2285 | G H I | | P Q R |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002286##
2287
Cary Clark154beea2017-10-26 07:58:48 -04002288sets Matrix to:
2289
2290#Code
2291#Literal
2292 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
2293Matrix * other = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
2294 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
2295##
2296
2297#Param other Matrix on right side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002298
2299#Example
Cary Clark154beea2017-10-26 07:58:48 -04002300#Image 3
2301#Description
2302setPolyToPoly creates perspective matrices, one the inverse of the other.
2303Multiplying the matrix by its inverse turns into an identity matrix.
2304##
2305SkMatrix matrix, matrix2;
2306SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2307SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2308matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2309matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
2310matrix.preConcat(matrix2);
2311canvas->concat(matrix);
2312canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002313##
2314
Cary Clark154beea2017-10-26 07:58:48 -04002315#SeeAlso postConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002316
Cary Clark154beea2017-10-26 07:58:48 -04002317#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002318
2319# ------------------------------------------------------------------------------
2320
2321#Method void postTranslate(SkScalar dx, SkScalar dy)
2322
Cary Clark154beea2017-10-26 07:58:48 -04002323Sets Matrix to Matrix constructed from translation (dx, dy) multiplied by Matrix.
2324This can be thought of as moving the point to be mapped after applying Matrix.
2325
2326Given:
2327
2328#Code
2329#Literal
2330 | J K L | | 1 0 dx |
2331Matrix = | M N O |, T(dx, dy) = | 0 1 dy |
2332 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002333##
2334
Cary Clark154beea2017-10-26 07:58:48 -04002335sets Matrix to:
2336
2337#Code
2338#Literal
2339 | 1 0 dx | | J K L | | J+dx*P K+dx*Q L+dx*R |
2340T(dx, dy) * Matrix = | 0 1 dy | | M N O | = | M+dy*P N+dy*Q O+dy*R |
2341 | 0 0 1 | | P Q R | | P Q R |
2342##
2343
2344#Param dx x translation after applying Matrix ##
2345#Param dy y translation after applying Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002346
2347#Example
Cary Clark154beea2017-10-26 07:58:48 -04002348#Height 160
2349#Description
2350Compare with preTranslate example.
2351##
2352 SkPaint paint;
2353 paint.setAntiAlias(true);
2354 SkRect rect = {20, 20, 100, 100};
2355 for (int i = 0; i < 2; ++i ) {
2356 SkMatrix matrix;
2357 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
2358 {
2359 SkAutoCanvasRestore acr(canvas, true);
2360 canvas->concat(matrix);
2361 paint.setColor(SK_ColorGRAY);
2362 canvas->drawRect(rect, paint);
2363 }
2364 paint.setColor(SK_ColorRED);
2365 for (int j = 0; j < 2; ++j ) {
2366 SkAutoCanvasRestore acr(canvas, true);
2367 matrix.postTranslate(40, 40);
2368 canvas->concat(matrix);
2369 canvas->drawCircle(0, 0, 3, paint);
2370 }
2371 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002372##
2373
Cary Clark154beea2017-10-26 07:58:48 -04002374#SeeAlso preTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04002375
Cary Clark154beea2017-10-26 07:58:48 -04002376#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002377
2378# ------------------------------------------------------------------------------
2379
2380#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
2381
Cary Clark154beea2017-10-26 07:58:48 -04002382Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
2383(px, py), multiplied by Matrix.
2384This can be thought of as scaling about a pivot point after applying Matrix.
2385
2386Given:
2387
2388#Code
2389#Literal
2390 | J K L | | sx 0 dx |
2391Matrix = | M N O |, S(sx, sy, px, py) = | 0 sy dy |
2392 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002393##
2394
Cary Clark154beea2017-10-26 07:58:48 -04002395where
2396
2397#Code
2398#Literal
2399dx = px - sx * px
2400dy = py - sy * py
2401##
2402
2403sets Matrix to:
2404
2405#Code
2406#Literal
2407 | sx 0 dx | | J K L | | sx*J+dx*P sx*K+dx*Q sx*L+dx+R |
2408S(sx, sy, px, py) * Matrix = | 0 sy dy | | M N O | = | sy*M+dy*P sy*N+dy*Q sy*O+dy*R |
2409 | 0 0 1 | | P Q R | | P Q R |
2410##
2411
2412#Param sx horizontal scale factor ##
2413#Param sy vertical scale factor ##
2414#Param px pivot x ##
2415#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002416
2417#Example
Cary Clark154beea2017-10-26 07:58:48 -04002418#Image 3
2419SkMatrix matrix;
2420SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2421SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2422matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2423matrix.postScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
2424canvas->concat(matrix);
2425canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002426##
2427
Cary Clark154beea2017-10-26 07:58:48 -04002428#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002429
2430##
2431
2432# ------------------------------------------------------------------------------
2433
2434#Method void postScale(SkScalar sx, SkScalar sy)
2435
Cary Clark154beea2017-10-26 07:58:48 -04002436Sets Matrix to Matrix constructed from scaling by (sx, sy) about pivot point
2437(0, 0), multiplied by Matrix.
2438This can be thought of as scaling about the origin after applying Matrix.
2439
2440Given:
2441
2442#Code
2443#Literal
2444 | J K L | | sx 0 0 |
2445Matrix = | M N O |, S(sx, sy) = | 0 sy 0 |
2446 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002447##
2448
Cary Clark154beea2017-10-26 07:58:48 -04002449sets Matrix to:
2450
2451#Code
2452#Literal
2453 | sx 0 0 | | J K L | | sx*J sx*K sx*L |
2454S(sx, sy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
2455 | 0 0 1 | | P Q R | | P Q R |
2456##
2457
2458#Param sx horizontal scale factor ##
2459#Param sy vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002460
2461#Example
Cary Clark154beea2017-10-26 07:58:48 -04002462#Image 3
2463SkMatrix matrix;
2464SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2465SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2466matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2467matrix.postScale(.75f, 1.5f);
2468canvas->concat(matrix);
2469canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002470##
2471
Cary Clark154beea2017-10-26 07:58:48 -04002472#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002473
2474##
2475
2476# ------------------------------------------------------------------------------
2477
2478#Method bool postIDiv(int divx, int divy)
2479
Cary Clark154beea2017-10-26 07:58:48 -04002480Sets Matrix to Matrix constructed from scaling by
Cary Clarkbc5697d2017-10-04 14:31:33 -04002481#Formula
Cary Clark154beea2017-10-26 07:58:48 -04002482(1/divx, 1/divy)
2483##
2484about pivot point (px, py), multiplied by Matrix.
2485
2486Returns false if either divx or divy is zero.
2487
2488Given:
2489
2490#Code
2491#Literal
2492 | J K L | | sx 0 0 |
2493Matrix = | M N O |, I(divx, divy) = | 0 sy 0 |
2494 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002495##
2496
Cary Clark154beea2017-10-26 07:58:48 -04002497where
Cary Clarkbc5697d2017-10-04 14:31:33 -04002498
Cary Clark154beea2017-10-26 07:58:48 -04002499#Code
2500#Literal
2501sx = 1 / divx
2502sy = 1 / divy
2503##
2504
2505sets Matrix to:
2506
2507#Code
2508#Literal
2509 | sx 0 0 | | J K L | | sx*J sx*K sx*L |
2510I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
2511 | 0 0 1 | | P Q R | | P Q R |
2512##
2513
2514#Param divx integer divisor for inverse scale in x ##
2515#Param divy integer divisor for inverse scale in y ##
2516
2517#Return true on successful scale ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002518
2519#Example
Cary Clark154beea2017-10-26 07:58:48 -04002520#Image 3
2521SkMatrix matrix, matrix2;
2522SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2523SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2524matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2525matrix.postIDiv(1, 2);
2526canvas->concat(matrix);
2527canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002528##
2529
Cary Clark154beea2017-10-26 07:58:48 -04002530#SeeAlso postScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002531
2532##
2533
2534# ------------------------------------------------------------------------------
2535
2536#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py)
2537
Cary Clark154beea2017-10-26 07:58:48 -04002538Sets Matrix to Matrix constructed from rotating by degrees about pivot point
2539(px, py), multiplied by Matrix.
2540This can be thought of as rotating about a pivot point after applying Matrix.
2541
2542Positive degrees rotates clockwise.
2543
2544Given:
2545
2546#Code
2547#Literal
2548 | J K L | | c -s dx |
2549Matrix = | M N O |, R(degrees, px, py) = | s c dy |
2550 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002551##
2552
Cary Clark154beea2017-10-26 07:58:48 -04002553where
2554
2555#Code
2556#Literal
2557c = cos(degrees)
2558s = sin(degrees)
2559dx = s * py + (1 - c) * px
2560dy = -s * px + (1 - c) * py
2561##
2562
2563sets Matrix to:
2564
2565#Code
2566#Literal
2567 |c -s dx| |J K L| |cJ-sM+dx*P cK-sN+dx*Q cL-sO+dx+R|
2568R(degrees, px, py) * Matrix = |s c dy| |M N O| = |sJ+cM+dy*P sK+cN+dy*Q sL+cO+dy*R|
2569 |0 0 1| |P Q R| | P Q R|
2570##
2571
2572#Param degrees angle of axes relative to upright axes ##
2573#Param px pivot x ##
2574#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002575
2576#Example
Cary Clark154beea2017-10-26 07:58:48 -04002577#Image 3
2578SkMatrix matrix;
2579SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2580SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2581matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2582matrix.postRotate(45, source.width() / 2, source.height() / 2);
2583canvas->concat(matrix);
2584canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002585##
2586
Cary Clark154beea2017-10-26 07:58:48 -04002587#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002588
2589##
2590
2591# ------------------------------------------------------------------------------
2592
2593#Method void postRotate(SkScalar degrees)
2594
Cary Clark154beea2017-10-26 07:58:48 -04002595Sets Matrix to Matrix constructed from rotating by degrees about pivot point
2596(0, 0), multiplied by Matrix.
2597This can be thought of as rotating about the origin after applying Matrix.
2598
2599Positive degrees rotates clockwise.
2600
2601Given:
2602
2603#Code
2604#Literal
2605 | J K L | | c -s 0 |
2606Matrix = | M N O |, R(degrees, px, py) = | s c 0 |
2607 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002608##
2609
Cary Clark154beea2017-10-26 07:58:48 -04002610where
2611
2612#Code
2613#Literal
2614c = cos(degrees)
2615s = sin(degrees)
2616##
2617
2618sets Matrix to:
2619
2620#Code
2621#Literal
2622 | c -s dx | | J K L | | cJ-sM cK-sN cL-sO |
2623R(degrees, px, py) * Matrix = | s c dy | | M N O | = | sJ+cM sK+cN sL+cO |
2624 | 0 0 1 | | P Q R | | P Q R |
2625##
2626
2627#Param degrees angle of axes relative to upright axes ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002628
2629#Example
Cary Clark154beea2017-10-26 07:58:48 -04002630#Image 3
2631SkMatrix matrix;
2632SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2633SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2634matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2635matrix.postRotate(45);
2636canvas->concat(matrix);
2637canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002638##
2639
Cary Clark154beea2017-10-26 07:58:48 -04002640#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002641
2642##
2643
2644# ------------------------------------------------------------------------------
2645
2646#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
2647
Cary Clark154beea2017-10-26 07:58:48 -04002648Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
2649(px, py), multiplied by Matrix.
2650This can be thought of as skewing about a pivot point after applying Matrix.
2651
2652Given:
2653
2654#Code
2655#Literal
2656 | J K L | | 1 kx dx |
2657Matrix = | M N O |, K(kx, ky, px, py) = | ky 1 dy |
2658 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002659##
2660
Cary Clark154beea2017-10-26 07:58:48 -04002661where
2662
2663#Code
2664#Literal
2665dx = -kx * py
2666dy = -ky * px
2667##
2668
2669sets Matrix to:
2670
2671#Code
2672#Literal
2673 | 1 kx dx| |J K L| |J+kx*M+dx*P K+kx*N+dx*Q L+kx*O+dx+R|
2674K(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|
2675 | 0 0 1| |P Q R| | P Q R|
2676##
2677
2678#Param kx horizontal skew factor ##
2679#Param ky vertical skew factor ##
2680#Param px pivot x ##
2681#Param py pivot y ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002682
2683#Example
Cary Clark154beea2017-10-26 07:58:48 -04002684#Image 3
2685SkMatrix matrix;
2686SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2687SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2688matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2689matrix.postSkew(.5f, 0, source.width() / 2, source.height() / 2);
2690canvas->concat(matrix);
2691canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002692##
2693
Cary Clark154beea2017-10-26 07:58:48 -04002694#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002695
2696##
2697
2698# ------------------------------------------------------------------------------
2699
2700#Method void postSkew(SkScalar kx, SkScalar ky)
2701
Cary Clark154beea2017-10-26 07:58:48 -04002702Sets Matrix to Matrix constructed from skewing by (kx, ky) about pivot point
2703(0, 0), multiplied by Matrix.
2704This can be thought of as skewing about the origin after applying Matrix.
2705
2706Given:
2707
2708#Code
2709#Literal
2710 | J K L | | 1 kx 0 |
2711Matrix = | M N O |, K(kx, ky) = | ky 1 0 |
2712 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002713##
2714
Cary Clark154beea2017-10-26 07:58:48 -04002715sets Matrix to:
2716
2717#Code
2718#Literal
2719 | 1 kx 0 | | J K L | | J+kx*M K+kx*N L+kx*O |
2720K(kx, ky) * Matrix = | ky 1 0 | | M N O | = | ky*J+M ky*K+N ky*L+O |
2721 | 0 0 1 | | P Q R | | P Q R |
2722##
2723
2724#Param kx horizontal skew factor ##
2725#Param ky vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002726
2727#Example
Cary Clark154beea2017-10-26 07:58:48 -04002728#Image 3
2729SkMatrix matrix;
2730SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2731SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2732matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2733matrix.postSkew(.5f, 0);
2734canvas->concat(matrix);
2735canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002736##
2737
Cary Clark154beea2017-10-26 07:58:48 -04002738#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04002739
2740##
2741
2742# ------------------------------------------------------------------------------
2743
2744#Method void postConcat(const SkMatrix& other)
2745
Cary Clark154beea2017-10-26 07:58:48 -04002746Sets Matrix to Matrix other multiplied by Matrix.
2747This can be thought of mapping by other after applying Matrix.
2748
2749Given:
2750
2751#Code
2752#Literal
2753 | J K L | | A B C |
2754Matrix = | M N O |, other = | D E F |
2755 | P Q R | | G H I |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002756##
2757
Cary Clark154beea2017-10-26 07:58:48 -04002758sets Matrix to:
2759
2760#Code
2761#Literal
2762 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
2763other * Matrix = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
2764 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
2765##
2766
2767#Param other Matrix on left side of multiply expression ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002768
2769#Example
Cary Clark154beea2017-10-26 07:58:48 -04002770#Image 3
2771#Height 64
2772SkMatrix matrix, matrix2;
2773SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2774SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2775matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2776matrix.postConcat(matrix);
2777canvas->concat(matrix);
2778canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002779##
2780
Cary Clark154beea2017-10-26 07:58:48 -04002781#SeeAlso preConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002782
2783##
2784
2785# ------------------------------------------------------------------------------
2786
2787#Enum ScaleToFit
2788
2789#Code
2790 enum ScaleToFit {
2791 kFill_ScaleToFit,
2792 kStart_ScaleToFit,
2793 kCenter_ScaleToFit,
2794 kEnd_ScaleToFit,
2795 };
2796##
2797
Cary Clark154beea2017-10-26 07:58:48 -04002798ScaleToFit describes how Matrix is constructed to map one Rect to another.
2799ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling,
2800or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies
2801how Matrix maps to the side or center of the destination Rect.
2802
2803#Const kFill_ScaleToFit 0
2804 Computes Matrix that scales in x and y independently, so that source Rect is
2805 mapped to completely fill destination Rect. The aspect ratio of source Rect
2806 may change.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002807##
Cary Clark154beea2017-10-26 07:58:48 -04002808#Const kStart_ScaleToFit 1
2809 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2810 width or height to destination Rect. Aligns mapping to left and top edges
2811 of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002812##
Cary Clark154beea2017-10-26 07:58:48 -04002813#Const kCenter_ScaleToFit 2
2814 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2815 width or height to destination Rect. Aligns mapping to center of destination
2816 Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002817##
Cary Clark154beea2017-10-26 07:58:48 -04002818#Const kEnd_ScaleToFit 3
2819 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
2820 width or height to destination Rect. Aligns mapping to right and bottom
2821 edges of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002822##
2823
2824#Example
Cary Clark154beea2017-10-26 07:58:48 -04002825 const char* labels[] = { "Fill", "Start", "Center", "End" };
2826 SkRect rects[] = {{5, 5, 59, 59}, {5, 74, 59, 108}, {10, 123, 44, 172}, {10, 187, 54, 231}};
2827 SkRect bounds;
2828 source.getBounds(&bounds);
2829 SkPaint paint;
2830 paint.setAntiAlias(true);
2831 for (auto fit : { SkMatrix::kFill_ScaleToFit, SkMatrix::kStart_ScaleToFit,
2832 SkMatrix::kCenter_ScaleToFit, SkMatrix::kEnd_ScaleToFit } ) {
2833 for (auto rect : rects ) {
2834 canvas->drawRect(rect, paint);
2835 SkMatrix matrix;
2836 if (!matrix.setRectToRect(bounds, rect, fit)) {
2837 continue;
2838 }
2839 SkAutoCanvasRestore acr(canvas, true);
2840 canvas->concat(matrix);
2841 canvas->drawBitmap(source, 0, 0);
2842 }
2843 canvas->drawString(labels[fit], 10, 255, paint);
2844 canvas->translate(64, 0);
2845 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002846##
2847
Cary Clark154beea2017-10-26 07:58:48 -04002848#SeeAlso setRectToRect MakeRectToRect setPolyToPoly
Cary Clarkbc5697d2017-10-04 14:31:33 -04002849
2850##
2851
2852# ------------------------------------------------------------------------------
2853
2854#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
2855
Cary Clark154beea2017-10-26 07:58:48 -04002856Sets Matrix to scale and translate src Rect to dst Rect. stf selects whether
2857mapping completely fills dst or preserves the aspect ratio, and how to align
2858src within dst. Returns false if src is empty, and sets Matrix to identity.
2859Returns true if dst is empty, and sets Matrix to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04002860
Cary Clark154beea2017-10-26 07:58:48 -04002861#Code
2862#Literal
2863| 0 0 0 |
2864| 0 0 0 |
2865| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002866##
2867
Cary Clark154beea2017-10-26 07:58:48 -04002868#Param src Rect to map from ##
2869#Param dst Rect to map to ##
2870#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
2871 kCenter_ScaleToFit, kEnd_ScaleToFit
Cary Clarkbc5697d2017-10-04 14:31:33 -04002872##
2873
Cary Clark154beea2017-10-26 07:58:48 -04002874#Return true if Matrix can represent Rect mapping ##
2875
Cary Clarkbc5697d2017-10-04 14:31:33 -04002876#Example
Cary Clark154beea2017-10-26 07:58:48 -04002877 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
2878 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
2879 for (auto src : srcs) {
2880 for (auto dst : dsts) {
2881 SkMatrix matrix;
2882 matrix.setAll(-1, -1, -1, -1, -1, -1, -1, -1, -1);
2883 bool success = matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
2884 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g success: %s\n",
2885 src.fLeft, src.fTop, src.fRight, src.fBottom,
2886 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, success ? "true" : "false");
2887 matrix.dump();
2888 }
2889 }
2890#StdOut
2891src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false
2892[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2893src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false
2894[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2895src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true
2896[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2897src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true
2898[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
2899##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002900##
2901
Cary Clark154beea2017-10-26 07:58:48 -04002902#SeeAlso MakeRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04002903
2904##
2905
2906# ------------------------------------------------------------------------------
2907
2908#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
2909
Cary Clark154beea2017-10-26 07:58:48 -04002910Returns Matrix set to scale and translate src Rect to dst Rect. stf selects
2911whether mapping completely fills dst or preserves the aspect ratio, and how to
2912align src within dst. Returns the identity Matrix if src is empty. If dst is
2913empty, returns Matrix set to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04002914
Cary Clark154beea2017-10-26 07:58:48 -04002915#Code
2916#Literal
2917| 0 0 0 |
2918| 0 0 0 |
2919| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04002920##
2921
Cary Clark154beea2017-10-26 07:58:48 -04002922#Param src Rect to map from ##
2923#Param dst Rect to map to ##
2924#Param stf one of: kFill_ScaleToFit, kStart_ScaleToFit,
2925 kCenter_ScaleToFit, kEnd_ScaleToFit
2926##
2927
2928#Return Matrix mapping src to dst ##
2929
2930#Example
2931 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
2932 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
2933 for (auto src : srcs) {
2934 for (auto dst : dsts) {
2935 SkMatrix matrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
2936 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g\n",
2937 src.fLeft, src.fTop, src.fRight, src.fBottom,
2938 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom);
2939 matrix.dump();
2940 }
2941 }
2942#StdOut
2943src: 0, 0, 0, 0 dst: 0, 0, 0, 0
2944[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2945src: 0, 0, 0, 0 dst: 5, 6, 8, 9
2946[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2947src: 1, 2, 3, 4 dst: 0, 0, 0, 0
2948[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2949src: 1, 2, 3, 4 dst: 5, 6, 8, 9
2950[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
2951##
2952##
2953
2954#SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04002955
2956##
2957
2958# ------------------------------------------------------------------------------
2959
2960#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
2961
Cary Clark154beea2017-10-26 07:58:48 -04002962Sets Matrix to map src to dst. count must be zero or greater, and four or less.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002963
Cary Clark154beea2017-10-26 07:58:48 -04002964If count is zero, sets Matrix to identity and returns true.
2965If count is one, sets Matrix to translate and returns true.
2966If count is two or more, sets Matrix to map Points if possible; returns false
2967if Matrix cannot be constructed. If count is four, Matrix may include
2968perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04002969
Cary Clark154beea2017-10-26 07:58:48 -04002970#Param src Points to map from ##
2971#Param dst Points to map to ##
2972#Param count number of Points in src and dst ##
2973
2974#Return true if Matrix was constructed successfully
Cary Clarkbc5697d2017-10-04 14:31:33 -04002975##
2976
2977#Example
Cary Clark154beea2017-10-26 07:58:48 -04002978 const SkPoint src[] = { { 0, 0}, {30, 0}, {30, -30}, { 0, -30} };
2979 const SkPoint dst[] = { {50, 0}, {80, -10}, {90, -30}, {60, -40} };
2980 SkPaint blackPaint;
2981 blackPaint.setAntiAlias(true);
2982 blackPaint.setTextSize(42);
2983 SkPaint redPaint = blackPaint;
2984 redPaint.setColor(SK_ColorRED);
2985 for (int count : { 1, 2, 3, 4 } ) {
2986 canvas->translate(35, 55);
2987 for (int index = 0; index < count; ++index) {
2988 canvas->drawCircle(src[index], 3, blackPaint);
2989 canvas->drawCircle(dst[index], 3, blackPaint);
2990 if (index > 0) {
2991 canvas->drawLine(src[index], src[index - 1], blackPaint);
2992 canvas->drawLine(dst[index], dst[index - 1], blackPaint);
2993 }
2994 }
2995 SkMatrix matrix;
2996 matrix.setPolyToPoly(src, dst, count);
2997 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
2998 SkAutoCanvasRestore acr(canvas, true);
2999 canvas->concat(matrix);
3000 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
3001 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003002##
3003
Cary Clark154beea2017-10-26 07:58:48 -04003004#SeeAlso setRectToRect MakeRectToRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003005
3006##
3007
3008# ------------------------------------------------------------------------------
3009
3010#Method bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const
3011
Cary Clark154beea2017-10-26 07:58:48 -04003012Sets inverse to reciprocal matrix, returning true if Matrix can be inverted.
3013Geometrically, if Matrix maps from source to destination, inverse Matrix
3014maps from destination to source. If Matrix can not be inverted, inverse is
3015unchanged.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003016
Cary Clark154beea2017-10-26 07:58:48 -04003017#Param inverse storage for inverted Matrix; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003018
Cary Clark154beea2017-10-26 07:58:48 -04003019#Return true if Matrix can be inverted ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003020
3021#Example
Cary Clark154beea2017-10-26 07:58:48 -04003022#Height 128
3023 const SkPoint src[] = { { 10, 120}, {120, 120}, {120, 10}, { 10, 10} };
3024 const SkPoint dst[] = { {150, 120}, {200, 100}, {240, 30}, { 130, 40} };
3025 SkPaint paint;
3026 paint.setAntiAlias(true);
3027 SkMatrix matrix;
3028 matrix.setPolyToPoly(src, dst, 4);
3029 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, src, paint);
3030 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, dst, paint);
3031 paint.setColor(SK_ColorBLUE);
3032 paint.setStrokeWidth(3);
3033 paint.setStrokeCap(SkPaint::kRound_Cap);
3034 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
3035 matrix.invert(&matrix);
3036 canvas->concat(matrix);
3037 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003038##
3039
Cary Clark154beea2017-10-26 07:58:48 -04003040#SeeAlso Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04003041
3042##
3043
3044# ------------------------------------------------------------------------------
3045
3046#Method static void SetAffineIdentity(SkScalar affine[6])
3047
Cary Clark154beea2017-10-26 07:58:48 -04003048Fills affine with identity values in column major order.
3049Sets affine to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003050
Cary Clark154beea2017-10-26 07:58:48 -04003051#Code
3052#Literal
3053| 1 0 0 |
3054| 0 1 0 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003055##
3056
Cary Clark154beea2017-10-26 07:58:48 -04003057Affine 3x2 matrices in column major order are used by OpenGL and XPS.
3058
3059#Param affine storage for 3x2 affine matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003060
3061#Example
Cary Clark154beea2017-10-26 07:58:48 -04003062 SkScalar affine[6];
3063 SkMatrix::SetAffineIdentity(affine);
3064 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3065 for (int i = 0; i < 6; ++i) {
3066 SkDebugf("%s: %g ", names[i], affine[i]);
3067 }
3068 SkDebugf("\n");
3069#StdOut
3070ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0
3071##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003072##
3073
Cary Clark154beea2017-10-26 07:58:48 -04003074#SeeAlso setAffine asAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -04003075
3076##
3077
3078# ------------------------------------------------------------------------------
3079
3080#Method bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const
3081
Cary Clark154beea2017-10-26 07:58:48 -04003082Fills affine in column major order. Sets affine to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003083
Cary Clark154beea2017-10-26 07:58:48 -04003084#Code
3085#Literal
3086| scale-x skew-x translate-x |
3087| skew-y scale-y translate-y |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003088##
3089
Cary Clark154beea2017-10-26 07:58:48 -04003090If Matrix contains perspective, returns false and leaves affine unchanged.
3091
3092#Param affine storage for 3x2 affine matrix; may be nullptr ##
3093
3094#Return true if Matrix does not contain perspective ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003095
3096#Example
Cary Clark154beea2017-10-26 07:58:48 -04003097SkMatrix matrix;
3098matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
3099SkScalar affine[6];
3100matrix.asAffine(affine);
3101const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3102for (int i = 0; i < 6; ++i) {
3103 SkDebugf("%s: %g ", names[i], affine[i]);
3104}
3105SkDebugf("\n");
3106#StdOut
3107ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
3108##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003109##
3110
Cary Clark154beea2017-10-26 07:58:48 -04003111#SeeAlso setAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04003112
3113##
3114
3115# ------------------------------------------------------------------------------
3116
3117#Method void setAffine(const SkScalar affine[6])
3118
Cary Clark154beea2017-10-26 07:58:48 -04003119Sets Matrix to affine values, passed in column major order. Given affine,
3120column, then row, as:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003121
Cary Clark154beea2017-10-26 07:58:48 -04003122#Code
3123#Literal
3124| scale-x skew-x translate-x |
3125| skew-y scale-y translate-y |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003126##
3127
Cary Clark154beea2017-10-26 07:58:48 -04003128Matrix is set, row, then column, to:
3129
3130#Code
3131#Literal
3132| scale-x skew-x translate-x |
3133| skew-y scale-y translate-y |
3134| 0 0 1 |
3135##
3136
3137#Param affine 3x2 affine matrix ##
3138
3139#Example
3140SkMatrix matrix;
3141matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
3142SkScalar affine[6];
3143matrix.asAffine(affine);
3144const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
3145for (int i = 0; i < 6; ++i) {
3146 SkDebugf("%s: %g ", names[i], affine[i]);
3147}
3148SkDebugf("\n");
3149matrix.reset();
3150matrix.setAffine(affine);
3151matrix.dump();
3152#StdOut
3153ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
3154[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000]
3155##
3156##
3157
3158#SeeAlso asAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04003159
3160##
3161
3162# ------------------------------------------------------------------------------
3163
3164#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
3165
Cary Clark154beea2017-10-26 07:58:48 -04003166Maps src Point array of length count to dst Point array of equal or greater
3167length. Points are mapped by multiplying each Point by Matrix. Given:
3168
3169#Code
3170#Literal
3171 | A B C | | x |
3172Matrix = | D E F |, pt = | y |
3173 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003174##
3175
Cary Clark154beea2017-10-26 07:58:48 -04003176where
3177
3178#Code
3179#Literal
3180for (i = 0; i < count; ++i) {
3181 x = src[i].fX
3182 y = src[i].fY
3183}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003184##
Cary Clark154beea2017-10-26 07:58:48 -04003185
3186each dst Point is computed as:
3187
3188#Code
3189#Literal
3190 |A B C| |x| Ax+By+C Dx+Ey+F
3191Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3192 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003193##
Cary Clark154beea2017-10-26 07:58:48 -04003194
3195src and dst may point to the same storage.
3196
3197#Param dst storage for mapped Points ##
3198#Param src Points to transform ##
3199#Param count number of Points to transform ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003200
3201#Example
Cary Clark154beea2017-10-26 07:58:48 -04003202 SkMatrix matrix;
3203 matrix.reset();
3204 const int count = 4;
3205 SkPoint src[count];
3206 matrix.mapRectToQuad(src, {40, 70, 180, 220} );
3207 SkPaint paint;
3208 paint.setARGB(77, 23, 99, 154);
3209 for (int i = 0; i < 5; ++i) {
3210 SkPoint dst[count];
3211 matrix.mapPoints(dst, src, count);
3212 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, dst, paint);
3213 matrix.preRotate(35, 128, 128);
3214 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003215##
3216
Brian Salomonfa3783f2018-01-05 13:49:07 -05003217#SeeAlso mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003218
3219##
3220
3221# ------------------------------------------------------------------------------
3222
3223#Method void mapPoints(SkPoint pts[], int count) const
3224
Cary Clark154beea2017-10-26 07:58:48 -04003225Maps pts Point array of length count in place. Points are mapped by multiplying
3226each Point by Matrix. Given:
3227
3228#Code
3229#Literal
3230 | A B C | | x |
3231Matrix = | D E F |, pt = | y |
3232 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003233##
3234
Cary Clark154beea2017-10-26 07:58:48 -04003235where
3236
3237#Code
3238#Literal
3239for (i = 0; i < count; ++i) {
3240 x = pts[i].fX
3241 y = pts[i].fY
3242}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003243##
Cary Clark154beea2017-10-26 07:58:48 -04003244
3245each resulting pts Point is computed as:
3246
3247#Code
3248#Literal
3249 |A B C| |x| Ax+By+C Dx+Ey+F
3250Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3251 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003252##
3253
Cary Clark154beea2017-10-26 07:58:48 -04003254#Param pts storage for mapped Points ##
3255#Param count number of Points to transform ##
3256
Cary Clarkbc5697d2017-10-04 14:31:33 -04003257#Example
Cary Clark154beea2017-10-26 07:58:48 -04003258 SkMatrix matrix;
3259 matrix.setRotate(35, 128, 128);
3260 const int count = 4;
3261 SkPoint pts[count];
3262 matrix.mapRectToQuad(pts, {40, 70, 180, 220} );
3263 SkPaint paint;
3264 paint.setARGB(77, 23, 99, 154);
3265 for (int i = 0; i < 5; ++i) {
3266 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, pts, paint);
3267 matrix.mapPoints(pts, count);
3268 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003269##
3270
Brian Salomonfa3783f2018-01-05 13:49:07 -05003271#SeeAlso mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003272
3273##
3274
3275# ------------------------------------------------------------------------------
3276
Cary Clark154beea2017-10-26 07:58:48 -04003277#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
Cary Clarkbc5697d2017-10-04 14:31:33 -04003278
Cary Clark154beea2017-10-26 07:58:48 -04003279Maps src Point3 array of length count to dst Point3 array, which must of length count or
3280greater. Point3 array is mapped by multiplying each Point3 by Matrix. Given:
3281
3282#Code
3283#Literal
3284 | A B C | | x |
3285Matrix = | D E F |, src = | y |
3286 | G H I | | z |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003287##
3288
Cary Clark154beea2017-10-26 07:58:48 -04003289each resulting dst Point is computed as:
3290
3291#Code
3292#Literal
3293 |A B C| |x|
3294Matrix * src = |D E F| |y| = |Ax+By+Cz Dx+Ey+Fz Gx+Hy+Iz|
3295 |G H I| |z|
Cary Clarkbc5697d2017-10-04 14:31:33 -04003296##
Cary Clark154beea2017-10-26 07:58:48 -04003297
3298#Param dst storage for mapped Point3 array ##
3299#Param src Point3 array to transform ##
3300#Param count items in Point3 array to transform ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003301
3302#Example
Cary Clark154beea2017-10-26 07:58:48 -04003303 SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3},
3304 {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}};
3305 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 };
3306 constexpr int count = SK_ARRAY_COUNT(src);
3307 auto debugster = [=](SkPoint3 src[]) -> void {
3308 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) {
3309 const SkPoint3& s = src[lines[i]];
3310 const SkPoint3& e = src[lines[i + 1]];
3311 SkPaint paint;
3312 paint.setARGB(77, 23, 99, 154);
3313 canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint);
3314 }
3315 };
3316 canvas->save();
3317 canvas->translate(5, 5);
3318 canvas->scale(15, 15);
3319 debugster(src);
3320 canvas->restore();
3321 canvas->translate(128, 128);
3322 SkMatrix matrix;
3323 matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1);
Cary Clarka560c472017-11-27 10:44:06 -05003324 matrix.mapHomogeneousPoints(src, src, count);
Cary Clark154beea2017-10-26 07:58:48 -04003325 debugster(src);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003326##
3327
Brian Salomonfa3783f2018-01-05 13:49:07 -05003328#SeeAlso mapPoints mapXY mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003329
3330##
3331
3332# ------------------------------------------------------------------------------
3333
3334#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const
3335
Cary Clark154beea2017-10-26 07:58:48 -04003336Maps Point (x, y) to result. Point is mapped by multiplying by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003337
Cary Clark154beea2017-10-26 07:58:48 -04003338#Code
3339#Literal
3340 | A B C | | x |
3341Matrix = | D E F |, pt = | y |
3342 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003343##
3344
Cary Clark154beea2017-10-26 07:58:48 -04003345result is computed as:
3346
3347#Code
3348#Literal
3349 |A B C| |x| Ax+By+C Dx+Ey+F
3350Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3351 |G H I| |1| Gx+Hy+I Gx+Hy+I
3352##
3353
3354#Param x x-coordinate of Point to map ##
3355#Param y y-coordinate of Point to map ##
3356#Param result storage for mapped Point ##
3357
3358#Example
3359 SkPaint paint;
3360 paint.setAntiAlias(true);
3361 SkMatrix matrix;
3362 matrix.setRotate(60, 128, 128);
3363 SkPoint lines[] = {{50, 50}, {150, 50}, {150, 150}};
3364 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); ++i) {
3365 SkPoint pt;
3366 matrix.mapXY(lines[i].fX, lines[i].fY, &pt);
3367 canvas->drawCircle(pt.fX, pt.fY, 3, paint);
3368 }
3369 canvas->concat(matrix);
3370 canvas->drawPoints(SkCanvas::kPolygon_PointMode, SK_ARRAY_COUNT(lines), lines, paint);
3371##
3372
Brian Salomonfa3783f2018-01-05 13:49:07 -05003373#SeeAlso mapPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003374
3375##
3376
3377# ------------------------------------------------------------------------------
3378
3379#Method SkPoint mapXY(SkScalar x, SkScalar y) const
3380
Cary Clark154beea2017-10-26 07:58:48 -04003381Returns Point (x, y) multiplied by Matrix. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003382
Cary Clark154beea2017-10-26 07:58:48 -04003383#Code
3384#Literal
3385 | A B C | | x |
3386Matrix = | D E F |, pt = | y |
3387 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003388##
3389
Cary Clark154beea2017-10-26 07:58:48 -04003390result is computed as:
3391
3392#Code
3393#Literal
3394 |A B C| |x| Ax+By+C Dx+Ey+F
3395Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3396 |G H I| |1| Gx+Hy+I Gx+Hy+I
3397##
3398
3399#Param x x-coordinate of Point to map ##
3400#Param y y-coordinate of Point to map ##
3401
3402#Return mapped Point ##
3403
3404#Example
3405#Image 4
3406SkMatrix matrix;
3407SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {30, 206}};
3408SkRect::Make(source.bounds()).toQuad(bitmapBounds);
3409matrix.setPolyToPoly(bitmapBounds, perspect, 4);
3410SkPaint paint;
3411paint.setAntiAlias(true);
3412paint.setStrokeWidth(3);
3413for (int x : { 0, source.width() } ) {
3414 for (int y : { 0, source.height() } ) {
3415 canvas->drawPoint(matrix.mapXY(x, y), paint);
3416 }
3417}
3418canvas->concat(matrix);
3419canvas->drawBitmap(source, 0, 0);
3420##
3421
Brian Salomonfa3783f2018-01-05 13:49:07 -05003422#SeeAlso mapPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04003423
3424##
3425
3426# ------------------------------------------------------------------------------
3427
3428#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const
3429
Cary Clark154beea2017-10-26 07:58:48 -04003430Maps src Vector array of length count to Vector Point array of equal or greater
3431length. Vectors are mapped by multiplying each Vector by Matrix, treating
3432Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003433
Cary Clark154beea2017-10-26 07:58:48 -04003434#Code
3435#Literal
3436 | A B 0 | | x |
3437Matrix = | D E 0 |, src = | y |
3438 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003439##
Cary Clark154beea2017-10-26 07:58:48 -04003440
3441where
3442
3443#Code
3444#Literal
3445for (i = 0; i < count; ++i) {
3446 x = src[i].fX
3447 y = src[i].fY
3448}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003449##
Cary Clark154beea2017-10-26 07:58:48 -04003450
3451each dst Vector is computed as:
3452
3453#Code
3454#Literal
3455 |A B 0| |x| Ax+By Dx+Ey
3456Matrix * src = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
3457 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003458##
3459
Cary Clark154beea2017-10-26 07:58:48 -04003460src and dst may point to the same storage.
3461
3462#Param dst storage for mapped Vectors ##
3463#Param src Vectors to transform ##
3464#Param count number of Vectors to transform ##
3465
Cary Clarkbc5697d2017-10-04 14:31:33 -04003466#Example
Cary Clark154beea2017-10-26 07:58:48 -04003467 SkPaint paint;
3468 paint.setAntiAlias(true);
3469 paint.setStyle(SkPaint::kStroke_Style);
3470 SkMatrix matrix;
3471 matrix.reset();
3472 const SkVector radii[] = {{8, 4}, {9, 1}, {6, 2}, {7, 3}};
3473 for (int i = 0; i < 4; ++i) {
3474 SkVector rScaled[4];
3475 matrix.preScale(1.5f, 2.f);
3476 matrix.mapVectors(rScaled, radii, SK_ARRAY_COUNT(radii));
3477 SkRRect rrect;
3478 rrect.setRectRadii({20, 20, 180, 70}, rScaled);
3479 canvas->drawRRect(rrect, paint);
3480 canvas->translate(0, 60);
3481 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003482##
3483
Brian Salomonfa3783f2018-01-05 13:49:07 -05003484#SeeAlso mapVector mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003485
3486##
3487
3488# ------------------------------------------------------------------------------
3489
3490#Method void mapVectors(SkVector vecs[], int count) const
3491
Cary Clark154beea2017-10-26 07:58:48 -04003492Maps vecs Vector array of length count in place, multiplying each Vector by
3493Matrix, treating Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003494
Cary Clark154beea2017-10-26 07:58:48 -04003495#Code
3496#Literal
3497 | A B 0 | | x |
3498Matrix = | D E 0 |, vec = | y |
3499 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003500##
Cary Clark154beea2017-10-26 07:58:48 -04003501
3502where
3503
3504#Code
3505#Literal
3506for (i = 0; i < count; ++i) {
3507 x = vecs[i].fX
3508 y = vecs[i].fY
3509}
Cary Clarkbc5697d2017-10-04 14:31:33 -04003510##
3511
Cary Clark154beea2017-10-26 07:58:48 -04003512each result Vector is computed as:
3513
3514#Code
3515#Literal
3516 |A B 0| |x| Ax+By Dx+Ey
3517Matrix * vec = |D E 0| |y| = |Ax+By Dx+Ey Gx+Hy+I| = ------- , -------
3518 |G H I| |1| Gx+Hy+I Gx+Hy+I
3519##
3520
3521#Param vecs Vectors to transform, and storage for mapped Vectors ##
3522#Param count number of Vectors to transform ##
3523
Cary Clarkbc5697d2017-10-04 14:31:33 -04003524#Example
Cary Clark154beea2017-10-26 07:58:48 -04003525 SkPaint paint;
3526 paint.setAntiAlias(true);
3527 paint.setStyle(SkPaint::kStroke_Style);
3528 SkMatrix matrix;
3529 matrix.setScale(2, 3);
3530 SkVector radii[] = {{7, 7}, {3, 3}, {2, 2}, {4, 0}};
3531 for (int i = 0; i < 4; ++i) {
3532 SkRRect rrect;
3533 rrect.setRectRadii({20, 20, 180, 70}, radii);
3534 canvas->drawRRect(rrect, paint);
3535 canvas->translate(0, 60);
3536 matrix.mapVectors(radii, SK_ARRAY_COUNT(radii));
3537 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003538##
3539
Brian Salomonfa3783f2018-01-05 13:49:07 -05003540#SeeAlso mapVector mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003541
3542##
3543
3544# ------------------------------------------------------------------------------
3545
3546#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const
3547
Cary Clark154beea2017-10-26 07:58:48 -04003548Maps Vector (x, y) to result. Vector is mapped by multiplying by Matrix,
3549treating Matrix translation as zero. Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003550
Cary Clark154beea2017-10-26 07:58:48 -04003551#Code
3552#Literal
3553 | A B 0 | | dx |
3554Matrix = | D E 0 |, vec = | dy |
3555 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003556##
3557
Cary Clark154beea2017-10-26 07:58:48 -04003558each result Vector is computed as:
3559
3560#Code
3561#Literal
3562#Outdent
3563 |A B 0| |dx| A*dx+B*dy D*dx+E*dy
3564Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
3565 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
3566##
3567
3568#Param dx x-coordinate of Vector to map ##
3569#Param dy y-coordinate of Vector to map ##
3570#Param result storage for mapped Vector ##
3571
3572#Example
3573 SkPaint paint;
3574 paint.setColor(SK_ColorGREEN);
3575 paint.setAntiAlias(true);
3576 paint.setTextSize(48);
3577 SkMatrix matrix;
3578 matrix.setRotate(90);
3579 SkVector offset = { 7, 7 };
3580 for (int i = 0; i < 4; ++i) {
3581 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
3582 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
3583 matrix.mapVector(offset.fX, offset.fY, &offset);
3584 canvas->translate(0, 60);
3585 canvas->drawString("Text", 50, 0, paint);
3586 }
3587##
3588
Brian Salomonfa3783f2018-01-05 13:49:07 -05003589#SeeAlso mapVectors mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003590
3591##
3592
3593# ------------------------------------------------------------------------------
3594
3595#Method SkVector mapVector(SkScalar dx, SkScalar dy) const
3596
Cary Clark154beea2017-10-26 07:58:48 -04003597Returns Vector (x, y) multiplied by Matrix, treating Matrix translation as zero.
3598Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04003599
Cary Clark154beea2017-10-26 07:58:48 -04003600#Code
3601#Literal
3602 | A B 0 | | dx |
3603Matrix = | D E 0 |, vec = | dy |
3604 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003605##
3606
Cary Clark154beea2017-10-26 07:58:48 -04003607each result Vector is computed as:
3608
3609#Code
3610#Literal
3611#Outdent
3612 |A B 0| |dx| A*dx+B*dy D*dx+E*dy
3613Matrix * vec = |D E 0| |dy| = |A*dx+B*dy D*dx+E*dy G*dx+H*dy+I| = ----------- , -----------
3614 |G H I| | 1| G*dx+H*dy+I G*dx+*dHy+I
3615##
3616
3617#Param dx x-coordinate of Vector to map ##
3618#Param dy y-coordinate of Vector to map ##
3619
3620#Return mapped Vector ##
3621
3622#Example
3623 SkPaint paint;
3624 paint.setColor(SK_ColorGREEN);
3625 paint.setAntiAlias(true);
3626 paint.setTextSize(48);
3627 SkMatrix matrix;
3628 matrix.setRotate(90);
3629 SkVector offset = { 7, 7 };
3630 for (int i = 0; i < 4; ++i) {
3631 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
3632 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
3633 offset = matrix.mapVector(offset.fX, offset.fY);
3634 canvas->translate(0, 60);
3635 canvas->drawString("Text", 50, 0, paint);
3636 }
3637##
3638
Brian Salomonfa3783f2018-01-05 13:49:07 -05003639#SeeAlso mapVectors mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04003640
3641##
3642
3643# ------------------------------------------------------------------------------
3644
3645#Method bool mapRect(SkRect* dst, const SkRect& src) const
3646
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
3709
Cary Clark154beea2017-10-26 07:58:48 -04003710Maps four corners of rect to dst. Points are mapped by multiplying each
3711rect corner by Matrix. rect corner is processed in this order:
3712(rect.fLeft, rect.fTop), (rect.fRight, rect.fTop), (rect.fRight, rect.fBottom),
3713(rect.fLeft, rect.fBottom).
Cary Clarkbc5697d2017-10-04 14:31:33 -04003714
Cary Clark154beea2017-10-26 07:58:48 -04003715rect may be empty: rect.fLeft may be greater than or equal to rect.fRight;
3716rect.fTop may be greater than or equal to rect.fBottom.
3717
3718Given:
3719
3720#Code
3721#Literal
3722 | A B C | | x |
3723Matrix = | D E F |, pt = | y |
3724 | G H I | | 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04003725##
Cary Clark154beea2017-10-26 07:58:48 -04003726
3727where pt is initialized from each of (rect.fLeft, rect.fTop),
3728(rect.fRight, rect.fTop), (rect.fRight, rect.fBottom), (rect.fLeft, rect.fBottom),
3729each dst Point is computed as:
3730
3731#Code
3732#Literal
3733 |A B C| |x| Ax+By+C Dx+Ey+F
3734Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
3735 |G H I| |1| Gx+Hy+I Gx+Hy+I
Cary Clarkbc5697d2017-10-04 14:31:33 -04003736##
3737
Cary Clark154beea2017-10-26 07:58:48 -04003738#Param dst storage for mapped corner Points ##
3739#Param rect Rect to map ##
3740
Cary Clarkbc5697d2017-10-04 14:31:33 -04003741#Example
Cary Clark2ade9972017-11-02 17:49:34 -04003742#Height 192
Cary Clark154beea2017-10-26 07:58:48 -04003743 SkPaint paint;
3744 paint.setAntiAlias(true);
3745 SkMatrix matrix;
3746 matrix.setRotate(60, 128, 128);
3747 SkRect rect = {50, 50, 150, 150};
3748 SkPoint pts[4];
3749 matrix.mapRectToQuad(pts, rect);
3750 for (int i = 0; i < 4; ++i) {
3751 canvas->drawCircle(pts[i].fX, pts[i].fY, 3, paint);
3752 }
3753 canvas->concat(matrix);
3754 paint.setStyle(SkPaint::kStroke_Style);
3755 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003756##
3757
Cary Clark154beea2017-10-26 07:58:48 -04003758#SeeAlso mapRect mapRectScaleTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04003759
3760##
3761
3762# ------------------------------------------------------------------------------
3763
3764#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const
3765
Cary Clark154beea2017-10-26 07:58:48 -04003766Sets dst to bounds of src corners mapped by Matrix. If matrix contains
3767elements other than scale or translate: asserts if SK_DEBUG is defined;
3768otherwise, results are undefined.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003769
Cary Clark154beea2017-10-26 07:58:48 -04003770#Param dst storage for bounds of mapped Points ##
3771#Param src Rect to map ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003772
3773#Example
Cary Clark154beea2017-10-26 07:58:48 -04003774 SkPaint paint;
3775 SkMatrix matrix;
3776 SkRect rect = {100, 50, 150, 180};
3777 matrix.setScale(2, .5f, rect.centerX(), rect.centerY());
3778 SkRect rotated;
3779 matrix.mapRectScaleTranslate(&rotated, rect);
3780 paint.setStyle(SkPaint::kStroke_Style);
3781 canvas->drawRect(rect, paint);
3782 paint.setColor(SK_ColorRED);
3783 canvas->drawRect(rotated, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003784##
3785
Cary Clark154beea2017-10-26 07:58:48 -04003786#SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04003787
3788##
3789
3790# ------------------------------------------------------------------------------
3791
3792#Method SkScalar mapRadius(SkScalar radius) const
3793
Cary Clark154beea2017-10-26 07:58:48 -04003794Returns geometric mean radius of ellipse formed by constructing Circle of
3795size radius, and mapping constructed Circle with Matrix. The result squared is
3796equal to the major axis length times the minor axis length.
3797Result is not meaningful if Matrix contains perspective elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003798
Cary Clark154beea2017-10-26 07:58:48 -04003799#Param radius Circle size to map ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003800
Cary Clark154beea2017-10-26 07:58:48 -04003801#Return average mapped radius ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003802
3803#Example
Cary Clark154beea2017-10-26 07:58:48 -04003804#Description
3805The area enclosed by a square with sides equal to mappedRadius is the same as
3806the area enclosed by the ellipse major and minor axes.
3807##
3808 SkPaint paint;
3809 paint.setAntiAlias(true);
3810 SkMatrix matrix;
3811 const SkPoint center = {108, 93};
3812 matrix.setScale(2, .5f, center.fX, center.fY);
3813 matrix.postRotate(45, center.fX, center.fY);
3814 const SkScalar circleRadius = 50;
3815 SkScalar mappedRadius = matrix.mapRadius(circleRadius);
3816 SkVector minorAxis, majorAxis;
3817 matrix.mapVector(0, circleRadius, &minorAxis);
3818 matrix.mapVector(circleRadius, 0, &majorAxis);
3819 SkString mappedArea;
3820 mappedArea.printf("area = %g", mappedRadius * mappedRadius);
3821 canvas->drawString(mappedArea, 145, 250, paint);
3822 canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint);
3823 paint.setColor(SK_ColorRED);
3824 SkString axArea;
3825 axArea.printf("area = %g", majorAxis.length() * minorAxis.length());
3826 paint.setStyle(SkPaint::kFill_Style);
3827 canvas->drawString(axArea, 15, 250, paint);
3828 paint.setStyle(SkPaint::kStroke_Style);
3829 canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint);
3830 paint.setColor(SK_ColorBLACK);
3831 canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint);
3832 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint);
3833 canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint);
3834 canvas->concat(matrix);
3835 canvas->drawCircle(center.fX, center.fY, circleRadius, paint);
3836 paint.setColor(SK_ColorRED);
3837 canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint);
3838 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04003839##
3840
Cary Clark154beea2017-10-26 07:58:48 -04003841#SeeAlso mapVector
Cary Clarkbc5697d2017-10-04 14:31:33 -04003842
3843##
3844
3845# ------------------------------------------------------------------------------
3846
3847#Method bool isFixedStepInX() const
3848
Cary Clark154beea2017-10-26 07:58:48 -04003849Returns true if a unit step in x at some y mapped through Matrix can be
3850represented by a constant Vector. Returns true if getType returns kIdentity_Mask,
3851or combinations of: kTranslate_Mask, kScale_Mask, and kAffine_Mask.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003852
Cary Clark154beea2017-10-26 07:58:48 -04003853May return true if getType returns kPerspective_Mask, but only when Matrix
3854does not include rotation or skewing along the y-axis.
3855
3856#Return true if Matrix does not have complex perspective ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003857
3858#Example
Cary Clark154beea2017-10-26 07:58:48 -04003859 SkMatrix matrix;
3860 for (SkScalar px : { 0.0f, 0.1f } ) {
3861 for (SkScalar py : { 0.0f, 0.1f } ) {
3862 for (SkScalar sy : { 1, 2 } ) {
3863 matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1);
3864 matrix.dump();
3865 SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false");
3866 }
3867 }
3868 }
3869#StdOut
3870[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
3871isFixedStepInX: true
3872[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000]
3873isFixedStepInX: true
3874[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000]
3875isFixedStepInX: true
3876[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000]
3877isFixedStepInX: true
3878[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000]
3879isFixedStepInX: false
3880[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000]
3881isFixedStepInX: false
3882[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000]
3883isFixedStepInX: false
3884[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000]
3885isFixedStepInX: false
3886##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003887##
3888
Cary Clark154beea2017-10-26 07:58:48 -04003889#SeeAlso fixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04003890
3891##
3892
3893# ------------------------------------------------------------------------------
3894
3895#Method SkVector fixedStepInX(SkScalar y) const
3896
Cary Clark154beea2017-10-26 07:58:48 -04003897Returns Vector representing a unit step in x at y mapped through Matrix.
3898If isFixedStepInX is false, returned value is undefined.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003899
Cary Clark154beea2017-10-26 07:58:48 -04003900#Param y position of line parallel to x-axis ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003901
Cary Clark154beea2017-10-26 07:58:48 -04003902#Return Vector advance of mapped unit step in x ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003903
3904#Example
Cary Clark154beea2017-10-26 07:58:48 -04003905#Image 3
3906 SkMatrix matrix;
3907 const SkPoint center = { 128, 128 };
3908 matrix.setScale(20, 25, center.fX, center.fY);
3909 matrix.postRotate(75, center.fX, center.fY);
3910 {
3911 SkAutoCanvasRestore acr(canvas, true);
3912 canvas->concat(matrix);
3913 canvas->drawBitmap(source, 0, 0);
3914 }
3915 if (matrix.isFixedStepInX()) {
3916 SkPaint paint;
3917 paint.setAntiAlias(true);
3918 SkVector step = matrix.fixedStepInX(128);
3919 SkVector end = center + step;
3920 canvas->drawLine(center, end, paint);
3921 SkVector arrow = { step.fX + step.fY, step.fY - step.fX};
3922 arrow = arrow * .25f;
3923 canvas->drawLine(end, end - arrow, paint);
3924 canvas->drawLine(end, {end.fX + arrow.fY, end.fY - arrow.fX}, paint);
3925 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04003926##
3927
Cary Clark154beea2017-10-26 07:58:48 -04003928#SeeAlso isFixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04003929
3930##
3931
3932# ------------------------------------------------------------------------------
3933
3934#Method bool cheapEqualTo(const SkMatrix& m) const
3935
3936Returns true if Matrix equals m, using an efficient comparison.
3937
Cary Clark154beea2017-10-26 07:58:48 -04003938Returns false when the sign of zero values is the different; when one
Cary Clarkbc5697d2017-10-04 14:31:33 -04003939matrix has positive zero value and the other has negative zero value.
3940
Cary Clark154beea2017-10-26 07:58:48 -04003941Returns true even when both Matrices contain NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003942
Cary Clark154beea2017-10-26 07:58:48 -04003943NaN never equals any value, including itself. To improve performance, NaN values
3944are treated as bit patterns that are equal if their bit patterns are equal.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003945
Cary Clark154beea2017-10-26 07:58:48 -04003946#Param m Matrix to compare ##
3947
3948#Return true if m and Matrix are represented by identical bit patterns ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003949
3950#Example
Cary Clark154beea2017-10-26 07:58:48 -04003951 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
3952 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
3953 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
Cary Clarkbc5697d2017-10-04 14:31:33 -04003954 };
Cary Clark154beea2017-10-26 07:58:48 -04003955 SkMatrix a, b;
3956 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
3957 b.setIdentity();
3958 debugster("identity", a, b);
3959 a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1);
3960 debugster("neg zero", a, b);
3961 a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
3962 debugster(" one NaN", a, b);
3963 b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
3964 debugster("both NaN", a, b);
3965#StdOut
3966identity: a == b a.cheapEqualTo(b): true
3967neg zero: a == b a.cheapEqualTo(b): false
3968 one NaN: a != b a.cheapEqualTo(b): false
3969both NaN: a != b a.cheapEqualTo(b): true
3970##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003971##
3972
Cary Clark154beea2017-10-26 07:58:48 -04003973#SeeAlso operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04003974
3975##
3976
3977# ------------------------------------------------------------------------------
3978
Cary Clark154beea2017-10-26 07:58:48 -04003979#Method bool operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04003980
Cary Clark154beea2017-10-26 07:58:48 -04003981Compares a and b; returns true if a and b are numerically equal. Returns true
3982even if sign of zero values are different. Returns false if either Matrix
3983contains NaN, even if the other Matrix also contains NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04003984
Cary Clark154beea2017-10-26 07:58:48 -04003985#Param a Matrix to compare ##
3986#Param b Matrix to compare ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003987
Cary Clark154beea2017-10-26 07:58:48 -04003988#Return true if m and Matrix are numerically equal ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003989
3990#Example
Cary Clark154beea2017-10-26 07:58:48 -04003991 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
3992 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
3993 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
3994 };
3995 SkMatrix a, b;
3996 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
3997 b.setScale(2, 4);
3998 b.postScale(0.5f, 0.25f);
3999 debugster("identity", a, b);
4000#StdOut
4001identity: a == b a.cheapEqualTo(b): true
4002##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004003##
4004
Cary Clark154beea2017-10-26 07:58:48 -04004005#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004006
4007##
4008
4009# ------------------------------------------------------------------------------
4010
Cary Clark154beea2017-10-26 07:58:48 -04004011#Method bool operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004012
Cary Clark154beea2017-10-26 07:58:48 -04004013Compares a and b; returns true if a and b are not numerically equal. Returns false
4014even if sign of zero values are different. Returns true if either Matrix
4015contains NaN, even if the other Matrix also contains NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004016
Cary Clark154beea2017-10-26 07:58:48 -04004017#Param a Matrix to compare ##
4018#Param b Matrix to compare ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004019
Cary Clark154beea2017-10-26 07:58:48 -04004020#Return true if m and Matrix are numerically not equal ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004021
4022#Example
Cary Clark154beea2017-10-26 07:58:48 -04004023 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
4024 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
4025 a != b ? '!' : '=', a.cheapEqualTo(b) ? "true" : "false");
4026 };
4027 SkMatrix a, b;
4028 a.setAll(1, 0, 0, 0, 1, 0, 1, 0, 1);
4029 a.invert(&b);
4030 debugster("identity", a, b);
Cary Clarkbc5697d2017-10-04 14:31:33 -04004031##
4032
Cary Clark154beea2017-10-26 07:58:48 -04004033#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04004034
4035##
4036
4037# ------------------------------------------------------------------------------
4038
4039#Method void dump() const
4040
Cary Clark154beea2017-10-26 07:58:48 -04004041Writes text representation of Matrix to standard output. Floating point values
4042are written with limited precision; it may not be possible to reconstruct
4043original Matrix from output.
4044
Cary Clarkbc5697d2017-10-04 14:31:33 -04004045#Example
Cary Clark154beea2017-10-26 07:58:48 -04004046 SkMatrix matrix;
4047 matrix.setRotate(45);
4048 matrix.dump();
4049 SkMatrix nearlyEqual;
4050 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
4051 nearlyEqual.dump();
4052 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
4053#StdOut
4054[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4055[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4056matrix != nearlyEqual
4057##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004058##
4059
Cary Clark154beea2017-10-26 07:58:48 -04004060#SeeAlso toString
Cary Clarkbc5697d2017-10-04 14:31:33 -04004061
4062##
4063
4064# ------------------------------------------------------------------------------
4065
4066#Method void toString(SkString* str) const
4067
Cary Clark154beea2017-10-26 07:58:48 -04004068Creates string representation of Matrix. Floating point values
4069are written with limited precision; it may not be possible to reconstruct
4070original Matrix from output.
4071
4072#Param str storage for string representation of Matrix ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004073
4074#Example
Cary Clark154beea2017-10-26 07:58:48 -04004075 SkMatrix matrix;
4076 matrix.setRotate(45);
4077 SkString mStr, neStr;
4078 matrix.toString(&mStr);
4079 SkMatrix nearlyEqual;
4080 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
4081 nearlyEqual.toString(&neStr);
4082 SkDebugf("mStr %s\n", mStr.c_str());
4083 SkDebugf("neStr %s\n", neStr.c_str());
4084 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
4085#StdOut
4086mStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4087neStr [ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
4088matrix != nearlyEqual
4089##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004090##
4091
Cary Clark154beea2017-10-26 07:58:48 -04004092#SeeAlso dump
Cary Clarkbc5697d2017-10-04 14:31:33 -04004093
4094##
4095
4096# ------------------------------------------------------------------------------
4097
4098#Method SkScalar getMinScale() const
4099
Cary Clark154beea2017-10-26 07:58:48 -04004100Returns the minimum scaling factor of Matrix by decomposing the scaling and
4101skewing elements.
4102Returns -1 if scale factor overflows or Matrix contains perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004103
4104#Return minimum scale factor
4105##
4106
4107#Example
Cary Clark154beea2017-10-26 07:58:48 -04004108 SkMatrix matrix;
4109 matrix.setScale(42, 24);
4110 SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale());
4111#StdOut
4112matrix.getMinScale() 24
4113##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004114##
4115
Cary Clark154beea2017-10-26 07:58:48 -04004116#SeeAlso getMaxScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04004117
4118##
4119
4120# ------------------------------------------------------------------------------
4121
4122#Method SkScalar getMaxScale() const
4123
Cary Clark154beea2017-10-26 07:58:48 -04004124Returns the maximum scaling factor of Matrix by decomposing the scaling and
4125skewing elements.
4126Returns -1 if scale factor overflows or Matrix contains perspective.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004127
4128#Return maximum scale factor
4129##
4130
4131#Example
Cary Clark154beea2017-10-26 07:58:48 -04004132 SkMatrix matrix;
4133 matrix.setScale(42, 24);
4134 SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale());
4135#StdOut
4136matrix.getMaxScale() 42
4137##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004138##
4139
Cary Clark154beea2017-10-26 07:58:48 -04004140#SeeAlso getMinScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04004141
4142##
4143
4144# ------------------------------------------------------------------------------
4145
4146#Method bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const
4147
Cary Clark154beea2017-10-26 07:58:48 -04004148Sets scaleFactors[0] to the minimum scaling factor, and scaleFactors[1] to the
4149maximum scaling factor. Scaling factors are computed by decomposing
4150the Matrix scaling and skewing elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004151
Cary Clark154beea2017-10-26 07:58:48 -04004152Returns true if scaleFactors are found; otherwise, returns false and sets
4153scaleFactors to undefined values.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004154
Cary Clark154beea2017-10-26 07:58:48 -04004155#Param scaleFactors storage for minimum and maximum scale factors ##
4156
4157#Return true if scale factors were computed correctly ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004158
4159#Example
Cary Clark154beea2017-10-26 07:58:48 -04004160 SkMatrix matrix;
4161 matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0);
4162 matrix.invert(&matrix);
4163 SkScalar factor[2] = {2, 2};
4164 bool result = matrix.getMinMaxScales(factor);
4165 SkDebugf("matrix.getMinMaxScales() %s %g %g\n", result ? "true" : "false", factor[0], factor[1]);
4166#StdOut
4167matrix.getMinMaxScales() false 2 2
4168##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004169##
4170
Cary Clark154beea2017-10-26 07:58:48 -04004171#SeeAlso getMinScale getMaxScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04004172
4173##
4174
4175# ------------------------------------------------------------------------------
4176
4177#Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const
4178
Cary Clark154beea2017-10-26 07:58:48 -04004179Decomposes Matrix into scale components and whatever remains. Returns false if
4180Matrix could not be decomposed.
4181
4182Sets scale to portion of Matrix that scales in x and y. Sets remaining to Matrix
4183with x and y scaling factored out. remaining may be passed as nullptr
4184to determine if Matrix can be decomposed without computing remainder.
4185
4186Returns true if scale components are found. scale and remaining are
4187unchanged if Matrix contains perspective; scale factors are not finite, or
4188are nearly zero.
4189
4190On success
4191
Cary Clarkbc5697d2017-10-04 14:31:33 -04004192#Formula
Cary Clark154beea2017-10-26 07:58:48 -04004193Matrix = scale * Remaining
Cary Clarkbc5697d2017-10-04 14:31:33 -04004194##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004195
Cary Clark154beea2017-10-26 07:58:48 -04004196#Param scale x and y scaling factors; may be nullptr ##
4197#Param remaining Matrix without scaling; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004198
Cary Clark154beea2017-10-26 07:58:48 -04004199#Return true if scale can be computed ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004200
4201#Example
Cary Clark154beea2017-10-26 07:58:48 -04004202 SkMatrix matrix;
4203 matrix.setRotate(90 * SK_Scalar1);
4204 matrix.postScale(1.f / 4, 1.f / 2);
4205 matrix.dump();
4206 SkSize scale = {SK_ScalarNaN, SK_ScalarNaN};
4207 SkMatrix remaining;
4208 remaining.reset();
4209 bool success = matrix.decomposeScale(&scale, &remaining);
4210 SkDebugf("success: %s ", success ? "true" : "false");
4211 SkDebugf("scale: %g, %g\n", scale.width(), scale.height());
4212 remaining.dump();
4213 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height());
4214 SkMatrix combined = SkMatrix::Concat(scaleMatrix, remaining);
4215 combined.dump();
4216#StdOut
4217[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4218success: true scale: 0.5, 0.25
4219[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4220[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
4221##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004222##
4223
Cary Clark154beea2017-10-26 07:58:48 -04004224#SeeAlso setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04004225
4226##
4227
4228# ------------------------------------------------------------------------------
4229
4230#Method static const SkMatrix& I()
4231
Cary Clark154beea2017-10-26 07:58:48 -04004232Returns reference to const identity Matrix. Returned Matrix is set to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004233
Cary Clark154beea2017-10-26 07:58:48 -04004234#Code
4235#Literal
4236| 1 0 0 |
4237| 0 1 0 |
4238| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004239##
4240
Cary Clark154beea2017-10-26 07:58:48 -04004241#Return const identity Matrix ##
4242
4243#Example
4244 SkMatrix m1, m2, m3;
4245 m1.reset();
4246 m2.setIdentity();
4247 m3 = SkMatrix::I();
4248 SkDebugf("m1 %c= m2\n", m1 == m2 ? '=' : '!');
4249 SkDebugf("m2 %c= m3\n", m1 == m2 ? '=' : '!');
4250#StdOut
4251m1 == m2
4252m2 == m3
4253##
4254##
4255
4256#SeeAlso reset() setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04004257
4258##
4259
4260# ------------------------------------------------------------------------------
4261
4262#Method static const SkMatrix& InvalidMatrix()
4263
Cary Clark154beea2017-10-26 07:58:48 -04004264Returns reference to a const Matrix with invalid values. Returned Matrix is set
4265to:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004266
Cary Clark154beea2017-10-26 07:58:48 -04004267#Code
4268#Literal
4269| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
4270| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
4271| SK_ScalarMax SK_ScalarMax SK_ScalarMax |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004272##
4273
Cary Clark154beea2017-10-26 07:58:48 -04004274#Return const invalid Matrix ##
4275
4276#Example
4277 SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX());
4278#StdOut
4279scaleX 3.40282e+38
4280##
4281##
4282
4283#SeeAlso SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04004284
4285##
4286
4287# ------------------------------------------------------------------------------
4288
4289#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b)
4290
Cary Clark154beea2017-10-26 07:58:48 -04004291Returns Matrix a multiplied by Matrix b.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004292
Cary Clark154beea2017-10-26 07:58:48 -04004293Given:
Cary Clarkbc5697d2017-10-04 14:31:33 -04004294
Cary Clark154beea2017-10-26 07:58:48 -04004295#Code
4296#Literal
4297 | A B C | | J K L |
4298a = | D E F |, b = | M N O |
4299 | G H I | | P Q R |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004300##
4301
Cary Clark154beea2017-10-26 07:58:48 -04004302sets Matrix to:
4303
4304#Code
4305#Literal
4306 | A B C | | J K L | | AJ+BM+CP AK+BN+CQ AL+BO+CR |
4307a * b = | D E F | * | M N O | = | DJ+EM+FP DK+EN+FQ DL+EO+FR |
4308 | G H I | | P Q R | | GJ+HM+IP GK+HN+IQ GL+HO+IR |
4309##
4310
4311#Param a Matrix on left side of multiply expression ##
4312#Param b Matrix on right side of multiply expression ##
4313
4314#Return Matrix computed from a times b ##
4315
4316#Example
4317#Height 64
4318#Image 4
4319#Description
4320setPolyToPoly creates perspective matrices, one the inverse of the other.
4321Multiplying the matrix by its inverse turns into an identity matrix.
4322##
4323SkMatrix matrix, matrix2;
4324SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
4325SkRect::Make(source.bounds()).toQuad(bitmapBounds);
4326matrix.setPolyToPoly(bitmapBounds, perspect, 4);
4327matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
4328SkMatrix concat = SkMatrix::Concat(matrix, matrix2);
4329canvas->concat(concat);
4330canvas->drawBitmap(source, 0, 0);
4331##
4332
4333#SeeAlso preConcat postConcat
Cary Clarkbc5697d2017-10-04 14:31:33 -04004334
4335##
4336
4337# ------------------------------------------------------------------------------
4338
4339#Method void dirtyMatrixTypeCache()
4340
Cary Clark154beea2017-10-26 07:58:48 -04004341Sets internal cache to unknown state. Use to force update after repeated
4342modifications to Matrix element reference returned by operator[](int index).
Cary Clarkbc5697d2017-10-04 14:31:33 -04004343
4344#Example
Cary Clark154beea2017-10-26 07:58:48 -04004345SkMatrix matrix;
4346matrix.setIdentity();
4347SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
4348SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
4349skewRef = 0;
4350SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
4351skewRef = 1;
4352SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
4353matrix.dirtyMatrixTypeCache();
4354SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
4355#StdOut
4356with identity matrix: x = 24
4357after skew x mod: x = 24
4358after 2nd skew x mod: x = 24
4359after dirty cache: x = 66
4360##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004361##
4362
Cary Clark154beea2017-10-26 07:58:48 -04004363#SeeAlso operator[](int index) getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04004364
4365##
4366
4367# ------------------------------------------------------------------------------
4368
4369#Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
4370
Cary Clark154beea2017-10-26 07:58:48 -04004371Initializes Matrix with scale and translate elements.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004372
Cary Clark154beea2017-10-26 07:58:48 -04004373#Code
4374#Literal
4375| sx 0 tx |
4376| 0 sy ty |
4377| 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04004378##
4379
Cary Clark154beea2017-10-26 07:58:48 -04004380#Param sx horizontal scale factor to store ##
4381#Param sy vertical scale factor to store ##
4382#Param tx horizontal translation to store ##
4383#Param ty vertical translation to store ##
4384
4385#Example
4386SkMatrix matrix;
4387matrix.setScaleTranslate(1, 2, 3, 4);
4388matrix.dump();
4389#StdOut
4390[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000]
4391##
4392##
4393
4394#SeeAlso setScale preTranslate postTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04004395
4396##
4397
4398# ------------------------------------------------------------------------------
4399
4400#Method bool isFinite() const
4401
Cary Clark154beea2017-10-26 07:58:48 -04004402Returns true if all elements of the matrix are finite. Returns false if any
4403element is infinity, or NaN.
Cary Clarkbc5697d2017-10-04 14:31:33 -04004404
Cary Clark154beea2017-10-26 07:58:48 -04004405#Return true if matrix has only finite elements ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004406
4407#Example
Cary Clark154beea2017-10-26 07:58:48 -04004408SkMatrix matrix = SkMatrix::MakeTrans(SK_ScalarNaN, 0);
4409matrix.dump();
4410SkDebugf("matrix is finite: %s\n", matrix.isFinite() ? "true" : "false");
4411SkDebugf("matrix %c= matrix\n", matrix == matrix ? '=' : '!');
4412#StdOut
4413[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
4414matrix is finite: false
4415matrix != matrix
4416##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004417##
4418
Cary Clark154beea2017-10-26 07:58:48 -04004419#SeeAlso operator==
Cary Clarkbc5697d2017-10-04 14:31:33 -04004420
4421##
4422
4423#Class SkMatrix ##
4424
4425#Topic Matrix ##