blob: 17ceab5d0c839c08a0fa58cefb1515e419f50c5c [file] [log] [blame]
Cary Clarkbc5697d2017-10-04 14:31:33 -04001#Topic Matrix
Cary Clark137b8742018-05-30 09:21:49 -04002#Alias Matrices ##
3#Alias Matrix_Reference ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04004
5#Class SkMatrix
6
Cary Clark61313f32018-10-08 14:57:48 -04007#Code
8#Populate
9##
10
Cary Clark154beea2017-10-26 07:58:48 -040011Matrix holds a 3x3 matrix for transforming coordinates. This allows mapping
12Points and Vectors with translation, scaling, skewing, rotation, and
13perspective.
Cary Clark884dd7d2017-10-11 10:37:52 -040014
Cary Clark154beea2017-10-26 07:58:48 -040015Matrix elements are in row major order. Matrix does not have a constructor,
16so it must be explicitly initialized. setIdentity initializes Matrix
17so it has no effect. setTranslate, setScale, setSkew, setRotate, set9 and setAll
18initializes all Matrix elements with the corresponding mapping.
Cary Clark884dd7d2017-10-11 10:37:52 -040019
Cary Clark682c58d2018-05-16 07:07:07 -040020Matrix includes a hidden variable that classifies the type of matrix to
Cary Clark154beea2017-10-26 07:58:48 -040021improve performance. Matrix is not thread safe unless getType is called first.
Cary Clarkbc5697d2017-10-04 14:31:33 -040022
Cary Clarkbc5697d2017-10-04 14:31:33 -040023# ------------------------------------------------------------------------------
24
Cary Clark61313f32018-10-08 14:57:48 -040025#Method static SkMatrix MakeScale(SkScalar sx, SkScalar sy)
26#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -050027#Line # constructs from scale in x and y ##
Cary Clark09d80c02018-10-31 12:14:03 -040028#Populate
Cary Clark154beea2017-10-26 07:58:48 -040029
30#Example
31#Image 4
32canvas->concat(SkMatrix::MakeScale(4, 3));
33canvas->drawBitmap(source, 0, 0);
34##
35
36#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -040037
38##
39
40# ------------------------------------------------------------------------------
41
Cary Clark61313f32018-10-08 14:57:48 -040042#Method static SkMatrix MakeScale(SkScalar scale)
Cary Clark09d80c02018-10-31 12:14:03 -040043#Populate
Cary Clark154beea2017-10-26 07:58:48 -040044
45#Example
46#Image 4
47canvas->concat(SkMatrix::MakeScale(4));
48canvas->drawBitmap(source, 0, 0);
49##
50
51#SeeAlso setScale postScale preScale
Cary Clarkbc5697d2017-10-04 14:31:33 -040052
53##
54
55# ------------------------------------------------------------------------------
56
Cary Clark61313f32018-10-08 14:57:48 -040057#Method static SkMatrix MakeTrans(SkScalar dx, SkScalar dy)
58#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -050059#Line # constructs from translate in x and y ##
Cary Clark09d80c02018-10-31 12:14:03 -040060#Populate
Cary Clark154beea2017-10-26 07:58:48 -040061
62#Example
63#Image 4
64SkMatrix matrix = SkMatrix::MakeTrans(64, 48);
65for (int i = 0; i < 4; ++i) {
66 canvas->drawBitmap(source, 0, 0);
67 canvas->concat(matrix);
68}
69##
70
71#SeeAlso setTranslate postTranslate preTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -040072
73##
74
75# ------------------------------------------------------------------------------
76
Cary Clark61313f32018-10-08 14:57:48 -040077#Method static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
Cary Clarkbef063a2017-10-31 15:44:45 -040078 SkScalar skewY, SkScalar scaleY, SkScalar transY,
79 SkScalar pers0, SkScalar pers1, SkScalar pers2)
Cary Clark61313f32018-10-08 14:57:48 -040080#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -050081#Line # constructs all nine values ##
Cary Clark09d80c02018-10-31 12:14:03 -040082#Populate
Cary Clarkbef063a2017-10-31 15:44:45 -040083
84#Example
85 SkPaint p;
86 p.setAntiAlias(true);
87 p.setTextSize(64);
88 for (SkScalar sx : { -1, 1 } ) {
89 for (SkScalar sy : { -1, 1 } ) {
90 SkAutoCanvasRestore autoRestore(canvas, true);
91 SkMatrix m = SkMatrix::MakeAll(sx, 1, 128, 0, sy, 128, 0, 0, 1);
92 canvas->concat(m);
93 canvas->drawString("K", 0, 0, p);
94 }
95 }
96##
97
98#SeeAlso setAll set9 postConcat preConcat
99
100##
101
102
103# ------------------------------------------------------------------------------
104
Cary Clarkbc5697d2017-10-04 14:31:33 -0400105#Enum TypeMask
Cary Clark682c58d2018-05-16 07:07:07 -0400106#Line # bit field for Matrix complexity ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400107#Code
Cary Clarka90ea222018-10-16 10:30:28 -0400108#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400109##
110
Cary Clark154beea2017-10-26 07:58:48 -0400111Enum of bit fields for mask returned by getType.
112Used to identify the complexity of Matrix, to optimize performance.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400113
Cary Clark154beea2017-10-26 07:58:48 -0400114#Const kIdentity_Mask 0
Cary Clark682c58d2018-05-16 07:07:07 -0400115#Line # identity Matrix; all bits clear ##
Cary Clark154beea2017-10-26 07:58:48 -0400116all bits clear if Matrix is identity
Cary Clarkbc5697d2017-10-04 14:31:33 -0400117##
Cary Clark154beea2017-10-26 07:58:48 -0400118#Const kTranslate_Mask 1
Cary Clark682c58d2018-05-16 07:07:07 -0400119#Line # translation Matrix ##
Cary Clark154beea2017-10-26 07:58:48 -0400120set if Matrix has translation
Cary Clarkbc5697d2017-10-04 14:31:33 -0400121##
Cary Clark154beea2017-10-26 07:58:48 -0400122#Const kScale_Mask 2
Cary Clark682c58d2018-05-16 07:07:07 -0400123#Line # scale Matrix ##
Cary Clark154beea2017-10-26 07:58:48 -0400124set if Matrix has x or y scale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400125##
Cary Clark154beea2017-10-26 07:58:48 -0400126#Const kAffine_Mask 4
Cary Clark682c58d2018-05-16 07:07:07 -0400127#Line # skew or rotate Matrix ##
Cary Clark154beea2017-10-26 07:58:48 -0400128set if Matrix skews or rotates
Cary Clarkbc5697d2017-10-04 14:31:33 -0400129##
Cary Clark154beea2017-10-26 07:58:48 -0400130#Const kPerspective_Mask 8
Cary Clark682c58d2018-05-16 07:07:07 -0400131#Line # perspective Matrix ##
Cary Clark154beea2017-10-26 07:58:48 -0400132set if Matrix has perspective
Cary Clarkbc5697d2017-10-04 14:31:33 -0400133##
134
135#Example
Cary Clark154beea2017-10-26 07:58:48 -0400136 auto debugster = [](const char* prefix, const SkMatrix& matrix) -> void {
137 SkString typeMask;
138 typeMask += SkMatrix::kIdentity_Mask == matrix.getType() ? "kIdentity_Mask " : "";
139 typeMask += SkMatrix::kTranslate_Mask & matrix.getType() ? "kTranslate_Mask " : "";
140 typeMask += SkMatrix::kScale_Mask & matrix.getType() ? "kScale_Mask " : "";
141 typeMask += SkMatrix::kAffine_Mask & matrix.getType() ? "kAffine_Mask " : "";
142 typeMask += SkMatrix::kPerspective_Mask & matrix.getType() ? "kPerspective_Mask" : "";
143 SkDebugf("after %s: %s\n", prefix, typeMask.c_str());
144 };
145SkMatrix matrix;
146matrix.reset();
147debugster("reset", matrix);
148matrix.postTranslate(1, 0);
149debugster("postTranslate", matrix);
150matrix.postScale(2, 1);
151debugster("postScale", matrix);
152matrix.postRotate(45);
153debugster("postScale", matrix);
154SkPoint polys[][4] = {{{0, 0}, {0, 1}, {1, 1}, {1, 0}}, {{0, 0}, {0, 1}, {2, 1}, {1, 0}}};
155matrix.setPolyToPoly(polys[0], polys[1], 4);
156debugster("setPolyToPoly", matrix);
157#StdOut
Cary Clark682c58d2018-05-16 07:07:07 -0400158after reset: kIdentity_Mask
159after postTranslate: kTranslate_Mask
160after postScale: kTranslate_Mask kScale_Mask
161after postScale: kTranslate_Mask kScale_Mask kAffine_Mask
Cary Clark154beea2017-10-26 07:58:48 -0400162after setPolyToPoly: kTranslate_Mask kScale_Mask kAffine_Mask kPerspective_Mask
163##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400164##
165
Cary Clark154beea2017-10-26 07:58:48 -0400166#SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400167
168##
169
170# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500171#Subtopic Property
Cary Clark4855f782018-02-06 09:41:53 -0500172#Line # values and attributes ##
173##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400174
175#Method TypeMask getType() const
Cary Clark4855f782018-02-06 09:41:53 -0500176#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500177#Line # returns transform complexity ##
Cary Clark09d80c02018-10-31 12:14:03 -0400178#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400179
Cary Clark154beea2017-10-26 07:58:48 -0400180#Example
181SkMatrix matrix;
182matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
183SkDebugf("identity flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
184matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, .5f);
185SkDebugf("set all flags hex: %0x decimal: %d\n", matrix.getType(), matrix.getType());
186#StdOut
187identity flags hex: 0 decimal: 0
188set all flags hex: f decimal: 15
189##
190##
191
192#SeeAlso TypeMask
Cary Clarkbc5697d2017-10-04 14:31:33 -0400193
194##
195
196# ------------------------------------------------------------------------------
197
198#Method bool isIdentity() const
Cary Clark4855f782018-02-06 09:41:53 -0500199#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500200#Line # returns if matrix equals the identity Matrix ##
Cary Clark09d80c02018-10-31 12:14:03 -0400201#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400202
203#Example
204SkMatrix matrix;
205matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
206SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
207matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 2);
208SkDebugf("is identity: %s\n", matrix.isIdentity() ? "true" : "false");
209#StdOut
210is identity: true
211is identity: false
212##
213##
214
215#SeeAlso reset() setIdentity getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400216
217##
218
219# ------------------------------------------------------------------------------
220
221#Method bool isScaleTranslate() const
Cary Clark4855f782018-02-06 09:41:53 -0500222#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500223#Line # returns if transform is limited to scale and translate ##
Cary Clark09d80c02018-10-31 12:14:03 -0400224#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400225
226#Example
227SkMatrix matrix;
228for (SkScalar scaleX : { 1, 2 } ) {
229 for (SkScalar translateX : { 0, 20 } ) {
230 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
231 SkDebugf("is scale-translate: %s\n", matrix.isScaleTranslate() ? "true" : "false");
232 }
233}
234#StdOut
235is scale-translate: true
236is scale-translate: true
237is scale-translate: true
238is scale-translate: true
239##
240##
241
242#SeeAlso setScale isTranslate setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400243
244##
245
246# ------------------------------------------------------------------------------
247
248#Method bool isTranslate() const
Cary Clark4855f782018-02-06 09:41:53 -0500249#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500250#Line # returns if transform is limited to translate ##
Cary Clark09d80c02018-10-31 12:14:03 -0400251#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400252
253#Example
254SkMatrix matrix;
255for (SkScalar scaleX : { 1, 2 } ) {
256 for (SkScalar translateX : { 0, 20 } ) {
257 matrix.setAll(scaleX, 0, translateX, 0, 1, 0, 0, 0, 1);
258 SkDebugf("is translate: %s\n", matrix.isTranslate() ? "true" : "false");
259 }
260}
261#StdOut
262is translate: true
263is translate: true
264is translate: false
265is translate: false
266##
267##
268
269#SeeAlso setTranslate getType
Cary Clarkbc5697d2017-10-04 14:31:33 -0400270
271##
272
273# ------------------------------------------------------------------------------
274
275#Method bool rectStaysRect() const
Cary Clark4855f782018-02-06 09:41:53 -0500276#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500277#Line # returns if mapped Rect can be represented by another Rect ##
Cary Clark09d80c02018-10-31 12:14:03 -0400278#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400279
280#Example
281SkMatrix matrix;
282for (SkScalar angle: { 0, 90, 180, 270 } ) {
283 matrix.setRotate(angle);
284 SkDebugf("rectStaysRect: %s\n", matrix.rectStaysRect() ? "true" : "false");
285}
286#StdOut
287rectStaysRect: true
288rectStaysRect: true
289rectStaysRect: true
290rectStaysRect: true
291##
292##
293
294#SeeAlso preservesAxisAlignment preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400295
296##
297
298# ------------------------------------------------------------------------------
299
300#Method bool preservesAxisAlignment() const
Cary Clark4855f782018-02-06 09:41:53 -0500301#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500302#Line # returns if mapping restricts to 90 degree multiples and mirroring ##
Cary Clark09d80c02018-10-31 12:14:03 -0400303#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400304
305#Example
306SkMatrix matrix;
307for (SkScalar angle: { 0, 90, 180, 270 } ) {
308 matrix.setRotate(angle);
309 SkDebugf("preservesAxisAlignment: %s\n", matrix.preservesAxisAlignment() ? "true" : "false");
310}
311#StdOut
312preservesAxisAlignment: true
313preservesAxisAlignment: true
314preservesAxisAlignment: true
315preservesAxisAlignment: true
316##
317##
318
319#SeeAlso rectStaysRect preservesRightAngles
Cary Clarkbc5697d2017-10-04 14:31:33 -0400320
321##
322
323# ------------------------------------------------------------------------------
324
325#Method bool hasPerspective() const
Cary Clark4855f782018-02-06 09:41:53 -0500326#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500327#Line # returns if transform includes perspective ##
Cary Clark09d80c02018-10-31 12:14:03 -0400328#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400329
330#Example
331#Image 4
332SkMatrix matrix;
333SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
334SkRect::Make(source.bounds()).toQuad(bitmapBounds);
335matrix.setPolyToPoly(bitmapBounds, perspect, 4);
336canvas->concat(matrix);
337SkString string;
338string.printf("hasPerspective %s", matrix.hasPerspective() ? "true" : "false");
339canvas->drawBitmap(source, 0, 0);
340SkPaint paint;
341paint.setAntiAlias(true);
342paint.setTextSize(48);
343canvas->drawString(string, 0, source.bounds().height() + 48, paint);
344##
345
Cary Clarkbef063a2017-10-31 15:44:45 -0400346#SeeAlso setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -0400347
348##
349
350# ------------------------------------------------------------------------------
351
352#Method bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const
Cary Clark4855f782018-02-06 09:41:53 -0500353#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500354#Line # returns if transform is limited to square scale and rotation ##
Cary Clark09d80c02018-10-31 12:14:03 -0400355#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400356
357#Example
Cary Clark154beea2017-10-26 07:58:48 -0400358#Description
359String is drawn four times through but only two are visible. Drawing the pair
360with isSimilarity false reveals the pair not visible through the matrix.
361##
362 SkPaint p;
363 p.setAntiAlias(true);
364 SkMatrix m;
365 int below = 175;
366 for (SkScalar sx : { -1, 1 } ) {
367 for (SkScalar sy : { -1, 1 } ) {
368 m.setAll(sx, 1, 128, 1, sy, 32, 0, 0, 1);
369 bool isSimilarity = m.isSimilarity();
370 SkString str;
371 str.printf("sx: %g sy: %g sim: %s", sx, sy, isSimilarity ? "true" : "false");
372 {
373 SkAutoCanvasRestore autoRestore(canvas, true);
374 canvas->concat(m);
Cary Clark682c58d2018-05-16 07:07:07 -0400375 canvas->drawString(str, 0, 0, p);
Cary Clark154beea2017-10-26 07:58:48 -0400376 }
377 if (!isSimilarity) {
378 canvas->drawString(str, 40, below, p);
379 below += 20;
380 }
381 }
382 }
Cary Clarkbc5697d2017-10-04 14:31:33 -0400383##
384
Cary Clark154beea2017-10-26 07:58:48 -0400385#SeeAlso isScaleTranslate preservesRightAngles rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400386
387##
388
389# ------------------------------------------------------------------------------
390
391#Method bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const
Cary Clark4855f782018-02-06 09:41:53 -0500392#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500393#Line # returns if mapped 90 angle remains 90 degrees ##
Cary Clark09d80c02018-10-31 12:14:03 -0400394#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400395
396#Example
Cary Clark154beea2017-10-26 07:58:48 -0400397#Height 128
398#Description
399Equal scale is both similar and preserves right angles.
400Unequal scale is not similar but preserves right angles.
401Skews are not similar and do not preserve right angles.
402##
403SkPaint p;
404p.setAntiAlias(true);
405SkMatrix m;
406int pos = 0;
407for (SkScalar sx : { 1, 2 } ) {
408 for (SkScalar kx : { 0, 1 } ) {
409 m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1);
410 bool isSimilarity = m.isSimilarity();
411 bool preservesRightAngles = m.preservesRightAngles();
412 SkString str;
413 str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "",
414 preservesRightAngles ? "right" : "");
415 SkAutoCanvasRestore autoRestore(canvas, true);
416 canvas->concat(m);
Cary Clark682c58d2018-05-16 07:07:07 -0400417 canvas->drawString(str, 0, pos, p);
Cary Clark154beea2017-10-26 07:58:48 -0400418 pos += 20;
419 }
420}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400421##
422
Cary Clark154beea2017-10-26 07:58:48 -0400423#SeeAlso isScaleTranslate isSimilarity rectStaysRect isFixedStepInX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400424
425##
426
427# ------------------------------------------------------------------------------
428
Cary Clarkd98f78c2018-04-26 08:32:37 -0400429#Subtopic MemberIndex
430#In Constant
431#Line # member indices ##
Cary Clarka90ea222018-10-16 10:30:28 -0400432#Filter kM
Cary Clarkbc5697d2017-10-04 14:31:33 -0400433#Code
Cary Clarka90ea222018-10-16 10:30:28 -0400434#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400435##
436
Cary Clark154beea2017-10-26 07:58:48 -0400437Matrix organizes its values in row order. These members correspond to
438each value in Matrix.
439
Cary Clarkbc5697d2017-10-04 14:31:33 -0400440#Const kMScaleX 0
Cary Clark682c58d2018-05-16 07:07:07 -0400441#Line # horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400442##
443#Const kMSkewX 1
Cary Clark682c58d2018-05-16 07:07:07 -0400444#Line # horizontal skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400445##
446#Const kMTransX 2
Cary Clark682c58d2018-05-16 07:07:07 -0400447#Line # horizontal translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400448##
449#Const kMSkewY 3
Cary Clark682c58d2018-05-16 07:07:07 -0400450#Line # vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400451##
452#Const kMScaleY 4
Cary Clark682c58d2018-05-16 07:07:07 -0400453#Line # vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400454##
455#Const kMTransY 5
Cary Clark682c58d2018-05-16 07:07:07 -0400456#Line # vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400457##
458#Const kMPersp0 6
Cary Clark682c58d2018-05-16 07:07:07 -0400459#Line # input x perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400460##
461#Const kMPersp1 7
Cary Clark682c58d2018-05-16 07:07:07 -0400462#Line # input y perspective factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400463##
464#Const kMPersp2 8
Cary Clark682c58d2018-05-16 07:07:07 -0400465#Line # perspective bias ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400466##
467
468#Example
Cary Clark154beea2017-10-26 07:58:48 -0400469SkPaint black;
470black.setAntiAlias(true);
471black.setTextSize(48);
472SkPaint gray = black;
473gray.setColor(0xFF9f9f9f);
474SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 };
475for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX,
476 SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY,
477 SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) {
478 SkMatrix m;
479 m.setIdentity();
480 m.set(i, offset[i]);
481 SkAutoCanvasRestore autoRestore(canvas, true);
482 canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88);
483 canvas->drawString("&", 0, 0, gray);
484 canvas->concat(m);
485 canvas->drawString("&", 0, 0, black);
486}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400487##
488
Cary Clark154beea2017-10-26 07:58:48 -0400489#SeeAlso get() set()
Cary Clarkbc5697d2017-10-04 14:31:33 -0400490
491##
492
493# ------------------------------------------------------------------------------
494
Cary Clarkd98f78c2018-04-26 08:32:37 -0400495#Subtopic AffineIndex
496#In Constant
497#Line # affine member indices ##
Cary Clarka90ea222018-10-16 10:30:28 -0400498#Filter KA
Cary Clarkbc5697d2017-10-04 14:31:33 -0400499
500#Code
Cary Clarka90ea222018-10-16 10:30:28 -0400501#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400502##
503
Cary Clark154beea2017-10-26 07:58:48 -0400504Affine arrays are in column major order to match the matrix used by
505PDF and XPS.
Cary Clarkbc5697d2017-10-04 14:31:33 -0400506
507#Const kAScaleX 0
Cary Clark682c58d2018-05-16 07:07:07 -0400508#Line # horizontal scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400509##
510#Const kASkewY 1
Cary Clark682c58d2018-05-16 07:07:07 -0400511#Line # vertical skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400512##
513#Const kASkewX 2
Cary Clark682c58d2018-05-16 07:07:07 -0400514#Line # horizontal skew factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400515##
516#Const kAScaleY 3
Cary Clark682c58d2018-05-16 07:07:07 -0400517#Line # vertical scale factor ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400518##
519#Const kATransX 4
Cary Clark682c58d2018-05-16 07:07:07 -0400520#Line # horizontal translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400521##
522#Const kATransY 5
Cary Clark682c58d2018-05-16 07:07:07 -0400523#Line # vertical translation ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400524##
525
Cary Clark154beea2017-10-26 07:58:48 -0400526#NoExample
Cary Clarkbc5697d2017-10-04 14:31:33 -0400527##
528
Cary Clark154beea2017-10-26 07:58:48 -0400529#SeeAlso SetAffineIdentity asAffine setAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -0400530
531##
532
533# ------------------------------------------------------------------------------
534
Cary Clarka560c472017-11-27 10:44:06 -0500535#Method SkScalar operator[](int index)_const
Cary Clarkbc5697d2017-10-04 14:31:33 -0400536
Cary Clark08895c42018-02-01 09:37:32 -0500537#Line # returns Matrix value ##
Cary Clark09d80c02018-10-31 12:14:03 -0400538#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400539
540#Example
541SkMatrix matrix;
542matrix.setScale(42, 24);
543SkDebugf("matrix[SkMatrix::kMScaleX] %c= 42\n", matrix[SkMatrix::kMScaleX] == 42 ? '=' : '!');
544SkDebugf("matrix[SkMatrix::kMScaleY] %c= 24\n", matrix[SkMatrix::kMScaleY] == 24 ? '=' : '!');
545#StdOut
546matrix[SkMatrix::kMScaleX] == 42
547matrix[SkMatrix::kMScaleY] == 24
548##
549##
550
551#SeeAlso get set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400552
553##
554
555# ------------------------------------------------------------------------------
556
557#Method SkScalar get(int index) const
Cary Clark4855f782018-02-06 09:41:53 -0500558#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500559#Line # returns one of nine Matrix values ##
Cary Clark09d80c02018-10-31 12:14:03 -0400560#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400561
562#Example
563SkMatrix matrix;
564matrix.setSkew(42, 24);
565SkDebugf("matrix.get(SkMatrix::kMSkewX) %c= 42\n",
566 matrix.get(SkMatrix::kMSkewX) == 42 ? '=' : '!');
567SkDebugf("matrix.get(SkMatrix::kMSkewY) %c= 24\n",
568 matrix.get(SkMatrix::kMSkewY) == 24 ? '=' : '!');
569#StdOut
570matrix.get(SkMatrix::kMSkewX) == 42
571matrix.get(SkMatrix::kMSkewY) == 24
572##
573##
574
575#SeeAlso operator[](int index) set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400576
577##
578
579# ------------------------------------------------------------------------------
580
581#Method SkScalar getScaleX() const
Cary Clark4855f782018-02-06 09:41:53 -0500582#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500583#Line # returns horizontal scale factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400584#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400585
586#Example
Cary Clark154beea2017-10-26 07:58:48 -0400587SkMatrix matrix;
588matrix.setScale(42, 24);
589SkDebugf("matrix.getScaleX() %c= 42\n", matrix.getScaleX() == 42 ? '=' : '!');
590#StdOut
591matrix.getScaleX() == 42
592##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400593##
594
Cary Clark154beea2017-10-26 07:58:48 -0400595#SeeAlso get getScaleY setScaleX setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400596
597##
598
599# ------------------------------------------------------------------------------
600
601#Method SkScalar getScaleY() const
Cary Clark4855f782018-02-06 09:41:53 -0500602#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500603#Line # returns vertical scale factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400604#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400605
606#Example
Cary Clark154beea2017-10-26 07:58:48 -0400607SkMatrix matrix;
608matrix.setScale(42, 24);
609SkDebugf("matrix.getScaleY() %c= 24\n", matrix.getScaleY() == 24 ? '=' : '!');
610#StdOut
611matrix.getScaleY() == 24
612##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400613##
614
Cary Clark154beea2017-10-26 07:58:48 -0400615#SeeAlso get getScaleX setScaleY setScale
Cary Clarkbc5697d2017-10-04 14:31:33 -0400616
617##
618
619# ------------------------------------------------------------------------------
620
621#Method SkScalar getSkewY() const
Cary Clark4855f782018-02-06 09:41:53 -0500622#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500623#Line # returns vertical skew factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400624#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400625
626#Example
Cary Clark154beea2017-10-26 07:58:48 -0400627SkMatrix matrix;
628matrix.setSkew(42, 24);
629SkDebugf("matrix.getSkewY() %c= 24\n", matrix.getSkewY() == 24 ? '=' : '!');
630#StdOut
631matrix.getSkewY() == 24
632##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400633##
634
Cary Clark154beea2017-10-26 07:58:48 -0400635#SeeAlso get getSkewX setSkewY setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400636
637##
638
639# ------------------------------------------------------------------------------
640
641#Method SkScalar getSkewX() const
Cary Clark4855f782018-02-06 09:41:53 -0500642#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500643#Line # returns horizontal skew factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400644#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400645
646#Example
Cary Clark154beea2017-10-26 07:58:48 -0400647SkMatrix matrix;
648matrix.setSkew(42, 24);
649SkDebugf("matrix.getSkewX() %c= 42\n", matrix.getSkewX() == 42 ? '=' : '!');
650#StdOut
651matrix.getSkewX() == 42
652##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400653##
654
Cary Clark154beea2017-10-26 07:58:48 -0400655#SeeAlso get getSkewY setSkewX setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -0400656
657##
658
659# ------------------------------------------------------------------------------
660
661#Method SkScalar getTranslateX() const
Cary Clark4855f782018-02-06 09:41:53 -0500662#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500663#Line # returns horizontal translation ##
Cary Clark09d80c02018-10-31 12:14:03 -0400664#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400665
666#Example
Cary Clark154beea2017-10-26 07:58:48 -0400667SkMatrix matrix;
668matrix.setTranslate(42, 24);
669SkDebugf("matrix.getTranslateX() %c= 42\n", matrix.getTranslateX() == 42 ? '=' : '!');
670#StdOut
671matrix.getTranslateX() == 42
672##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400673##
674
Cary Clark154beea2017-10-26 07:58:48 -0400675#SeeAlso get getTranslateY setTranslateX setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400676
677##
678
679# ------------------------------------------------------------------------------
680
681#Method SkScalar getTranslateY() const
Cary Clark4855f782018-02-06 09:41:53 -0500682#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500683#Line # returns vertical translation ##
Cary Clark09d80c02018-10-31 12:14:03 -0400684#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400685
686#Example
Cary Clark154beea2017-10-26 07:58:48 -0400687SkMatrix matrix;
688matrix.setTranslate(42, 24);
689SkDebugf("matrix.getTranslateY() %c= 24\n", matrix.getTranslateY() == 24 ? '=' : '!');
690#StdOut
691matrix.getTranslateY() == 24
692##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400693##
694
Cary Clark154beea2017-10-26 07:58:48 -0400695#SeeAlso get getTranslateX setTranslateY setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400696
697##
698
699# ------------------------------------------------------------------------------
700
701#Method SkScalar getPerspX() const
Cary Clark4855f782018-02-06 09:41:53 -0500702#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500703#Line # returns input x perspective factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400704#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400705
706#Example
Cary Clark154beea2017-10-26 07:58:48 -0400707 SkMatrix m;
708 m.setIdentity();
709 m.set(SkMatrix::kMPersp0, -0.004f);
710 SkAutoCanvasRestore autoRestore(canvas, true);
711 canvas->translate(22, 144);
712 SkPaint black;
713 black.setAntiAlias(true);
714 black.setTextSize(24);
715 SkPaint gray = black;
716 gray.setColor(0xFF9f9f9f);
717 SkString string;
718 string.appendScalar(m.getPerspX());
719 canvas->drawString(string, 0, -72, gray);
720 canvas->concat(m);
721 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400722##
723
Cary Clark154beea2017-10-26 07:58:48 -0400724#SeeAlso kMPersp0 getPerspY
Cary Clarkbc5697d2017-10-04 14:31:33 -0400725
726##
727
728# ------------------------------------------------------------------------------
729
730#Method SkScalar getPerspY() const
Cary Clark4855f782018-02-06 09:41:53 -0500731#In Property
Cary Clark08895c42018-02-01 09:37:32 -0500732#Line # returns input y perspective factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400733#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400734
735#Example
Cary Clark154beea2017-10-26 07:58:48 -0400736 SkMatrix m;
737 m.setIdentity();
738 m.set(SkMatrix::kMPersp1, -0.004f);
739 SkAutoCanvasRestore autoRestore(canvas, true);
740 canvas->translate(22, 144);
741 SkPaint black;
742 black.setAntiAlias(true);
743 black.setTextSize(24);
744 SkPaint gray = black;
745 gray.setColor(0xFF9f9f9f);
746 SkString string;
747 string.appendScalar(m.getPerspY());
748 canvas->drawString(string, 0, -72, gray);
749 canvas->concat(m);
750 canvas->drawString(string, 0, 0, black);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400751##
752
Cary Clark154beea2017-10-26 07:58:48 -0400753#SeeAlso kMPersp1 getPerspX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400754
755##
756
757# ------------------------------------------------------------------------------
758
Cary Clark154beea2017-10-26 07:58:48 -0400759#Method SkScalar& operator[](int index)
Cary Clarkbc5697d2017-10-04 14:31:33 -0400760
Cary Clark08895c42018-02-01 09:37:32 -0500761#Line # returns writable reference to Matrix value ##
Cary Clark09d80c02018-10-31 12:14:03 -0400762#Populate
Cary Clark154beea2017-10-26 07:58:48 -0400763
764#Example
765SkMatrix matrix;
766matrix.setIdentity();
767SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
768SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
769skewRef = 0;
770SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
771skewRef = 1;
772SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
773matrix.dirtyMatrixTypeCache();
774SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
775#StdOut
776with identity matrix: x = 24
777after skew x mod: x = 24
778after 2nd skew x mod: x = 24
779after dirty cache: x = 66
780##
781##
782
783#SeeAlso get dirtyMatrixTypeCache set
Cary Clarkbc5697d2017-10-04 14:31:33 -0400784
785##
786
787# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500788#Subtopic Set
Cary Clark682c58d2018-05-16 07:07:07 -0400789#Line # sets one or more matrix values ##
Cary Clark4855f782018-02-06 09:41:53 -0500790##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400791
792#Method void set(int index, SkScalar value)
Cary Clark4855f782018-02-06 09:41:53 -0500793#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500794#Line # sets one value ##
Cary Clark09d80c02018-10-31 12:14:03 -0400795#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400796
797#Example
Cary Clark154beea2017-10-26 07:58:48 -0400798SkMatrix matrix;
799matrix.setIdentity();
800SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
801matrix.set(SkMatrix::kMSkewX, 0);
802SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
803matrix.set(SkMatrix::kMSkewX, 1);
804SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
805#StdOut
806with identity matrix: x = 24
807after skew x mod: x = 24
808after 2nd skew x mod: x = 66
809##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400810##
811
Cary Clark154beea2017-10-26 07:58:48 -0400812#SeeAlso operator[] get
Cary Clarkbc5697d2017-10-04 14:31:33 -0400813
Cary Clark154beea2017-10-26 07:58:48 -0400814#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400815
816# ------------------------------------------------------------------------------
817
818#Method void setScaleX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500819#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500820#Line # sets horizontal scale factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400821#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400822
823#Example
Cary Clark154beea2017-10-26 07:58:48 -0400824#Height 64
825SkPaint paint;
826paint.setAntiAlias(true);
827paint.setTextSize(24);
828canvas->drawString("normal", 12, 24, paint);
829SkMatrix matrix;
830matrix.setIdentity();
831matrix.setScaleX(3);
832canvas->concat(matrix);
833canvas->drawString("x scale", 0, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400834##
835
Cary Clark154beea2017-10-26 07:58:48 -0400836#SeeAlso set setScale setScaleY
Cary Clarkbc5697d2017-10-04 14:31:33 -0400837
Cary Clark154beea2017-10-26 07:58:48 -0400838#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400839
840# ------------------------------------------------------------------------------
841
842#Method void setScaleY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500843#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500844#Line # sets vertical scale factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400845#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400846
847#Example
Cary Clark154beea2017-10-26 07:58:48 -0400848#Height 192
849SkPaint paint;
850paint.setAntiAlias(true);
851paint.setTextSize(24);
852canvas->drawString("normal", 12, 24, paint);
853SkMatrix matrix;
854matrix.setIdentity();
855matrix.setScaleY(3);
856canvas->concat(matrix);
857canvas->drawString("y scale", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400858##
859
Cary Clark154beea2017-10-26 07:58:48 -0400860#SeeAlso set setScale setScaleX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400861
Cary Clark154beea2017-10-26 07:58:48 -0400862#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400863
864# ------------------------------------------------------------------------------
865
866#Method void setSkewY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500867#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500868#Line # sets vertical skew factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400869#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400870
871#Example
Cary Clark154beea2017-10-26 07:58:48 -0400872#Height 96
873SkPaint paint;
874paint.setAntiAlias(true);
875paint.setTextSize(24);
876canvas->drawString("normal", 12, 24, paint);
877SkMatrix matrix;
878matrix.setIdentity();
879matrix.setSkewY(.3f);
880canvas->concat(matrix);
881canvas->drawString("y skew", 12, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400882##
883
Cary Clark154beea2017-10-26 07:58:48 -0400884#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400885
Cary Clark154beea2017-10-26 07:58:48 -0400886#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400887
888# ------------------------------------------------------------------------------
889
890#Method void setSkewX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500891#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500892#Line # sets horizontal skew factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400893#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400894
895#Example
Cary Clark154beea2017-10-26 07:58:48 -0400896#Height 64
897SkPaint paint;
898paint.setAntiAlias(true);
899paint.setTextSize(24);
900canvas->drawString("normal", 12, 24, paint);
901SkMatrix matrix;
902matrix.setIdentity();
903matrix.setSkewX(-.7f);
904canvas->concat(matrix);
905canvas->drawString("x skew", 36, 48, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400906##
907
Cary Clark154beea2017-10-26 07:58:48 -0400908#SeeAlso set setSkew setSkewX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400909
Cary Clark154beea2017-10-26 07:58:48 -0400910#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400911
912# ------------------------------------------------------------------------------
913
914#Method void setTranslateX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500915#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500916#Line # sets horizontal translation ##
Cary Clark09d80c02018-10-31 12:14:03 -0400917#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400918
919#Example
Cary Clark154beea2017-10-26 07:58:48 -0400920#Height 48
921SkPaint paint;
922paint.setAntiAlias(true);
923paint.setTextSize(24);
924canvas->drawString("normal", 8, 24, paint);
925SkMatrix matrix;
926matrix.setIdentity();
927matrix.setTranslateX(96);
928canvas->concat(matrix);
929canvas->drawString("x translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400930##
931
Cary Clark154beea2017-10-26 07:58:48 -0400932#SeeAlso set setTranslate setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -0400933
Cary Clark154beea2017-10-26 07:58:48 -0400934#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400935
936# ------------------------------------------------------------------------------
937
938#Method void setTranslateY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500939#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500940#Line # sets vertical translation ##
Cary Clark09d80c02018-10-31 12:14:03 -0400941#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400942
943#Example
Cary Clark154beea2017-10-26 07:58:48 -0400944#Height 64
945SkPaint paint;
946paint.setAntiAlias(true);
947paint.setTextSize(24);
948canvas->drawString("normal", 8, 24, paint);
949SkMatrix matrix;
950matrix.setIdentity();
951matrix.setTranslateY(24);
952canvas->concat(matrix);
953canvas->drawString("y translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -0400954##
955
Cary Clark154beea2017-10-26 07:58:48 -0400956#SeeAlso set setTranslate setTranslateX
Cary Clarkbc5697d2017-10-04 14:31:33 -0400957
Cary Clark154beea2017-10-26 07:58:48 -0400958#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400959
960# ------------------------------------------------------------------------------
961
962#Method void setPerspX(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500963#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500964#Line # sets input x perspective factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400965#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400966
967#Example
Cary Clark154beea2017-10-26 07:58:48 -0400968#Image 4
969for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
970 SkMatrix matrix;
971 matrix.setIdentity();
972 matrix.setPerspX(perspX);
973 canvas->save();
974 canvas->concat(matrix);
975 canvas->drawBitmap(source, 0, 0);
976 canvas->restore();
977 canvas->translate(64, 64);
978}
Cary Clarkbc5697d2017-10-04 14:31:33 -0400979##
980
Cary Clarkbef063a2017-10-31 15:44:45 -0400981#SeeAlso getPerspX set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -0400982
Cary Clark154beea2017-10-26 07:58:48 -0400983#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -0400984
985# ------------------------------------------------------------------------------
986
987#Method void setPerspY(SkScalar v)
Cary Clark4855f782018-02-06 09:41:53 -0500988#In Set
Cary Clark08895c42018-02-01 09:37:32 -0500989#Line # sets input y perspective factor ##
Cary Clark09d80c02018-10-31 12:14:03 -0400990#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -0400991
992#Example
Cary Clark154beea2017-10-26 07:58:48 -0400993#Image 4
994for (SkScalar perspX : { -.003f, 0.f, .003f, .012f } ) {
995 SkMatrix matrix;
996 matrix.setIdentity();
997 matrix.setPerspY(perspX);
998 canvas->save();
999 canvas->concat(matrix);
1000 canvas->drawBitmap(source, 0, 0);
1001 canvas->restore();
1002 canvas->translate(64, 64);
1003}
Cary Clarkbc5697d2017-10-04 14:31:33 -04001004##
1005
Cary Clarkbef063a2017-10-31 15:44:45 -04001006#SeeAlso getPerspY set setAll set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001007
Cary Clark154beea2017-10-26 07:58:48 -04001008#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001009
1010# ------------------------------------------------------------------------------
1011
1012#Method void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
1013 SkScalar skewY, SkScalar scaleY, SkScalar transY,
1014 SkScalar persp0, SkScalar persp1, SkScalar persp2)
Cary Clark4855f782018-02-06 09:41:53 -05001015#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001016#Line # sets all values from parameters ##
Cary Clark09d80c02018-10-31 12:14:03 -04001017#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001018
1019#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001020#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001021 SkPaint p;
1022 p.setAntiAlias(true);
1023 p.setTextSize(64);
1024 SkMatrix m;
1025 for (SkScalar sx : { -1, 1 } ) {
1026 for (SkScalar sy : { -1, 1 } ) {
1027 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001028 m.setAll(sx, 1, 128, 0, sy, 64, 0, 0, 1);
Cary Clark154beea2017-10-26 07:58:48 -04001029 canvas->concat(m);
1030 canvas->drawString("K", 0, 0, p);
1031 }
1032 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001033##
1034
Cary Clarkbef063a2017-10-31 15:44:45 -04001035#SeeAlso set9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001036
Cary Clark154beea2017-10-26 07:58:48 -04001037#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001038
1039# ------------------------------------------------------------------------------
1040
1041#Method void get9(SkScalar buffer[9]) const
Cary Clark4855f782018-02-06 09:41:53 -05001042#In Property
Cary Clark08895c42018-02-01 09:37:32 -05001043#Line # returns all nine Matrix values ##
Cary Clark09d80c02018-10-31 12:14:03 -04001044#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001045
1046#Example
Cary Clark154beea2017-10-26 07:58:48 -04001047SkMatrix matrix = SkMatrix::MakeRectToRect({0, 0, 1, 1}, {3, 4, 7, 9},
1048 SkMatrix::kFill_ScaleToFit);
1049SkScalar b[9];
1050matrix.get9(b);
Cary Clark682c58d2018-05-16 07:07:07 -04001051SkDebugf("{%g, %g, %g},\n{%g, %g, %g},\n{%g, %g, %g}\n", b[0], b[1], b[2],
Cary Clark154beea2017-10-26 07:58:48 -04001052 b[3], b[4], b[5], b[6], b[7], b[8]);
1053#StdOut
1054{4, 0, 3},
1055{0, 5, 4},
1056{0, 0, 1}
Cary Clark682c58d2018-05-16 07:07:07 -04001057##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001058##
1059
Cary Clark154beea2017-10-26 07:58:48 -04001060#SeeAlso set9
Cary Clarkbc5697d2017-10-04 14:31:33 -04001061
Cary Clark154beea2017-10-26 07:58:48 -04001062#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001063
1064# ------------------------------------------------------------------------------
1065
1066#Method void set9(const SkScalar buffer[9])
Cary Clark4855f782018-02-06 09:41:53 -05001067#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001068#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -05001069#Line # sets all values from Scalar array ##
Cary Clark09d80c02018-10-31 12:14:03 -04001070#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001071
1072#Example
Cary Clark154beea2017-10-26 07:58:48 -04001073#Image 4
1074SkMatrix m;
1075SkScalar buffer[9] = {4, 0, 3, 0, 5, 4, 0, 0, 1};
1076m.set9(buffer);
1077canvas->concat(m);
1078canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001079##
1080
Cary Clarkbef063a2017-10-31 15:44:45 -04001081#SeeAlso setAll get9 MakeAll
Cary Clarkbc5697d2017-10-04 14:31:33 -04001082
Cary Clark154beea2017-10-26 07:58:48 -04001083#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001084
1085# ------------------------------------------------------------------------------
1086
1087#Method void reset()
Cary Clark61313f32018-10-08 14:57:48 -04001088#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001089#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001090#Line # sets Matrix to identity ##
Cary Clark09d80c02018-10-31 12:14:03 -04001091#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001092
1093#Example
Cary Clark154beea2017-10-26 07:58:48 -04001094SkMatrix m;
1095m.reset();
1096SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1097#StdOut
1098m.isIdentity(): true
1099##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001100##
1101
Cary Clark154beea2017-10-26 07:58:48 -04001102#SeeAlso isIdentity setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04001103
Cary Clark154beea2017-10-26 07:58:48 -04001104#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001105
1106# ------------------------------------------------------------------------------
1107
1108#Method void setIdentity()
Cary Clark61313f32018-10-08 14:57:48 -04001109#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001110#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001111#Line # sets Matrix to identity ##
Cary Clark09d80c02018-10-31 12:14:03 -04001112#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001113
1114#Example
Cary Clark154beea2017-10-26 07:58:48 -04001115SkMatrix m;
1116m.setIdentity();
1117SkDebugf("m.isIdentity(): %s\n", m.isIdentity() ? "true" : "false");
1118#StdOut
1119m.isIdentity(): true
1120##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001121##
1122
Cary Clark154beea2017-10-26 07:58:48 -04001123#SeeAlso isIdentity reset
Cary Clarkbc5697d2017-10-04 14:31:33 -04001124
Cary Clark154beea2017-10-26 07:58:48 -04001125#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001126
1127# ------------------------------------------------------------------------------
1128
1129#Method void setTranslate(SkScalar dx, SkScalar dy)
Cary Clark61313f32018-10-08 14:57:48 -04001130#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001131#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001132#Line # sets to translate in x and y ##
Cary Clark09d80c02018-10-31 12:14:03 -04001133#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001134
1135#Example
Cary Clark154beea2017-10-26 07:58:48 -04001136#Height 64
1137SkPaint paint;
1138paint.setAntiAlias(true);
1139paint.setTextSize(24);
1140canvas->drawString("normal", 8, 24, paint);
1141SkMatrix matrix;
1142matrix.setTranslate(96, 24);
1143canvas->concat(matrix);
1144canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001145##
1146
Cary Clark154beea2017-10-26 07:58:48 -04001147#SeeAlso setTranslateX setTranslateY
Cary Clarkbc5697d2017-10-04 14:31:33 -04001148
Cary Clark154beea2017-10-26 07:58:48 -04001149#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001150
1151# ------------------------------------------------------------------------------
1152
1153#Method void setTranslate(const SkVector& v)
Cary Clark09d80c02018-10-31 12:14:03 -04001154#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001155
1156#Example
Cary Clark154beea2017-10-26 07:58:48 -04001157#Height 64
1158SkPaint paint;
1159paint.setAntiAlias(true);
1160paint.setTextSize(24);
1161canvas->drawString("normal", 8, 24, paint);
1162SkMatrix matrix;
1163matrix.setTranslate({96, 24});
1164canvas->concat(matrix);
1165canvas->drawString("translate", 8, 24, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001166##
1167
Cary Clark154beea2017-10-26 07:58:48 -04001168#SeeAlso setTranslateX setTranslateY MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001169
Cary Clark154beea2017-10-26 07:58:48 -04001170#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001171
1172# ------------------------------------------------------------------------------
1173
1174#Method void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Cary Clark61313f32018-10-08 14:57:48 -04001175#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001176#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001177#Line # sets to scale about a point ##
Cary Clark09d80c02018-10-31 12:14:03 -04001178#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001179
1180#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001181#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001182 SkPaint p;
1183 p.setAntiAlias(true);
1184 p.setTextSize(64);
1185 SkMatrix m;
1186 for (SkScalar sx : { -1, 1 } ) {
1187 for (SkScalar sy : { -1, 1 } ) {
1188 SkAutoCanvasRestore autoRestore(canvas, true);
Cary Clark2ade9972017-11-02 17:49:34 -04001189 m.setScale(sx, sy, 128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001190 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001191 canvas->drawString("%", 128, 64, p);
Cary Clark154beea2017-10-26 07:58:48 -04001192 }
1193 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001194##
1195
Cary Clark154beea2017-10-26 07:58:48 -04001196#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001197
Cary Clark154beea2017-10-26 07:58:48 -04001198#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001199
1200# ------------------------------------------------------------------------------
1201
1202#Method void setScale(SkScalar sx, SkScalar sy)
Cary Clark09d80c02018-10-31 12:14:03 -04001203#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001204
1205#Example
Cary Clark2ade9972017-11-02 17:49:34 -04001206#Height 128
Cary Clark154beea2017-10-26 07:58:48 -04001207 SkPaint p;
1208 p.setAntiAlias(true);
1209 p.setTextSize(64);
1210 SkMatrix m;
1211 for (SkScalar sx : { -1, 1 } ) {
1212 for (SkScalar sy : { -1, 1 } ) {
1213 SkAutoCanvasRestore autoRestore(canvas, true);
1214 m.setScale(sx, sy);
Cary Clark2ade9972017-11-02 17:49:34 -04001215 m.postTranslate(128, 64);
Cary Clark154beea2017-10-26 07:58:48 -04001216 canvas->concat(m);
Cary Clark2ade9972017-11-02 17:49:34 -04001217 canvas->drawString("@", 0, 0, p);
Cary Clark154beea2017-10-26 07:58:48 -04001218 }
1219 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001220##
1221
Cary Clark154beea2017-10-26 07:58:48 -04001222#SeeAlso setScaleX setScaleY MakeScale preScale postScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001223
Cary Clark154beea2017-10-26 07:58:48 -04001224#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001225
1226# ------------------------------------------------------------------------------
1227
1228#Method void setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Cary Clark61313f32018-10-08 14:57:48 -04001229#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001230#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001231#Line # sets to rotate about a point ##
Cary Clark09d80c02018-10-31 12:14:03 -04001232#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001233
1234#Example
Cary Clark154beea2017-10-26 07:58:48 -04001235#Height 128
1236 SkPaint paint;
1237 paint.setColor(SK_ColorGRAY);
1238 paint.setAntiAlias(true);
1239 SkRect rect = {20, 20, 100, 100};
1240 canvas->drawRect(rect, paint);
1241 paint.setColor(SK_ColorRED);
1242 SkMatrix matrix;
1243 matrix.setRotate(25, rect.centerX(), rect.centerY());
1244 canvas->concat(matrix);
1245 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001246##
1247
Cary Clark154beea2017-10-26 07:58:48 -04001248#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001249
Cary Clark154beea2017-10-26 07:58:48 -04001250#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001251
1252# ------------------------------------------------------------------------------
1253
1254#Method void setRotate(SkScalar degrees)
Cary Clark09d80c02018-10-31 12:14:03 -04001255#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001256
1257#Example
Cary Clark154beea2017-10-26 07:58:48 -04001258#Height 128
1259 SkPaint paint;
1260 paint.setColor(SK_ColorGRAY);
1261 paint.setAntiAlias(true);
1262 SkRect rect = {20, 20, 100, 100};
1263 canvas->drawRect(rect, paint);
1264 paint.setColor(SK_ColorRED);
1265 SkMatrix matrix;
1266 matrix.setRotate(25);
1267 canvas->translate(rect.centerX(), rect.centerY());
1268 canvas->concat(matrix);
1269 canvas->translate(-rect.centerX(), -rect.centerY());
1270 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001271##
1272
Cary Clark154beea2017-10-26 07:58:48 -04001273#SeeAlso setSinCos preRotate postRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001274
Cary Clark154beea2017-10-26 07:58:48 -04001275#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001276
1277# ------------------------------------------------------------------------------
1278
1279#Method void setSinCos(SkScalar sinValue, SkScalar cosValue,
1280 SkScalar px, SkScalar py)
Cary Clark61313f32018-10-08 14:57:48 -04001281#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001282#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001283#Line # sets to rotate and scale about a point ##
Cary Clark09d80c02018-10-31 12:14:03 -04001284#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001285
1286#Example
Cary Clark154beea2017-10-26 07:58:48 -04001287#Height 128
1288 SkPaint paint;
1289 paint.setColor(SK_ColorGRAY);
1290 paint.setAntiAlias(true);
1291 SkRect rect = {20, 20, 100, 100};
1292 canvas->drawRect(rect, paint);
1293 paint.setColor(SK_ColorRED);
1294 SkMatrix matrix;
1295 matrix.setSinCos(.25f, .85f, rect.centerX(), rect.centerY());
1296 canvas->concat(matrix);
1297 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001298##
1299
Cary Clark154beea2017-10-26 07:58:48 -04001300#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001301
Cary Clark154beea2017-10-26 07:58:48 -04001302#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001303
1304# ------------------------------------------------------------------------------
1305
1306#Method void setSinCos(SkScalar sinValue, SkScalar cosValue)
Cary Clark09d80c02018-10-31 12:14:03 -04001307#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001308
1309#Example
Cary Clark154beea2017-10-26 07:58:48 -04001310#Description
1311Canvas needs offset after applying Matrix to pivot about Rect center.
1312##
1313#Height 128
1314 SkPaint paint;
1315 paint.setColor(SK_ColorGRAY);
1316 paint.setAntiAlias(true);
1317 SkRect rect = {20, 20, 100, 100};
1318 canvas->drawRect(rect, paint);
1319 paint.setColor(SK_ColorRED);
1320 SkMatrix matrix;
1321 matrix.setSinCos(.25f, .85f);
1322 matrix.postTranslate(rect.centerX(), rect.centerY());
1323 canvas->concat(matrix);
1324 canvas->translate(-rect.centerX(), -rect.centerY());
1325 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001326##
1327
Cary Clark154beea2017-10-26 07:58:48 -04001328#SeeAlso setRotate setScale setRSXform
Cary Clarkbc5697d2017-10-04 14:31:33 -04001329
Cary Clark154beea2017-10-26 07:58:48 -04001330#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001331
1332# ------------------------------------------------------------------------------
1333
1334#Method SkMatrix& setRSXform(const SkRSXform& rsxForm)
Cary Clark61313f32018-10-08 14:57:48 -04001335#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001336#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001337#Line # sets to rotate, scale, and translate ##
Cary Clark09d80c02018-10-31 12:14:03 -04001338#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001339
1340#Example
Cary Clark154beea2017-10-26 07:58:48 -04001341#Description
1342Canvas needs offset after applying Matrix to pivot about Rect center.
1343##
1344#Height 128
1345 SkPaint paint;
1346 paint.setColor(SK_ColorGRAY);
1347 paint.setAntiAlias(true);
1348 SkRect rect = {20, 20, 100, 100};
1349 canvas->drawRect(rect, paint);
1350 paint.setColor(SK_ColorRED);
1351 SkMatrix matrix;
1352 matrix.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY()));
1353 canvas->concat(matrix);
1354 canvas->translate(-rect.centerX(), -rect.centerY());
1355 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001356##
1357
Cary Clark154beea2017-10-26 07:58:48 -04001358#SeeAlso setSinCos setScale setTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001359
Cary Clark154beea2017-10-26 07:58:48 -04001360#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001361
1362# ------------------------------------------------------------------------------
1363
1364#Method void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Cary Clark61313f32018-10-08 14:57:48 -04001365#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001366#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001367#Line # sets to skew about a point ##
Cary Clark09d80c02018-10-31 12:14:03 -04001368#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001369
1370#Example
Cary Clark154beea2017-10-26 07:58:48 -04001371 SkPaint p;
1372 p.setAntiAlias(true);
1373 p.setTextSize(48);
1374 SkMatrix m;
1375 for (SkScalar sx : { -1, 0, 1 } ) {
1376 for (SkScalar sy : { -1, 0, 1 } ) {
1377 SkAutoCanvasRestore autoRestore(canvas, true);
1378 m.setSkew(sx, sy, 96 + 64 * sx, 128 + 48 * sy);
1379 canvas->concat(m);
1380 canvas->drawString("K", 96 + 64 * sx, 128 + 48 * sy, p);
1381 }
1382 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001383##
1384
Cary Clark154beea2017-10-26 07:58:48 -04001385#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001386
Cary Clark154beea2017-10-26 07:58:48 -04001387#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001388
1389# ------------------------------------------------------------------------------
1390
1391#Method void setSkew(SkScalar kx, SkScalar ky)
Cary Clark09d80c02018-10-31 12:14:03 -04001392#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001393
1394#Example
Cary Clark154beea2017-10-26 07:58:48 -04001395 SkPaint p;
1396 p.setAntiAlias(true);
1397 p.setTextSize(48);
1398 SkMatrix m;
1399 for (SkScalar sx : { -1, 0, 1 } ) {
1400 for (SkScalar sy : { -1, 0, 1 } ) {
1401 SkAutoCanvasRestore autoRestore(canvas, true);
1402 m.setSkew(sx, sy);
1403 m.postTranslate(96 + 64 * sx, 128 + 48 * sy);
1404 canvas->concat(m);
1405 canvas->drawString("K", 0, 0, p);
1406 }
1407 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001408##
1409
Cary Clark154beea2017-10-26 07:58:48 -04001410#SeeAlso setSkewX setSkewY preSkew postSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001411
Cary Clark154beea2017-10-26 07:58:48 -04001412#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001413
1414# ------------------------------------------------------------------------------
1415
1416#Method void setConcat(const SkMatrix& a, const SkMatrix& b)
Cary Clark61313f32018-10-08 14:57:48 -04001417#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05001418#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001419#Line # sets to Matrix parameter multiplied by Matrix parameter ##
Cary Clark09d80c02018-10-31 12:14:03 -04001420#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001421
1422#Example
Cary Clark154beea2017-10-26 07:58:48 -04001423#Image 3
1424#Description
1425setPolyToPoly creates perspective matrices, one the inverse of the other.
1426Multiplying the matrix by its inverse turns into an identity matrix.
1427##
1428SkMatrix matrix, matrix2;
1429SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1430SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1431matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1432matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
1433matrix.setConcat(matrix, matrix2);
1434canvas->concat(matrix);
1435canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001436##
1437
Cary Clark154beea2017-10-26 07:58:48 -04001438#SeeAlso Concat preConcat postConcat SkCanvas::concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04001439
Cary Clark154beea2017-10-26 07:58:48 -04001440#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001441
1442# ------------------------------------------------------------------------------
1443
1444#Method void preTranslate(SkScalar dx, SkScalar dy)
Cary Clark4855f782018-02-06 09:41:53 -05001445#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001446#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001447#Line # pre-multiplies Matrix by translation ##
Cary Clark09d80c02018-10-31 12:14:03 -04001448#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001449
1450#Example
Cary Clark154beea2017-10-26 07:58:48 -04001451#Height 160
1452 SkPaint paint;
1453 paint.setAntiAlias(true);
1454 SkRect rect = {20, 20, 100, 100};
1455 for (int i = 0; i < 2; ++i ) {
1456 SkMatrix matrix;
1457 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
Cary Clark682c58d2018-05-16 07:07:07 -04001458 {
Cary Clark154beea2017-10-26 07:58:48 -04001459 SkAutoCanvasRestore acr(canvas, true);
1460 canvas->concat(matrix);
1461 paint.setColor(SK_ColorGRAY);
1462 canvas->drawRect(rect, paint);
1463 }
1464 paint.setColor(SK_ColorRED);
1465 for (int j = 0; j < 2; ++j ) {
1466 SkAutoCanvasRestore acr(canvas, true);
1467 matrix.preTranslate(40, 40);
1468 canvas->concat(matrix);
1469 canvas->drawCircle(0, 0, 3, paint);
1470 }
1471 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001472##
1473
Cary Clark154beea2017-10-26 07:58:48 -04001474#SeeAlso postTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001475
Cary Clark154beea2017-10-26 07:58:48 -04001476#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001477
1478# ------------------------------------------------------------------------------
1479
1480#Method void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001481#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001482#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001483#Line # pre-multiplies Matrix by scale ##
Cary Clark09d80c02018-10-31 12:14:03 -04001484#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001485
1486#Example
Cary Clark154beea2017-10-26 07:58:48 -04001487#Image 3
1488SkMatrix matrix;
1489SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1490SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1491matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1492matrix.preScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
1493canvas->concat(matrix);
1494canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001495##
1496
Cary Clark154beea2017-10-26 07:58:48 -04001497#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001498
Cary Clark154beea2017-10-26 07:58:48 -04001499#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001500
1501# ------------------------------------------------------------------------------
1502
1503#Method void preScale(SkScalar sx, SkScalar sy)
Cary Clark4855f782018-02-06 09:41:53 -05001504#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001505#In Operators
Cary Clark09d80c02018-10-31 12:14:03 -04001506#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001507
1508#Example
Cary Clark154beea2017-10-26 07:58:48 -04001509#Image 3
1510SkMatrix matrix;
1511SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1512SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1513matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1514matrix.preScale(.75f, 1.5f);
1515canvas->concat(matrix);
1516canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001517##
1518
Cary Clark154beea2017-10-26 07:58:48 -04001519#SeeAlso postScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001520
Cary Clark154beea2017-10-26 07:58:48 -04001521#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001522
1523# ------------------------------------------------------------------------------
1524
1525#Method void preRotate(SkScalar degrees, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001526#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001527#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001528#Line # pre-multiplies Matrix by rotation ##
Cary Clark09d80c02018-10-31 12:14:03 -04001529#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001530
1531#Example
Cary Clark154beea2017-10-26 07:58:48 -04001532#Image 3
1533SkMatrix matrix;
1534SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1535SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1536matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1537matrix.preRotate(45, source.width() / 2, source.height() / 2);
1538canvas->concat(matrix);
1539canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001540##
1541
Cary Clark154beea2017-10-26 07:58:48 -04001542#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001543
Cary Clark154beea2017-10-26 07:58:48 -04001544#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001545
1546# ------------------------------------------------------------------------------
1547
1548#Method void preRotate(SkScalar degrees)
Cary Clark09d80c02018-10-31 12:14:03 -04001549#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001550
1551#Example
Cary Clark154beea2017-10-26 07:58:48 -04001552#Image 3
1553SkMatrix matrix;
1554SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1555SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1556matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1557matrix.preRotate(45);
1558canvas->concat(matrix);
1559canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001560##
1561
Cary Clark154beea2017-10-26 07:58:48 -04001562#SeeAlso postRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001563
Cary Clark154beea2017-10-26 07:58:48 -04001564#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001565
1566# ------------------------------------------------------------------------------
1567
1568#Method void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001569#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001570#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001571#Line # pre-multiplies Matrix by skew ##
Cary Clark09d80c02018-10-31 12:14:03 -04001572#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001573
1574#Example
Cary Clark154beea2017-10-26 07:58:48 -04001575#Image 3
1576SkMatrix matrix;
1577SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1578SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1579matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1580matrix.preSkew(.5f, 0, source.width() / 2, source.height() / 2);
1581canvas->concat(matrix);
1582canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001583##
1584
Cary Clark154beea2017-10-26 07:58:48 -04001585#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001586
Cary Clark154beea2017-10-26 07:58:48 -04001587#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001588
1589# ------------------------------------------------------------------------------
1590
1591#Method void preSkew(SkScalar kx, SkScalar ky)
Cary Clark09d80c02018-10-31 12:14:03 -04001592#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001593
1594#Example
Cary Clark154beea2017-10-26 07:58:48 -04001595#Image 3
1596SkMatrix matrix;
1597SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1598SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1599matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1600matrix.preSkew(.5f, 0);
1601canvas->concat(matrix);
1602canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001603##
1604
Cary Clark154beea2017-10-26 07:58:48 -04001605#SeeAlso postSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001606
Cary Clark154beea2017-10-26 07:58:48 -04001607#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001608
1609# ------------------------------------------------------------------------------
1610
1611#Method void preConcat(const SkMatrix& other)
Cary Clark4855f782018-02-06 09:41:53 -05001612#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001613#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001614#Line # pre-multiplies Matrix by Matrix parameter ##
Cary Clark09d80c02018-10-31 12:14:03 -04001615#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001616
1617#Example
Cary Clark154beea2017-10-26 07:58:48 -04001618#Image 3
1619#Description
1620setPolyToPoly creates perspective matrices, one the inverse of the other.
1621Multiplying the matrix by its inverse turns into an identity matrix.
1622##
1623SkMatrix matrix, matrix2;
1624SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1625SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1626matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1627matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
1628matrix.preConcat(matrix2);
1629canvas->concat(matrix);
1630canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001631##
1632
Cary Clark154beea2017-10-26 07:58:48 -04001633#SeeAlso postConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04001634
Cary Clark154beea2017-10-26 07:58:48 -04001635#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001636
1637# ------------------------------------------------------------------------------
1638
1639#Method void postTranslate(SkScalar dx, SkScalar dy)
Cary Clark4855f782018-02-06 09:41:53 -05001640#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001641#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001642#Line # post-multiplies Matrix by translation ##
Cary Clark09d80c02018-10-31 12:14:03 -04001643#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001644
1645#Example
Cary Clark154beea2017-10-26 07:58:48 -04001646#Height 160
1647#Description
1648Compare with preTranslate example.
1649##
1650 SkPaint paint;
1651 paint.setAntiAlias(true);
1652 SkRect rect = {20, 20, 100, 100};
1653 for (int i = 0; i < 2; ++i ) {
1654 SkMatrix matrix;
1655 i == 0 ? matrix.reset(): matrix.setRotate(25, rect.centerX(), 320);
Cary Clark682c58d2018-05-16 07:07:07 -04001656 {
Cary Clark154beea2017-10-26 07:58:48 -04001657 SkAutoCanvasRestore acr(canvas, true);
1658 canvas->concat(matrix);
1659 paint.setColor(SK_ColorGRAY);
1660 canvas->drawRect(rect, paint);
1661 }
1662 paint.setColor(SK_ColorRED);
1663 for (int j = 0; j < 2; ++j ) {
1664 SkAutoCanvasRestore acr(canvas, true);
1665 matrix.postTranslate(40, 40);
1666 canvas->concat(matrix);
1667 canvas->drawCircle(0, 0, 3, paint);
1668 }
1669 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001670##
1671
Cary Clark682c58d2018-05-16 07:07:07 -04001672#SeeAlso preTranslate setTranslate MakeTrans
Cary Clarkbc5697d2017-10-04 14:31:33 -04001673
Cary Clark154beea2017-10-26 07:58:48 -04001674#Method ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001675
1676# ------------------------------------------------------------------------------
1677
1678#Method void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001679#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001680#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001681#Line # post-multiplies Matrix by scale ##
Cary Clark09d80c02018-10-31 12:14:03 -04001682#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001683
1684#Example
Cary Clark154beea2017-10-26 07:58:48 -04001685#Image 3
1686SkMatrix matrix;
1687SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1688SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1689matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1690matrix.postScale(.75f, 1.5f, source.width() / 2, source.height() / 2);
1691canvas->concat(matrix);
1692canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001693##
1694
Cary Clark154beea2017-10-26 07:58:48 -04001695#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001696
1697##
1698
1699# ------------------------------------------------------------------------------
1700
1701#Method void postScale(SkScalar sx, SkScalar sy)
Cary Clark09d80c02018-10-31 12:14:03 -04001702#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001703
1704#Example
Cary Clark154beea2017-10-26 07:58:48 -04001705#Image 3
1706SkMatrix matrix;
1707SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1708SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1709matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1710matrix.postScale(.75f, 1.5f);
1711canvas->concat(matrix);
1712canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001713##
1714
Cary Clark154beea2017-10-26 07:58:48 -04001715#SeeAlso preScale setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001716
1717##
1718
1719# ------------------------------------------------------------------------------
1720
1721#Method bool postIDiv(int divx, int divy)
Cary Clark4855f782018-02-06 09:41:53 -05001722#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001723#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001724#Line # post-multiplies Matrix by inverse scale ##
Cary Clark2be81cf2018-09-13 12:04:30 -04001725Sets Matrix to Matrix constructed from scaling by #Formula # (1/divx, 1/divy) ##,
Cary Clark154beea2017-10-26 07:58:48 -04001726about pivot point (px, py), multiplied by Matrix.
1727
1728Returns false if either divx or divy is zero.
1729
1730Given:
1731
1732#Code
1733#Literal
1734 | J K L | | sx 0 0 |
1735Matrix = | M N O |, I(divx, divy) = | 0 sy 0 |
1736 | P Q R | | 0 0 1 |
Cary Clarkbc5697d2017-10-04 14:31:33 -04001737##
1738
Cary Clark682c58d2018-05-16 07:07:07 -04001739where
Cary Clarkbc5697d2017-10-04 14:31:33 -04001740
Cary Clark154beea2017-10-26 07:58:48 -04001741#Code
1742#Literal
1743sx = 1 / divx
1744sy = 1 / divy
1745##
1746
1747sets Matrix to:
1748
1749#Code
1750#Literal
1751 | sx 0 0 | | J K L | | sx*J sx*K sx*L |
1752I(divx, divy) * Matrix = | 0 sy 0 | | M N O | = | sy*M sy*N sy*O |
1753 | 0 0 1 | | P Q R | | P Q R |
1754##
1755
1756#Param divx integer divisor for inverse scale in x ##
1757#Param divy integer divisor for inverse scale in y ##
1758
1759#Return true on successful scale ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001760
1761#Example
Cary Clark154beea2017-10-26 07:58:48 -04001762#Image 3
Cary Clark681287e2018-03-16 11:34:15 -04001763SkMatrix matrix;
Cary Clark154beea2017-10-26 07:58:48 -04001764SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1765SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1766matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1767matrix.postIDiv(1, 2);
1768canvas->concat(matrix);
1769canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001770##
1771
Cary Clark154beea2017-10-26 07:58:48 -04001772#SeeAlso postScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04001773
1774##
1775
1776# ------------------------------------------------------------------------------
1777
1778#Method void postRotate(SkScalar degrees, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001779#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001780#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001781#Line # post-multiplies Matrix by rotation ##
Cary Clark09d80c02018-10-31 12:14:03 -04001782#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001783
1784#Example
Cary Clark154beea2017-10-26 07:58:48 -04001785#Image 3
1786SkMatrix matrix;
1787SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1788SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1789matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1790matrix.postRotate(45, source.width() / 2, source.height() / 2);
1791canvas->concat(matrix);
1792canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001793##
1794
Cary Clark154beea2017-10-26 07:58:48 -04001795#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001796
1797##
1798
1799# ------------------------------------------------------------------------------
1800
1801#Method void postRotate(SkScalar degrees)
Cary Clark09d80c02018-10-31 12:14:03 -04001802#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001803
1804#Example
Cary Clark154beea2017-10-26 07:58:48 -04001805#Image 3
1806SkMatrix matrix;
1807SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1808SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1809matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1810matrix.postRotate(45);
1811canvas->concat(matrix);
1812canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001813##
1814
Cary Clark154beea2017-10-26 07:58:48 -04001815#SeeAlso preRotate setRotate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001816
1817##
1818
1819# ------------------------------------------------------------------------------
1820
1821#Method void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Cary Clark4855f782018-02-06 09:41:53 -05001822#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001823#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001824#Line # post-multiplies Matrix by skew ##
Cary Clark09d80c02018-10-31 12:14:03 -04001825#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001826
1827#Example
Cary Clark154beea2017-10-26 07:58:48 -04001828#Image 3
1829SkMatrix matrix;
1830SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1831SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1832matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1833matrix.postSkew(.5f, 0, source.width() / 2, source.height() / 2);
1834canvas->concat(matrix);
1835canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001836##
1837
Cary Clark154beea2017-10-26 07:58:48 -04001838#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001839
1840##
1841
1842# ------------------------------------------------------------------------------
1843
1844#Method void postSkew(SkScalar kx, SkScalar ky)
Cary Clark09d80c02018-10-31 12:14:03 -04001845#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001846
1847#Example
Cary Clark154beea2017-10-26 07:58:48 -04001848#Image 3
1849SkMatrix matrix;
1850SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1851SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1852matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1853matrix.postSkew(.5f, 0);
1854canvas->concat(matrix);
1855canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001856##
1857
Cary Clark154beea2017-10-26 07:58:48 -04001858#SeeAlso preSkew setSkew
Cary Clarkbc5697d2017-10-04 14:31:33 -04001859
1860##
1861
1862# ------------------------------------------------------------------------------
1863
1864#Method void postConcat(const SkMatrix& other)
Cary Clark4855f782018-02-06 09:41:53 -05001865#In Set
Cary Clark61313f32018-10-08 14:57:48 -04001866#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05001867#Line # post-multiplies Matrix by Matrix parameter ##
Cary Clark09d80c02018-10-31 12:14:03 -04001868#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04001869
1870#Example
Cary Clark154beea2017-10-26 07:58:48 -04001871#Image 3
1872#Height 64
Cary Clark681287e2018-03-16 11:34:15 -04001873SkMatrix matrix;
Cary Clark154beea2017-10-26 07:58:48 -04001874SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
1875SkRect::Make(source.bounds()).toQuad(bitmapBounds);
1876matrix.setPolyToPoly(bitmapBounds, perspect, 4);
1877matrix.postConcat(matrix);
1878canvas->concat(matrix);
1879canvas->drawBitmap(source, 0, 0);
Cary Clarkbc5697d2017-10-04 14:31:33 -04001880##
1881
Cary Clark154beea2017-10-26 07:58:48 -04001882#SeeAlso preConcat setConcat Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04001883
1884##
1885
1886# ------------------------------------------------------------------------------
1887
1888#Enum ScaleToFit
Cary Clark682c58d2018-05-16 07:07:07 -04001889#Line # options to map Rects ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001890#Code
1891 enum ScaleToFit {
1892 kFill_ScaleToFit,
1893 kStart_ScaleToFit,
1894 kCenter_ScaleToFit,
1895 kEnd_ScaleToFit,
1896 };
1897##
1898
Cary Clark154beea2017-10-26 07:58:48 -04001899ScaleToFit describes how Matrix is constructed to map one Rect to another.
1900ScaleToFit may allow Matrix to have unequal horizontal and vertical scaling,
1901or may restrict Matrix to square scaling. If restricted, ScaleToFit specifies
1902how Matrix maps to the side or center of the destination Rect.
1903
1904#Const kFill_ScaleToFit 0
Cary Clark682c58d2018-05-16 07:07:07 -04001905#Line # scales in x and y to fill destination Rect ##
Cary Clark154beea2017-10-26 07:58:48 -04001906 Computes Matrix that scales in x and y independently, so that source Rect is
1907 mapped to completely fill destination Rect. The aspect ratio of source Rect
1908 may change.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001909##
Cary Clark154beea2017-10-26 07:58:48 -04001910#Const kStart_ScaleToFit 1
Cary Clark682c58d2018-05-16 07:07:07 -04001911#Line # scales and aligns to left and top ##
Cary Clark154beea2017-10-26 07:58:48 -04001912 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
1913 width or height to destination Rect. Aligns mapping to left and top edges
1914 of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001915##
Cary Clark154beea2017-10-26 07:58:48 -04001916#Const kCenter_ScaleToFit 2
Cary Clark682c58d2018-05-16 07:07:07 -04001917#Line # scales and aligns to center ##
Cary Clark154beea2017-10-26 07:58:48 -04001918 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
1919 width or height to destination Rect. Aligns mapping to center of destination
1920 Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001921##
Cary Clark154beea2017-10-26 07:58:48 -04001922#Const kEnd_ScaleToFit 3
Cary Clark682c58d2018-05-16 07:07:07 -04001923#Line # scales and aligns to right and bottom ##
Cary Clark154beea2017-10-26 07:58:48 -04001924 Computes Matrix that maintains source Rect aspect ratio, mapping source Rect
1925 width or height to destination Rect. Aligns mapping to right and bottom
1926 edges of destination Rect.
Cary Clarkbc5697d2017-10-04 14:31:33 -04001927##
1928
1929#Example
Cary Clark154beea2017-10-26 07:58:48 -04001930 const char* labels[] = { "Fill", "Start", "Center", "End" };
1931 SkRect rects[] = {{5, 5, 59, 59}, {5, 74, 59, 108}, {10, 123, 44, 172}, {10, 187, 54, 231}};
1932 SkRect bounds;
1933 source.getBounds(&bounds);
1934 SkPaint paint;
1935 paint.setAntiAlias(true);
1936 for (auto fit : { SkMatrix::kFill_ScaleToFit, SkMatrix::kStart_ScaleToFit,
1937 SkMatrix::kCenter_ScaleToFit, SkMatrix::kEnd_ScaleToFit } ) {
1938 for (auto rect : rects ) {
1939 canvas->drawRect(rect, paint);
1940 SkMatrix matrix;
1941 if (!matrix.setRectToRect(bounds, rect, fit)) {
1942 continue;
1943 }
1944 SkAutoCanvasRestore acr(canvas, true);
1945 canvas->concat(matrix);
1946 canvas->drawBitmap(source, 0, 0);
1947 }
1948 canvas->drawString(labels[fit], 10, 255, paint);
1949 canvas->translate(64, 0);
1950 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04001951##
1952
Cary Clark154beea2017-10-26 07:58:48 -04001953#SeeAlso setRectToRect MakeRectToRect setPolyToPoly
Cary Clarkbc5697d2017-10-04 14:31:33 -04001954
1955##
1956
1957# ------------------------------------------------------------------------------
1958
1959#Method bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
Cary Clark4855f782018-02-06 09:41:53 -05001960#In Set
Cary Clark08895c42018-02-01 09:37:32 -05001961#Line # sets to map one Rect to another ##
Cary Clark09d80c02018-10-31 12:14:03 -04001962#Populate
Cary Clark154beea2017-10-26 07:58:48 -04001963
Cary Clarkbc5697d2017-10-04 14:31:33 -04001964#Example
Cary Clark154beea2017-10-26 07:58:48 -04001965 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
1966 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
1967 for (auto src : srcs) {
1968 for (auto dst : dsts) {
1969 SkMatrix matrix;
1970 matrix.setAll(-1, -1, -1, -1, -1, -1, -1, -1, -1);
1971 bool success = matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
1972 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g success: %s\n",
1973 src.fLeft, src.fTop, src.fRight, src.fBottom,
1974 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, success ? "true" : "false");
1975 matrix.dump();
1976 }
1977 }
1978#StdOut
1979src: 0, 0, 0, 0 dst: 0, 0, 0, 0 success: false
1980[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
1981src: 0, 0, 0, 0 dst: 5, 6, 8, 9 success: false
1982[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
1983src: 1, 2, 3, 4 dst: 0, 0, 0, 0 success: true
1984[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
1985src: 1, 2, 3, 4 dst: 5, 6, 8, 9 success: true
1986[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
1987##
Cary Clarkbc5697d2017-10-04 14:31:33 -04001988##
1989
Cary Clark682c58d2018-05-16 07:07:07 -04001990#SeeAlso MakeRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04001991
1992##
1993
1994# ------------------------------------------------------------------------------
1995
1996#Method static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf)
Cary Clark61313f32018-10-08 14:57:48 -04001997#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -05001998#Line # constructs from source Rect to destination Rect ##
Cary Clark09d80c02018-10-31 12:14:03 -04001999#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002000
2001#Example
2002 const SkRect srcs[] = { {0, 0, 0, 0}, {1, 2, 3, 4} };
2003 const SkRect dsts[] = { {0, 0, 0, 0}, {5, 6, 8, 9} };
2004 for (auto src : srcs) {
2005 for (auto dst : dsts) {
2006 SkMatrix matrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
2007 SkDebugf("src: %g, %g, %g, %g dst: %g, %g, %g, %g\n",
2008 src.fLeft, src.fTop, src.fRight, src.fBottom,
2009 dst.fLeft, dst.fTop, dst.fRight, dst.fBottom);
2010 matrix.dump();
2011 }
2012 }
2013#StdOut
2014src: 0, 0, 0, 0 dst: 0, 0, 0, 0
2015[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2016src: 0, 0, 0, 0 dst: 5, 6, 8, 9
2017[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2018src: 1, 2, 3, 4 dst: 0, 0, 0, 0
2019[ 0.0000 0.0000 0.0000][ 0.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2020src: 1, 2, 3, 4 dst: 5, 6, 8, 9
2021[ 1.5000 0.0000 3.5000][ 0.0000 1.5000 3.0000][ 0.0000 0.0000 1.0000]
2022##
2023##
2024
2025#SeeAlso setRectToRect ScaleToFit setPolyToPoly SkRect::isEmpty
Cary Clarkbc5697d2017-10-04 14:31:33 -04002026
2027##
2028
2029# ------------------------------------------------------------------------------
2030
2031#Method bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count)
Cary Clark4855f782018-02-06 09:41:53 -05002032#In Set
Cary Clark08895c42018-02-01 09:37:32 -05002033#Line # sets to map one to four points to an equal array of points ##
Cary Clark09d80c02018-10-31 12:14:03 -04002034#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002035
2036#Example
Cary Clark154beea2017-10-26 07:58:48 -04002037 const SkPoint src[] = { { 0, 0}, {30, 0}, {30, -30}, { 0, -30} };
2038 const SkPoint dst[] = { {50, 0}, {80, -10}, {90, -30}, {60, -40} };
2039 SkPaint blackPaint;
2040 blackPaint.setAntiAlias(true);
2041 blackPaint.setTextSize(42);
2042 SkPaint redPaint = blackPaint;
2043 redPaint.setColor(SK_ColorRED);
2044 for (int count : { 1, 2, 3, 4 } ) {
2045 canvas->translate(35, 55);
2046 for (int index = 0; index < count; ++index) {
2047 canvas->drawCircle(src[index], 3, blackPaint);
2048 canvas->drawCircle(dst[index], 3, blackPaint);
2049 if (index > 0) {
2050 canvas->drawLine(src[index], src[index - 1], blackPaint);
2051 canvas->drawLine(dst[index], dst[index - 1], blackPaint);
2052 }
2053 }
2054 SkMatrix matrix;
2055 matrix.setPolyToPoly(src, dst, count);
2056 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
2057 SkAutoCanvasRestore acr(canvas, true);
2058 canvas->concat(matrix);
2059 canvas->drawString("A", src[0].fX, src[0].fY, redPaint);
2060 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002061##
2062
Cary Clark154beea2017-10-26 07:58:48 -04002063#SeeAlso setRectToRect MakeRectToRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04002064
2065##
2066
2067# ------------------------------------------------------------------------------
2068
Cary Clark61313f32018-10-08 14:57:48 -04002069#Method bool invert(SkMatrix* inverse) const
2070#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05002071#Line # returns inverse, if possible ##
Cary Clark09d80c02018-10-31 12:14:03 -04002072#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002073
2074#Example
Cary Clark154beea2017-10-26 07:58:48 -04002075#Height 128
2076 const SkPoint src[] = { { 10, 120}, {120, 120}, {120, 10}, { 10, 10} };
2077 const SkPoint dst[] = { {150, 120}, {200, 100}, {240, 30}, { 130, 40} };
2078 SkPaint paint;
2079 paint.setAntiAlias(true);
2080 SkMatrix matrix;
2081 matrix.setPolyToPoly(src, dst, 4);
2082 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, src, paint);
2083 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, dst, paint);
2084 paint.setColor(SK_ColorBLUE);
2085 paint.setStrokeWidth(3);
2086 paint.setStrokeCap(SkPaint::kRound_Cap);
2087 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
Cary Clark681287e2018-03-16 11:34:15 -04002088 if (matrix.invert(&matrix)) {
2089 canvas->concat(matrix);
2090 canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, dst, paint);
2091 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002092##
2093
Cary Clark154beea2017-10-26 07:58:48 -04002094#SeeAlso Concat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002095
2096##
2097
2098# ------------------------------------------------------------------------------
2099
2100#Method static void SetAffineIdentity(SkScalar affine[6])
Cary Clark61313f32018-10-08 14:57:48 -04002101#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -05002102#Line # sets 3x2 array to identity ##
Cary Clark09d80c02018-10-31 12:14:03 -04002103#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002104
2105#Example
Cary Clark154beea2017-10-26 07:58:48 -04002106 SkScalar affine[6];
2107 SkMatrix::SetAffineIdentity(affine);
2108 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
2109 for (int i = 0; i < 6; ++i) {
2110 SkDebugf("%s: %g ", names[i], affine[i]);
2111 }
2112 SkDebugf("\n");
2113#StdOut
2114ScaleX: 1 SkewY: 0 SkewX: 0 ScaleY: 1 TransX: 0 TransY: 0
2115##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002116##
2117
Cary Clark154beea2017-10-26 07:58:48 -04002118#SeeAlso setAffine asAffine
Cary Clarkbc5697d2017-10-04 14:31:33 -04002119
2120##
2121
2122# ------------------------------------------------------------------------------
2123
Cary Clark61313f32018-10-08 14:57:48 -04002124#Method bool asAffine(SkScalar affine[6]) const
2125#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -05002126#Line # copies to 3x2 array ##
Cary Clark09d80c02018-10-31 12:14:03 -04002127#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002128
2129#Example
Cary Clark154beea2017-10-26 07:58:48 -04002130SkMatrix matrix;
2131matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
2132SkScalar affine[6];
Cary Clark681287e2018-03-16 11:34:15 -04002133if (matrix.asAffine(affine)) {
2134 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
2135 for (int i = 0; i < 6; ++i) {
2136 SkDebugf("%s: %g ", names[i], affine[i]);
2137 }
2138 SkDebugf("\n");
Cary Clark154beea2017-10-26 07:58:48 -04002139}
Cary Clark154beea2017-10-26 07:58:48 -04002140#StdOut
Cary Clark682c58d2018-05-16 07:07:07 -04002141ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
Cary Clark154beea2017-10-26 07:58:48 -04002142##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002143##
2144
Cary Clark154beea2017-10-26 07:58:48 -04002145#SeeAlso setAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04002146
2147##
2148
2149# ------------------------------------------------------------------------------
2150
2151#Method void setAffine(const SkScalar affine[6])
Cary Clark61313f32018-10-08 14:57:48 -04002152#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05002153#In Set
Cary Clark08895c42018-02-01 09:37:32 -05002154#Line # sets left two columns ##
Cary Clark09d80c02018-10-31 12:14:03 -04002155#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002156
2157#Example
2158SkMatrix matrix;
2159matrix.setAll(2, 3, 4, 5, 6, 7, 0, 0, 1);
2160SkScalar affine[6];
Cary Clark681287e2018-03-16 11:34:15 -04002161if (matrix.asAffine(affine)) {
2162 const char* names[] = { "ScaleX", "SkewY", "SkewX", "ScaleY", "TransX", "TransY" };
2163 for (int i = 0; i < 6; ++i) {
2164 SkDebugf("%s: %g ", names[i], affine[i]);
2165 }
2166 SkDebugf("\n");
2167 matrix.reset();
2168 matrix.setAffine(affine);
2169 matrix.dump();
Cary Clark154beea2017-10-26 07:58:48 -04002170}
Cary Clark154beea2017-10-26 07:58:48 -04002171#StdOut
Cary Clark682c58d2018-05-16 07:07:07 -04002172ScaleX: 2 SkewY: 5 SkewX: 3 ScaleY: 6 TransX: 4 TransY: 7
Cary Clark154beea2017-10-26 07:58:48 -04002173[ 2.0000 3.0000 4.0000][ 5.0000 6.0000 7.0000][ 0.0000 0.0000 1.0000]
2174##
2175##
2176
2177#SeeAlso asAffine SetAffineIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04002178
2179##
2180
2181# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05002182#Subtopic Transform
Cary Clark4855f782018-02-06 09:41:53 -05002183#Line # map points with Matrix ##
2184##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002185
2186#Method void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Cary Clark4855f782018-02-06 09:41:53 -05002187#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002188#Line # maps Point array ##
Cary Clark09d80c02018-10-31 12:14:03 -04002189#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002190
2191#Example
Cary Clark154beea2017-10-26 07:58:48 -04002192 SkMatrix matrix;
2193 matrix.reset();
2194 const int count = 4;
2195 SkPoint src[count];
2196 matrix.mapRectToQuad(src, {40, 70, 180, 220} );
2197 SkPaint paint;
2198 paint.setARGB(77, 23, 99, 154);
2199 for (int i = 0; i < 5; ++i) {
2200 SkPoint dst[count];
2201 matrix.mapPoints(dst, src, count);
2202 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, dst, paint);
2203 matrix.preRotate(35, 128, 128);
2204 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002205##
2206
Brian Salomonfa3783f2018-01-05 13:49:07 -05002207#SeeAlso mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04002208
2209##
2210
2211# ------------------------------------------------------------------------------
2212
2213#Method void mapPoints(SkPoint pts[], int count) const
Cary Clark09d80c02018-10-31 12:14:03 -04002214#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002215
Cary Clarkbc5697d2017-10-04 14:31:33 -04002216#Example
Cary Clark154beea2017-10-26 07:58:48 -04002217 SkMatrix matrix;
2218 matrix.setRotate(35, 128, 128);
2219 const int count = 4;
2220 SkPoint pts[count];
2221 matrix.mapRectToQuad(pts, {40, 70, 180, 220} );
2222 SkPaint paint;
2223 paint.setARGB(77, 23, 99, 154);
2224 for (int i = 0; i < 5; ++i) {
2225 canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, pts, paint);
2226 matrix.mapPoints(pts, count);
2227 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002228##
2229
Brian Salomonfa3783f2018-01-05 13:49:07 -05002230#SeeAlso mapXY mapHomogeneousPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04002231
2232##
2233
2234# ------------------------------------------------------------------------------
2235
Cary Clark154beea2017-10-26 07:58:48 -04002236#Method void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
Cary Clark4855f782018-02-06 09:41:53 -05002237#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002238#Line # maps Point3 array ##
Cary Clark09d80c02018-10-31 12:14:03 -04002239#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002240
2241#Example
Cary Clark154beea2017-10-26 07:58:48 -04002242 SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3},
2243 {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}};
2244 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 };
2245 constexpr int count = SK_ARRAY_COUNT(src);
2246 auto debugster = [=](SkPoint3 src[]) -> void {
2247 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) {
2248 const SkPoint3& s = src[lines[i]];
2249 const SkPoint3& e = src[lines[i + 1]];
2250 SkPaint paint;
2251 paint.setARGB(77, 23, 99, 154);
2252 canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint);
2253 }
2254 };
2255 canvas->save();
2256 canvas->translate(5, 5);
2257 canvas->scale(15, 15);
2258 debugster(src);
2259 canvas->restore();
2260 canvas->translate(128, 128);
2261 SkMatrix matrix;
2262 matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1);
Cary Clarka560c472017-11-27 10:44:06 -05002263 matrix.mapHomogeneousPoints(src, src, count);
Cary Clark154beea2017-10-26 07:58:48 -04002264 debugster(src);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002265##
2266
Brian Salomonfa3783f2018-01-05 13:49:07 -05002267#SeeAlso mapPoints mapXY mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04002268
2269##
2270
2271# ------------------------------------------------------------------------------
2272
2273#Method void mapXY(SkScalar x, SkScalar y, SkPoint* result) const
Cary Clark4855f782018-02-06 09:41:53 -05002274#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002275#Line # maps Point ##
Cary Clark09d80c02018-10-31 12:14:03 -04002276#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002277
2278#Example
2279 SkPaint paint;
2280 paint.setAntiAlias(true);
2281 SkMatrix matrix;
2282 matrix.setRotate(60, 128, 128);
2283 SkPoint lines[] = {{50, 50}, {150, 50}, {150, 150}};
2284 for (size_t i = 0; i < SK_ARRAY_COUNT(lines); ++i) {
2285 SkPoint pt;
2286 matrix.mapXY(lines[i].fX, lines[i].fY, &pt);
2287 canvas->drawCircle(pt.fX, pt.fY, 3, paint);
2288 }
2289 canvas->concat(matrix);
2290 canvas->drawPoints(SkCanvas::kPolygon_PointMode, SK_ARRAY_COUNT(lines), lines, paint);
2291##
2292
Brian Salomonfa3783f2018-01-05 13:49:07 -05002293#SeeAlso mapPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04002294
2295##
2296
2297# ------------------------------------------------------------------------------
2298
2299#Method SkPoint mapXY(SkScalar x, SkScalar y) const
Cary Clark09d80c02018-10-31 12:14:03 -04002300#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002301
2302#Example
2303#Image 4
2304SkMatrix matrix;
2305SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {30, 206}};
2306SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2307matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2308SkPaint paint;
2309paint.setAntiAlias(true);
2310paint.setStrokeWidth(3);
2311for (int x : { 0, source.width() } ) {
2312 for (int y : { 0, source.height() } ) {
2313 canvas->drawPoint(matrix.mapXY(x, y), paint);
2314 }
2315}
2316canvas->concat(matrix);
2317canvas->drawBitmap(source, 0, 0);
2318##
2319
Brian Salomonfa3783f2018-01-05 13:49:07 -05002320#SeeAlso mapPoints mapVectors
Cary Clarkbc5697d2017-10-04 14:31:33 -04002321
2322##
2323
2324# ------------------------------------------------------------------------------
2325
2326#Method void mapVectors(SkVector dst[], const SkVector src[], int count) const
Cary Clark4855f782018-02-06 09:41:53 -05002327#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002328#Line # maps Vector array ##
Cary Clark09d80c02018-10-31 12:14:03 -04002329#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002330
Cary Clarkbc5697d2017-10-04 14:31:33 -04002331#Example
Cary Clark154beea2017-10-26 07:58:48 -04002332 SkPaint paint;
2333 paint.setAntiAlias(true);
2334 paint.setStyle(SkPaint::kStroke_Style);
2335 SkMatrix matrix;
2336 matrix.reset();
2337 const SkVector radii[] = {{8, 4}, {9, 1}, {6, 2}, {7, 3}};
2338 for (int i = 0; i < 4; ++i) {
2339 SkVector rScaled[4];
2340 matrix.preScale(1.5f, 2.f);
2341 matrix.mapVectors(rScaled, radii, SK_ARRAY_COUNT(radii));
2342 SkRRect rrect;
2343 rrect.setRectRadii({20, 20, 180, 70}, rScaled);
2344 canvas->drawRRect(rrect, paint);
2345 canvas->translate(0, 60);
2346 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002347##
2348
Brian Salomonfa3783f2018-01-05 13:49:07 -05002349#SeeAlso mapVector mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04002350
2351##
2352
2353# ------------------------------------------------------------------------------
2354
2355#Method void mapVectors(SkVector vecs[], int count) const
Cary Clark09d80c02018-10-31 12:14:03 -04002356#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002357
Cary Clarkbc5697d2017-10-04 14:31:33 -04002358#Example
Cary Clark154beea2017-10-26 07:58:48 -04002359 SkPaint paint;
2360 paint.setAntiAlias(true);
2361 paint.setStyle(SkPaint::kStroke_Style);
2362 SkMatrix matrix;
2363 matrix.setScale(2, 3);
2364 SkVector radii[] = {{7, 7}, {3, 3}, {2, 2}, {4, 0}};
2365 for (int i = 0; i < 4; ++i) {
2366 SkRRect rrect;
2367 rrect.setRectRadii({20, 20, 180, 70}, radii);
2368 canvas->drawRRect(rrect, paint);
2369 canvas->translate(0, 60);
2370 matrix.mapVectors(radii, SK_ARRAY_COUNT(radii));
2371 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002372##
2373
Brian Salomonfa3783f2018-01-05 13:49:07 -05002374#SeeAlso mapVector mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04002375
2376##
2377
2378# ------------------------------------------------------------------------------
2379
2380#Method void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const
Cary Clark4855f782018-02-06 09:41:53 -05002381#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002382#Line # maps Vector ##
Cary Clark09d80c02018-10-31 12:14:03 -04002383#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002384
2385#Example
2386 SkPaint paint;
2387 paint.setColor(SK_ColorGREEN);
2388 paint.setAntiAlias(true);
2389 paint.setTextSize(48);
2390 SkMatrix matrix;
2391 matrix.setRotate(90);
2392 SkVector offset = { 7, 7 };
2393 for (int i = 0; i < 4; ++i) {
2394 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
2395 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
2396 matrix.mapVector(offset.fX, offset.fY, &offset);
2397 canvas->translate(0, 60);
2398 canvas->drawString("Text", 50, 0, paint);
2399 }
2400##
2401
Brian Salomonfa3783f2018-01-05 13:49:07 -05002402#SeeAlso mapVectors mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04002403
2404##
2405
2406# ------------------------------------------------------------------------------
2407
2408#Method SkVector mapVector(SkScalar dx, SkScalar dy) const
Cary Clark09d80c02018-10-31 12:14:03 -04002409#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002410
2411#Example
2412 SkPaint paint;
2413 paint.setColor(SK_ColorGREEN);
2414 paint.setAntiAlias(true);
2415 paint.setTextSize(48);
2416 SkMatrix matrix;
2417 matrix.setRotate(90);
2418 SkVector offset = { 7, 7 };
2419 for (int i = 0; i < 4; ++i) {
2420 paint.setImageFilter(SkDropShadowImageFilter::Make(offset.fX, offset.fY, 3, 3,
2421 SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr));
2422 offset = matrix.mapVector(offset.fX, offset.fY);
2423 canvas->translate(0, 60);
2424 canvas->drawString("Text", 50, 0, paint);
2425 }
2426##
2427
Brian Salomonfa3783f2018-01-05 13:49:07 -05002428#SeeAlso mapVectors mapPoints mapXY
Cary Clarkbc5697d2017-10-04 14:31:33 -04002429
2430##
2431
2432# ------------------------------------------------------------------------------
2433
2434#Method bool mapRect(SkRect* dst, const SkRect& src) const
Cary Clark4855f782018-02-06 09:41:53 -05002435#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002436#Line # returns bounds of mapped Rect ##
Cary Clark09d80c02018-10-31 12:14:03 -04002437#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002438
2439#Example
Cary Clark154beea2017-10-26 07:58:48 -04002440 SkPaint paint;
2441 paint.setAntiAlias(true);
2442 SkMatrix matrix;
2443 matrix.setRotate(45, 128, 128);
2444 SkRect rotatedBounds, bounds = {40, 50, 190, 200};
2445 matrix.mapRect(&rotatedBounds, bounds );
2446 paint.setColor(SK_ColorGRAY);
2447 canvas->drawRect(rotatedBounds, paint);
2448 canvas->concat(matrix);
2449 paint.setColor(SK_ColorRED);
2450 canvas->drawRect(bounds, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002451##
2452
Cary Clark154beea2017-10-26 07:58:48 -04002453#SeeAlso mapPoints rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04002454
2455##
2456
2457# ------------------------------------------------------------------------------
2458
2459#Method bool mapRect(SkRect* rect) const
Cary Clark09d80c02018-10-31 12:14:03 -04002460#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002461
2462#Example
Cary Clark154beea2017-10-26 07:58:48 -04002463 SkPaint paint;
2464 paint.setAntiAlias(true);
2465 SkMatrix matrix;
2466 matrix.setRotate(45, 128, 128);
2467 SkRect bounds = {40, 50, 190, 200};
2468 matrix.mapRect(&bounds);
2469 paint.setColor(SK_ColorGRAY);
2470 canvas->drawRect(bounds, paint);
2471 canvas->concat(matrix);
2472 paint.setColor(SK_ColorRED);
2473 canvas->drawRect({40, 50, 190, 200}, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002474##
2475
Cary Clark154beea2017-10-26 07:58:48 -04002476#SeeAlso mapRectScaleTranslate mapPoints rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04002477
2478##
2479
2480# ------------------------------------------------------------------------------
2481
Cary Clarkc06754b2018-05-16 21:28:55 -04002482#Method SkRect mapRect(const SkRect& src) const
Cary Clark09d80c02018-10-31 12:14:03 -04002483#Populate
Cary Clarkc06754b2018-05-16 21:28:55 -04002484
2485#Example
Cary Clark09d80c02018-10-31 12:14:03 -04002486 SkRect rect{110, 50, 180, 100};
2487 SkMatrix matrix;
2488 matrix.setRotate(50, 28, 28);
2489 SkRect mapped = matrix.mapRect(rect);
2490 SkPaint paint;
2491 paint.setAntiAlias(true);
2492 paint.setStyle(SkPaint::kStroke_Style);
2493 canvas->drawRect(rect, paint);
2494 canvas->drawRect(mapped, paint);
2495 canvas->concat(matrix);
2496 canvas->drawRect(rect, paint);
Cary Clarkc06754b2018-05-16 21:28:55 -04002497##
2498
Cary Clarkffb3d682018-05-17 12:17:28 -04002499#SeeAlso mapRectToQuad mapRectScaleTranslate
Cary Clarkc06754b2018-05-16 21:28:55 -04002500#Method ##
2501
2502# ------------------------------------------------------------------------------
2503
Cary Clarkbc5697d2017-10-04 14:31:33 -04002504#Method void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const
Cary Clark4855f782018-02-06 09:41:53 -05002505#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002506#Line # maps Rect to Point array ##
Cary Clark09d80c02018-10-31 12:14:03 -04002507#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002508
Cary Clarkbc5697d2017-10-04 14:31:33 -04002509#Example
Cary Clark2ade9972017-11-02 17:49:34 -04002510#Height 192
Cary Clark154beea2017-10-26 07:58:48 -04002511 SkPaint paint;
2512 paint.setAntiAlias(true);
2513 SkMatrix matrix;
2514 matrix.setRotate(60, 128, 128);
2515 SkRect rect = {50, 50, 150, 150};
2516 SkPoint pts[4];
2517 matrix.mapRectToQuad(pts, rect);
2518 for (int i = 0; i < 4; ++i) {
2519 canvas->drawCircle(pts[i].fX, pts[i].fY, 3, paint);
2520 }
2521 canvas->concat(matrix);
2522 paint.setStyle(SkPaint::kStroke_Style);
2523 canvas->drawRect(rect, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002524##
2525
Cary Clark154beea2017-10-26 07:58:48 -04002526#SeeAlso mapRect mapRectScaleTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002527
2528##
2529
2530# ------------------------------------------------------------------------------
2531
2532#Method void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const
Cary Clark4855f782018-02-06 09:41:53 -05002533#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002534#Line # returns bounds of mapped Rect ##
Cary Clark09d80c02018-10-31 12:14:03 -04002535#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002536
2537#Example
Cary Clark154beea2017-10-26 07:58:48 -04002538 SkPaint paint;
2539 SkMatrix matrix;
2540 SkRect rect = {100, 50, 150, 180};
2541 matrix.setScale(2, .5f, rect.centerX(), rect.centerY());
2542 SkRect rotated;
2543 matrix.mapRectScaleTranslate(&rotated, rect);
2544 paint.setStyle(SkPaint::kStroke_Style);
2545 canvas->drawRect(rect, paint);
2546 paint.setColor(SK_ColorRED);
2547 canvas->drawRect(rotated, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002548##
2549
Cary Clark154beea2017-10-26 07:58:48 -04002550#SeeAlso mapRect mapRectToQuad isScaleTranslate rectStaysRect
Cary Clarkbc5697d2017-10-04 14:31:33 -04002551
2552##
2553
2554# ------------------------------------------------------------------------------
2555
2556#Method SkScalar mapRadius(SkScalar radius) const
Cary Clark4855f782018-02-06 09:41:53 -05002557#In Transform
Cary Clark08895c42018-02-01 09:37:32 -05002558#Line # returns mean radius of mapped Circle ##
Cary Clark09d80c02018-10-31 12:14:03 -04002559#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002560
2561#Example
Cary Clark154beea2017-10-26 07:58:48 -04002562#Description
2563The area enclosed by a square with sides equal to mappedRadius is the same as
2564the area enclosed by the ellipse major and minor axes.
2565##
2566 SkPaint paint;
2567 paint.setAntiAlias(true);
2568 SkMatrix matrix;
2569 const SkPoint center = {108, 93};
2570 matrix.setScale(2, .5f, center.fX, center.fY);
2571 matrix.postRotate(45, center.fX, center.fY);
2572 const SkScalar circleRadius = 50;
2573 SkScalar mappedRadius = matrix.mapRadius(circleRadius);
2574 SkVector minorAxis, majorAxis;
2575 matrix.mapVector(0, circleRadius, &minorAxis);
2576 matrix.mapVector(circleRadius, 0, &majorAxis);
2577 SkString mappedArea;
2578 mappedArea.printf("area = %g", mappedRadius * mappedRadius);
2579 canvas->drawString(mappedArea, 145, 250, paint);
2580 canvas->drawString("mappedRadius", center.fX + mappedRadius + 3, center.fY, paint);
2581 paint.setColor(SK_ColorRED);
2582 SkString axArea;
2583 axArea.printf("area = %g", majorAxis.length() * minorAxis.length());
2584 paint.setStyle(SkPaint::kFill_Style);
2585 canvas->drawString(axArea, 15, 250, paint);
2586 paint.setStyle(SkPaint::kStroke_Style);
2587 canvas->drawRect({10, 200, 10 + majorAxis.length(), 200 + minorAxis.length()}, paint);
2588 paint.setColor(SK_ColorBLACK);
2589 canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint);
2590 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint);
2591 canvas->drawRect({140, 180, 140 + mappedRadius, 180 + mappedRadius}, paint);
2592 canvas->concat(matrix);
2593 canvas->drawCircle(center.fX, center.fY, circleRadius, paint);
2594 paint.setColor(SK_ColorRED);
2595 canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint);
2596 canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint);
Cary Clarkbc5697d2017-10-04 14:31:33 -04002597##
2598
Cary Clark154beea2017-10-26 07:58:48 -04002599#SeeAlso mapVector
Cary Clarkbc5697d2017-10-04 14:31:33 -04002600
2601##
2602
2603# ------------------------------------------------------------------------------
Cary Clarkbc5697d2017-10-04 14:31:33 -04002604#Method bool isFixedStepInX() const
Cary Clark4855f782018-02-06 09:41:53 -05002605#In Property
Cary Clark08895c42018-02-01 09:37:32 -05002606#Line # returns if transformation supports fixed step in x ##
Cary Clark09d80c02018-10-31 12:14:03 -04002607#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002608
2609#Example
Cary Clark154beea2017-10-26 07:58:48 -04002610 SkMatrix matrix;
2611 for (SkScalar px : { 0.0f, 0.1f } ) {
2612 for (SkScalar py : { 0.0f, 0.1f } ) {
2613 for (SkScalar sy : { 1, 2 } ) {
2614 matrix.setAll(1, 0, 0, 0, sy, 0, px, py, 1);
2615 matrix.dump();
2616 SkDebugf("isFixedStepInX: %s\n", matrix.isFixedStepInX() ? "true" : "false");
2617 }
2618 }
2619 }
2620#StdOut
2621[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
2622isFixedStepInX: true
2623[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.0000 1.0000]
2624isFixedStepInX: true
2625[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.0000 0.1000 1.0000]
2626isFixedStepInX: true
2627[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.0000 0.1000 1.0000]
2628isFixedStepInX: true
2629[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.0000 1.0000]
2630isFixedStepInX: false
2631[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.0000 1.0000]
2632isFixedStepInX: false
2633[ 1.0000 0.0000 0.0000][ 0.0000 1.0000 0.0000][ 0.1000 0.1000 1.0000]
2634isFixedStepInX: false
2635[ 1.0000 0.0000 0.0000][ 0.0000 2.0000 0.0000][ 0.1000 0.1000 1.0000]
2636isFixedStepInX: false
2637##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002638##
2639
Cary Clark154beea2017-10-26 07:58:48 -04002640#SeeAlso fixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04002641
2642##
2643
2644# ------------------------------------------------------------------------------
2645
2646#Method SkVector fixedStepInX(SkScalar y) const
Cary Clark4855f782018-02-06 09:41:53 -05002647#In Property
Cary Clark08895c42018-02-01 09:37:32 -05002648#Line # returns step in x for a position in y ##
Cary Clark09d80c02018-10-31 12:14:03 -04002649#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002650
2651#Example
Cary Clark154beea2017-10-26 07:58:48 -04002652#Image 3
2653 SkMatrix matrix;
2654 const SkPoint center = { 128, 128 };
2655 matrix.setScale(20, 25, center.fX, center.fY);
2656 matrix.postRotate(75, center.fX, center.fY);
2657 {
2658 SkAutoCanvasRestore acr(canvas, true);
2659 canvas->concat(matrix);
2660 canvas->drawBitmap(source, 0, 0);
2661 }
2662 if (matrix.isFixedStepInX()) {
2663 SkPaint paint;
2664 paint.setAntiAlias(true);
2665 SkVector step = matrix.fixedStepInX(128);
2666 SkVector end = center + step;
2667 canvas->drawLine(center, end, paint);
2668 SkVector arrow = { step.fX + step.fY, step.fY - step.fX};
2669 arrow = arrow * .25f;
2670 canvas->drawLine(end, end - arrow, paint);
2671 canvas->drawLine(end, {end.fX + arrow.fY, end.fY - arrow.fX}, paint);
2672 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002673##
2674
Cary Clark154beea2017-10-26 07:58:48 -04002675#SeeAlso isFixedStepInX getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04002676
2677##
2678
2679# ------------------------------------------------------------------------------
2680
2681#Method bool cheapEqualTo(const SkMatrix& m) const
Cary Clark61313f32018-10-08 14:57:48 -04002682#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05002683#Line # compares Matrix pair using memcmp() ##
Cary Clark09d80c02018-10-31 12:14:03 -04002684#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002685
2686#Example
Cary Clark154beea2017-10-26 07:58:48 -04002687 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
2688 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
2689 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
Cary Clarkbc5697d2017-10-04 14:31:33 -04002690 };
Cary Clark154beea2017-10-26 07:58:48 -04002691 SkMatrix a, b;
2692 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
2693 b.setIdentity();
2694 debugster("identity", a, b);
2695 a.setAll(1, -0.0f, 0, 0, 1, 0, 0, 0, 1);
2696 debugster("neg zero", a, b);
2697 a.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
2698 debugster(" one NaN", a, b);
2699 b.setAll(1, SK_ScalarNaN, 0, 0, 1, 0, 0, 0, 1);
2700 debugster("both NaN", a, b);
2701#StdOut
2702identity: a == b a.cheapEqualTo(b): true
2703neg zero: a == b a.cheapEqualTo(b): false
2704 one NaN: a != b a.cheapEqualTo(b): false
2705both NaN: a != b a.cheapEqualTo(b): true
2706##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002707##
2708
Cary Clark154beea2017-10-26 07:58:48 -04002709#SeeAlso operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04002710
2711##
2712
2713# ------------------------------------------------------------------------------
2714
Cary Clark154beea2017-10-26 07:58:48 -04002715#Method bool operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04002716
Cary Clark08895c42018-02-01 09:37:32 -05002717#Line # returns true if members are equal ##
Cary Clark09d80c02018-10-31 12:14:03 -04002718#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002719
2720#Example
Cary Clark154beea2017-10-26 07:58:48 -04002721 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
2722 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
2723 a == b ? '=' : '!', a.cheapEqualTo(b) ? "true" : "false");
2724 };
2725 SkMatrix a, b;
2726 a.setAll(1, 0, 0, 0, 1, 0, 0, 0, 1);
2727 b.setScale(2, 4);
2728 b.postScale(0.5f, 0.25f);
2729 debugster("identity", a, b);
2730#StdOut
2731identity: a == b a.cheapEqualTo(b): true
2732##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002733##
2734
Cary Clark154beea2017-10-26 07:58:48 -04002735#SeeAlso cheapEqualTo operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04002736
2737##
2738
2739# ------------------------------------------------------------------------------
2740
Cary Clark154beea2017-10-26 07:58:48 -04002741#Method bool operator!=(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04002742
Cary Clark08895c42018-02-01 09:37:32 -05002743#Line # returns true if members are unequal ##
Cary Clark09d80c02018-10-31 12:14:03 -04002744#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002745
2746#Example
Cary Clark154beea2017-10-26 07:58:48 -04002747 auto debugster = [](const char* prefix, const SkMatrix& a, const SkMatrix& b) -> void {
2748 SkDebugf("%s: a %c= b a.cheapEqualTo(b): %s\n", prefix,
2749 a != b ? '!' : '=', a.cheapEqualTo(b) ? "true" : "false");
2750 };
2751 SkMatrix a, b;
2752 a.setAll(1, 0, 0, 0, 1, 0, 1, 0, 1);
Cary Clark681287e2018-03-16 11:34:15 -04002753 if (a.invert(&b)) {
2754 debugster("identity", a, b);
2755 }
Cary Clarkbc5697d2017-10-04 14:31:33 -04002756##
2757
Cary Clark154beea2017-10-26 07:58:48 -04002758#SeeAlso cheapEqualTo operator==(const SkMatrix& a, const SkMatrix& b)
Cary Clarkbc5697d2017-10-04 14:31:33 -04002759
2760##
2761
2762# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05002763#Subtopic Utility
Cary Clark4855f782018-02-06 09:41:53 -05002764#Line # rarely called management functions ##
2765##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002766
2767#Method void dump() const
Cary Clark4855f782018-02-06 09:41:53 -05002768#In Utility
Cary Clark08895c42018-02-01 09:37:32 -05002769#Line # sends text representation using floats to standard output ##
Cary Clark09d80c02018-10-31 12:14:03 -04002770#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002771
Cary Clarkbc5697d2017-10-04 14:31:33 -04002772#Example
Cary Clark154beea2017-10-26 07:58:48 -04002773 SkMatrix matrix;
2774 matrix.setRotate(45);
2775 matrix.dump();
2776 SkMatrix nearlyEqual;
2777 nearlyEqual.setAll(0.7071f, -0.7071f, 0, 0.7071f, 0.7071f, 0, 0, 0, 1);
2778 nearlyEqual.dump();
2779 SkDebugf("matrix %c= nearlyEqual\n", matrix == nearlyEqual ? '=' : '!');
2780#StdOut
2781[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
2782[ 0.7071 -0.7071 0.0000][ 0.7071 0.7071 0.0000][ 0.0000 0.0000 1.0000]
2783matrix != nearlyEqual
2784##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002785##
2786
Cary Clark27dddae2018-06-08 15:57:37 -04002787#SeeAlso SkPath::dump
Cary Clarkbc5697d2017-10-04 14:31:33 -04002788
2789##
2790
2791# ------------------------------------------------------------------------------
2792
2793#Method SkScalar getMinScale() const
Cary Clark4855f782018-02-06 09:41:53 -05002794#In Property
Cary Clark08895c42018-02-01 09:37:32 -05002795#Line # returns minimum scaling, if possible ##
Cary Clark09d80c02018-10-31 12:14:03 -04002796#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002797
2798#Example
Cary Clark154beea2017-10-26 07:58:48 -04002799 SkMatrix matrix;
2800 matrix.setScale(42, 24);
2801 SkDebugf("matrix.getMinScale() %g\n", matrix.getMinScale());
2802#StdOut
2803matrix.getMinScale() 24
2804##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002805##
2806
Cary Clark154beea2017-10-26 07:58:48 -04002807#SeeAlso getMaxScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04002808
2809##
2810
2811# ------------------------------------------------------------------------------
2812
2813#Method SkScalar getMaxScale() const
Cary Clark4855f782018-02-06 09:41:53 -05002814#In Property
Cary Clark08895c42018-02-01 09:37:32 -05002815#Line # returns maximum scaling, if possible ##
Cary Clark09d80c02018-10-31 12:14:03 -04002816#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002817
2818#Example
Cary Clark154beea2017-10-26 07:58:48 -04002819 SkMatrix matrix;
2820 matrix.setScale(42, 24);
2821 SkDebugf("matrix.getMaxScale() %g\n", matrix.getMaxScale());
2822#StdOut
2823matrix.getMaxScale() 42
2824##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002825##
2826
Cary Clark154beea2017-10-26 07:58:48 -04002827#SeeAlso getMinScale getMinMaxScales
Cary Clarkbc5697d2017-10-04 14:31:33 -04002828
2829##
2830
2831# ------------------------------------------------------------------------------
2832
Cary Clark61313f32018-10-08 14:57:48 -04002833#Method bool getMinMaxScales(SkScalar scaleFactors[2]) const
Cary Clark4855f782018-02-06 09:41:53 -05002834#In Property
Cary Clark08895c42018-02-01 09:37:32 -05002835#Line # returns minimum and maximum scaling, if possible ##
Cary Clark09d80c02018-10-31 12:14:03 -04002836#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002837
2838#Example
Cary Clark154beea2017-10-26 07:58:48 -04002839 SkMatrix matrix;
2840 matrix.setAll(1, 0, 0, 0, 1, 0, 0, 0, 0);
Cary Clark681287e2018-03-16 11:34:15 -04002841 if (matrix.invert(&matrix)) {
2842 SkScalar factor[2] = {2, 2};
2843 bool result = matrix.getMinMaxScales(factor);
2844 SkDebugf("matrix.getMinMaxScales() %s %g %g\n",
2845 result ? "true" : "false", factor[0], factor[1]);
2846 }
Cary Clark154beea2017-10-26 07:58:48 -04002847#StdOut
2848matrix.getMinMaxScales() false 2 2
2849##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002850##
2851
Cary Clark154beea2017-10-26 07:58:48 -04002852#SeeAlso getMinScale getMaxScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002853
2854##
2855
2856# ------------------------------------------------------------------------------
2857
2858#Method bool decomposeScale(SkSize* scale, SkMatrix* remaining = nullptr) const
Cary Clark4855f782018-02-06 09:41:53 -05002859#In Property
Cary Clark08895c42018-02-01 09:37:32 -05002860#Line # separates scale if possible ##
Cary Clark154beea2017-10-26 07:58:48 -04002861Decomposes Matrix into scale components and whatever remains. Returns false if
2862Matrix could not be decomposed.
2863
Cary Clark5538c132018-06-14 12:28:14 -04002864Sets scale to portion of Matrix that scale axes. Sets remaining to Matrix
2865with scaling factored out. remaining may be passed as nullptr
Cary Clark154beea2017-10-26 07:58:48 -04002866to determine if Matrix can be decomposed without computing remainder.
2867
2868Returns true if scale components are found. scale and remaining are
2869unchanged if Matrix contains perspective; scale factors are not finite, or
Cary Clark682c58d2018-05-16 07:07:07 -04002870are nearly zero.
Cary Clark154beea2017-10-26 07:58:48 -04002871
Cary Clark2be81cf2018-09-13 12:04:30 -04002872On success: #Formula # Matrix = scale * Remaining ##.
Cary Clark154beea2017-10-26 07:58:48 -04002873
Cary Clark2be81cf2018-09-13 12:04:30 -04002874#Param scale axes scaling factors; may be nullptr ##
Cary Clark154beea2017-10-26 07:58:48 -04002875#Param remaining Matrix without scaling; may be nullptr ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002876
Cary Clark154beea2017-10-26 07:58:48 -04002877#Return true if scale can be computed ##
Cary Clarkbc5697d2017-10-04 14:31:33 -04002878
2879#Example
Cary Clark154beea2017-10-26 07:58:48 -04002880 SkMatrix matrix;
2881 matrix.setRotate(90 * SK_Scalar1);
2882 matrix.postScale(1.f / 4, 1.f / 2);
2883 matrix.dump();
2884 SkSize scale = {SK_ScalarNaN, SK_ScalarNaN};
2885 SkMatrix remaining;
2886 remaining.reset();
2887 bool success = matrix.decomposeScale(&scale, &remaining);
2888 SkDebugf("success: %s ", success ? "true" : "false");
2889 SkDebugf("scale: %g, %g\n", scale.width(), scale.height());
2890 remaining.dump();
2891 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height());
2892 SkMatrix combined = SkMatrix::Concat(scaleMatrix, remaining);
2893 combined.dump();
2894#StdOut
2895[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2896success: true scale: 0.5, 0.25
2897[ 0.0000 -0.5000 0.0000][ 2.0000 0.0000 0.0000][ 0.0000 0.0000 1.0000]
2898[ 0.0000 -0.2500 0.0000][ 0.5000 0.0000 0.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 setScale MakeScale
Cary Clarkbc5697d2017-10-04 14:31:33 -04002903
2904##
2905
2906# ------------------------------------------------------------------------------
2907
2908#Method static const SkMatrix& I()
Cary Clark61313f32018-10-08 14:57:48 -04002909#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -05002910#Line # returns a reference to a const identity Matrix ##
Cary Clark09d80c02018-10-31 12:14:03 -04002911#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002912
2913#Example
2914 SkMatrix m1, m2, m3;
2915 m1.reset();
2916 m2.setIdentity();
2917 m3 = SkMatrix::I();
2918 SkDebugf("m1 %c= m2\n", m1 == m2 ? '=' : '!');
2919 SkDebugf("m2 %c= m3\n", m1 == m2 ? '=' : '!');
2920#StdOut
2921m1 == m2
2922m2 == m3
2923##
2924##
2925
2926#SeeAlso reset() setIdentity
Cary Clarkbc5697d2017-10-04 14:31:33 -04002927
2928##
2929
2930# ------------------------------------------------------------------------------
2931
2932#Method static const SkMatrix& InvalidMatrix()
Cary Clark61313f32018-10-08 14:57:48 -04002933#In Constructors
Cary Clark08895c42018-02-01 09:37:32 -05002934#Line # returns a reference to a const invalid Matrix ##
Cary Clark09d80c02018-10-31 12:14:03 -04002935#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002936
2937#Example
2938 SkDebugf("scaleX %g\n", SkMatrix::InvalidMatrix().getScaleX());
2939#StdOut
2940scaleX 3.40282e+38
2941##
2942##
2943
2944#SeeAlso SeeAlso getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04002945
2946##
2947
2948# ------------------------------------------------------------------------------
2949
2950#Method static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b)
Cary Clark61313f32018-10-08 14:57:48 -04002951#In Operators
Cary Clark08895c42018-02-01 09:37:32 -05002952#Line # returns the concatenation of Matrix pair ##
Cary Clark09d80c02018-10-31 12:14:03 -04002953#Populate
Cary Clark154beea2017-10-26 07:58:48 -04002954
2955#Example
2956#Height 64
2957#Image 4
2958#Description
2959setPolyToPoly creates perspective matrices, one the inverse of the other.
2960Multiplying the matrix by its inverse turns into an identity matrix.
2961##
2962SkMatrix matrix, matrix2;
2963SkPoint bitmapBounds[4], perspect[4] = {{50, 10}, {180, 40}, {236, 176}, {10, 206}};
2964SkRect::Make(source.bounds()).toQuad(bitmapBounds);
2965matrix.setPolyToPoly(bitmapBounds, perspect, 4);
2966matrix2.setPolyToPoly(perspect, bitmapBounds, 4);
2967SkMatrix concat = SkMatrix::Concat(matrix, matrix2);
2968canvas->concat(concat);
2969canvas->drawBitmap(source, 0, 0);
2970##
2971
2972#SeeAlso preConcat postConcat
Cary Clarkbc5697d2017-10-04 14:31:33 -04002973
2974##
2975
2976# ------------------------------------------------------------------------------
2977
2978#Method void dirtyMatrixTypeCache()
Cary Clark4855f782018-02-06 09:41:53 -05002979#In Utility
Cary Clark08895c42018-02-01 09:37:32 -05002980#Line # sets internal cache to unknown state ##
Cary Clark09d80c02018-10-31 12:14:03 -04002981#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04002982
2983#Example
Cary Clark154beea2017-10-26 07:58:48 -04002984SkMatrix matrix;
2985matrix.setIdentity();
2986SkDebugf("with identity matrix: x = %g\n", matrix.mapXY(24, 42).fX);
2987SkScalar& skewRef = matrix[SkMatrix::kMSkewX];
2988skewRef = 0;
2989SkDebugf("after skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
2990skewRef = 1;
2991SkDebugf("after 2nd skew x mod: x = %g\n", matrix.mapXY(24, 42).fX);
2992matrix.dirtyMatrixTypeCache();
2993SkDebugf("after dirty cache: x = %g\n", matrix.mapXY(24, 42).fX);
2994#StdOut
2995with identity matrix: x = 24
2996after skew x mod: x = 24
2997after 2nd skew x mod: x = 24
2998after dirty cache: x = 66
2999##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003000##
3001
Cary Clark154beea2017-10-26 07:58:48 -04003002#SeeAlso operator[](int index) getType
Cary Clarkbc5697d2017-10-04 14:31:33 -04003003
3004##
3005
3006# ------------------------------------------------------------------------------
3007
3008#Method void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
Cary Clark61313f32018-10-08 14:57:48 -04003009#In Constructors
Cary Clark4855f782018-02-06 09:41:53 -05003010#In Set
Cary Clark08895c42018-02-01 09:37:32 -05003011#Line # sets to scale and translate ##
Cary Clark09d80c02018-10-31 12:14:03 -04003012#Populate
Cary Clark154beea2017-10-26 07:58:48 -04003013
3014#Example
3015SkMatrix matrix;
3016matrix.setScaleTranslate(1, 2, 3, 4);
3017matrix.dump();
3018#StdOut
3019[ 1.0000 0.0000 3.0000][ 0.0000 2.0000 4.0000][ 0.0000 0.0000 1.0000]
3020##
3021##
3022
3023#SeeAlso setScale preTranslate postTranslate
Cary Clarkbc5697d2017-10-04 14:31:33 -04003024
3025##
3026
3027# ------------------------------------------------------------------------------
3028
3029#Method bool isFinite() const
Cary Clark4855f782018-02-06 09:41:53 -05003030#In Property
Cary Clark08895c42018-02-01 09:37:32 -05003031#Line # returns if all Matrix values are not infinity, NaN ##
Cary Clark09d80c02018-10-31 12:14:03 -04003032#Populate
Cary Clarkbc5697d2017-10-04 14:31:33 -04003033
3034#Example
Cary Clark154beea2017-10-26 07:58:48 -04003035SkMatrix matrix = SkMatrix::MakeTrans(SK_ScalarNaN, 0);
3036matrix.dump();
3037SkDebugf("matrix is finite: %s\n", matrix.isFinite() ? "true" : "false");
3038SkDebugf("matrix %c= matrix\n", matrix == matrix ? '=' : '!');
3039#StdOut
3040[ 1.0000 0.0000 nan][ 0.0000 1.0000 0.0000][ 0.0000 0.0000 1.0000]
3041matrix is finite: false
3042matrix != matrix
3043##
Cary Clarkbc5697d2017-10-04 14:31:33 -04003044##
3045
Cary Clark154beea2017-10-26 07:58:48 -04003046#SeeAlso operator==
Cary Clarkbc5697d2017-10-04 14:31:33 -04003047
3048##
3049
3050#Class SkMatrix ##
3051
3052#Topic Matrix ##