blob: a69111c2cdc43351ecf09c31648d3faefc5969c6 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.com8260a892011-06-13 14:02:52 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.com8260a892011-06-13 14:02:52 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.com8260a892011-06-13 14:02:52 +000011#include "SkMatrix44.h"
12
13SkMatrix44::SkMatrix44() {
14 this->setIdentity();
15}
16
17SkMatrix44::SkMatrix44(const SkMatrix44& src) {
18 memcpy(this, &src, sizeof(src));
19}
20
21SkMatrix44::SkMatrix44(const SkMatrix44& a, const SkMatrix44& b) {
22 this->setConcat(a, b);
23}
24
reed@google.com631940c2012-11-27 13:13:22 +000025bool SkMatrix44::operator==(const SkMatrix44& other) const {
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +000026 if (fIdentity && other.fIdentity)
27 return true;
28
reed@google.com631940c2012-11-27 13:13:22 +000029 const SkMScalar* a = &fMat[0][0];
30 const SkMScalar* b = &other.fMat[0][0];
31 for (int i = 0; i < 16; ++i) {
32 if (a[i] != b[i]) {
33 return false;
34 }
35 }
36 return true;
reed@google.com8260a892011-06-13 14:02:52 +000037}
38
39///////////////////////////////////////////////////////////////////////////////
40
reed@google.comda9fac02011-06-13 14:46:52 +000041void SkMatrix44::asColMajorf(float dst[]) const {
42 const SkMScalar* src = &fMat[0][0];
43#ifdef SK_MSCALAR_IS_DOUBLE
44 for (int i = 0; i < 16; ++i) {
45 dst[i] = SkMScalarToFloat(src[i]);
46 }
vollick@chromium.org5596a692012-11-13 20:12:00 +000047#elif defined SK_MSCALAR_IS_FLOAT
reed@google.comda9fac02011-06-13 14:46:52 +000048 memcpy(dst, src, 16 * sizeof(float));
49#endif
50}
51
52void SkMatrix44::asColMajord(double dst[]) const {
53 const SkMScalar* src = &fMat[0][0];
54#ifdef SK_MSCALAR_IS_DOUBLE
55 memcpy(dst, src, 16 * sizeof(double));
vollick@chromium.org5596a692012-11-13 20:12:00 +000056#elif defined SK_MSCALAR_IS_FLOAT
reed@google.comda9fac02011-06-13 14:46:52 +000057 for (int i = 0; i < 16; ++i) {
58 dst[i] = SkMScalarToDouble(src[i]);
59 }
60#endif
61}
62
63void SkMatrix44::asRowMajorf(float dst[]) const {
64 const SkMScalar* src = &fMat[0][0];
65 for (int i = 0; i < 4; ++i) {
66 dst[0] = SkMScalarToFloat(src[0]);
67 dst[4] = SkMScalarToFloat(src[1]);
68 dst[8] = SkMScalarToFloat(src[2]);
69 dst[12] = SkMScalarToFloat(src[3]);
70 src += 4;
71 dst += 1;
72 }
73}
74
75void SkMatrix44::asRowMajord(double dst[]) const {
76 const SkMScalar* src = &fMat[0][0];
77 for (int i = 0; i < 4; ++i) {
78 dst[0] = SkMScalarToDouble(src[0]);
79 dst[4] = SkMScalarToDouble(src[1]);
80 dst[8] = SkMScalarToDouble(src[2]);
81 dst[12] = SkMScalarToDouble(src[3]);
82 src += 4;
83 dst += 1;
84 }
85}
86
vollick@chromium.orgf11cf9f2012-11-19 21:02:06 +000087void SkMatrix44::setColMajorf(const float src[]) {
88 SkMScalar* dst = &fMat[0][0];
89#ifdef SK_MSCALAR_IS_DOUBLE
90 for (int i = 0; i < 16; ++i) {
91 dst[i] = SkMScalarToFloat(src[i]);
92 }
93#elif defined SK_MSCALAR_IS_FLOAT
94 memcpy(dst, src, 16 * sizeof(float));
95#endif
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +000096 fIdentity = false;
vollick@chromium.orgf11cf9f2012-11-19 21:02:06 +000097}
98
99void SkMatrix44::setColMajord(const double src[]) {
100 SkMScalar* dst = &fMat[0][0];
101#ifdef SK_MSCALAR_IS_DOUBLE
102 memcpy(dst, src, 16 * sizeof(double));
103#elif defined SK_MSCALAR_IS_FLOAT
104 for (int i = 0; i < 16; ++i) {
105 dst[i] = SkMScalarToDouble(src[i]);
106 }
107#endif
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000108 fIdentity = false;
vollick@chromium.orgf11cf9f2012-11-19 21:02:06 +0000109}
110
111void SkMatrix44::setRowMajorf(const float src[]) {
112 SkMScalar* dst = &fMat[0][0];
113 for (int i = 0; i < 4; ++i) {
114 dst[0] = SkMScalarToFloat(src[0]);
115 dst[4] = SkMScalarToFloat(src[1]);
116 dst[8] = SkMScalarToFloat(src[2]);
117 dst[12] = SkMScalarToFloat(src[3]);
118 src += 4;
119 dst += 1;
120 }
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000121 fIdentity = false;
vollick@chromium.orgf11cf9f2012-11-19 21:02:06 +0000122}
123
124void SkMatrix44::setRowMajord(const double src[]) {
125 SkMScalar* dst = &fMat[0][0];
126 for (int i = 0; i < 4; ++i) {
127 dst[0] = SkMScalarToDouble(src[0]);
128 dst[4] = SkMScalarToDouble(src[1]);
129 dst[8] = SkMScalarToDouble(src[2]);
130 dst[12] = SkMScalarToDouble(src[3]);
131 src += 4;
132 dst += 1;
133 }
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000134 fIdentity = false;
vollick@chromium.orgf11cf9f2012-11-19 21:02:06 +0000135}
136
reed@google.comda9fac02011-06-13 14:46:52 +0000137///////////////////////////////////////////////////////////////////////////////
138
reed@google.com8260a892011-06-13 14:02:52 +0000139bool SkMatrix44::isIdentity() const {
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000140 if (fIdentity)
141 return true;
142
digit@google.com3e05f292012-01-10 10:00:59 +0000143 static const SkMScalar sIdentityMat[4][4] = {
144 { 1, 0, 0, 0 },
145 { 0, 1, 0, 0 },
146 { 0, 0, 1, 0 },
147 { 0, 0, 0, 1 },
148 };
149 return !memcmp(fMat, sIdentityMat, sizeof(fMat));
reed@google.com8260a892011-06-13 14:02:52 +0000150}
151
152///////////////////////////////////////////////////////////////////////////////
153
154void SkMatrix44::setIdentity() {
155 sk_bzero(fMat, sizeof(fMat));
156 fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = 1;
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000157 fIdentity = true;
reed@google.com8260a892011-06-13 14:02:52 +0000158}
159
160void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
161 SkMScalar m10, SkMScalar m11, SkMScalar m12,
162 SkMScalar m20, SkMScalar m21, SkMScalar m22) {
163 sk_bzero(fMat, sizeof(fMat));
164 fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0;
165 fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0;
166 fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0;
167 fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1;
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000168 fIdentity = false;
reed@google.com8260a892011-06-13 14:02:52 +0000169}
170
171///////////////////////////////////////////////////////////////////////////////
172
173void SkMatrix44::setTranslate(SkMScalar tx, SkMScalar ty, SkMScalar tz) {
174 this->setIdentity();
175 fMat[3][0] = tx;
176 fMat[3][1] = ty;
177 fMat[3][2] = tz;
178 fMat[3][3] = 1;
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000179 fIdentity = false;
reed@google.com8260a892011-06-13 14:02:52 +0000180}
181
182void SkMatrix44::preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
183 SkMatrix44 mat;
184 mat.setTranslate(dx, dy, dz);
185 this->preConcat(mat);
186}
187
188void SkMatrix44::postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
189 fMat[3][0] += dx;
190 fMat[3][1] += dy;
191 fMat[3][2] += dz;
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000192 fIdentity = false;
reed@google.com8260a892011-06-13 14:02:52 +0000193}
194
195///////////////////////////////////////////////////////////////////////////////
196
197void SkMatrix44::setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
198 sk_bzero(fMat, sizeof(fMat));
199 fMat[0][0] = sx;
200 fMat[1][1] = sy;
201 fMat[2][2] = sz;
202 fMat[3][3] = 1;
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000203 fIdentity = false;
reed@google.com8260a892011-06-13 14:02:52 +0000204}
205
206void SkMatrix44::preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
207 SkMatrix44 tmp;
208 tmp.setScale(sx, sy, sz);
209 this->preConcat(tmp);
210}
211
212void SkMatrix44::postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
213 for (int i = 0; i < 4; i++) {
214 fMat[i][0] *= sx;
215 fMat[i][1] *= sy;
216 fMat[i][2] *= sz;
217 }
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000218 fIdentity = false;
reed@google.com8260a892011-06-13 14:02:52 +0000219}
220
221///////////////////////////////////////////////////////////////////////////////
222
223void SkMatrix44::setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
224 SkMScalar radians) {
225 double len2 = x * x + y * y + z * z;
226 if (len2 != 1) {
227 if (len2 == 0) {
228 this->setIdentity();
229 return;
230 }
231 double scale = 1 / sqrt(len2);
bsalomon@google.com9d12f5c2011-09-29 18:08:18 +0000232 x = SkDoubleToMScalar(x * scale);
233 y = SkDoubleToMScalar(y * scale);
234 z = SkDoubleToMScalar(z * scale);
reed@google.com8260a892011-06-13 14:02:52 +0000235 }
236 this->setRotateAboutUnit(x, y, z, radians);
237}
238
239void SkMatrix44::setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
240 SkMScalar radians) {
241 double c = cos(radians);
242 double s = sin(radians);
243 double C = 1 - c;
244 double xs = x * s;
245 double ys = y * s;
246 double zs = z * s;
247 double xC = x * C;
248 double yC = y * C;
249 double zC = z * C;
250 double xyC = x * yC;
251 double yzC = y * zC;
252 double zxC = z * xC;
253
254 // if you're looking at wikipedia, remember that we're column major.
bsalomon@google.com9d12f5c2011-09-29 18:08:18 +0000255 this->set3x3(SkDoubleToMScalar(x * xC + c), // scale x
256 SkDoubleToMScalar(xyC + zs), // skew x
257 SkDoubleToMScalar(zxC - ys), // trans x
258
259 SkDoubleToMScalar(xyC - zs), // skew y
260 SkDoubleToMScalar(y * yC + c), // scale y
261 SkDoubleToMScalar(yzC + xs), // trans y
262
263 SkDoubleToMScalar(zxC + ys), // persp x
264 SkDoubleToMScalar(yzC - xs), // persp y
265 SkDoubleToMScalar(z * zC + c)); // persp 2
reed@google.com8260a892011-06-13 14:02:52 +0000266}
267
268///////////////////////////////////////////////////////////////////////////////
269
270void SkMatrix44::setConcat(const SkMatrix44& a, const SkMatrix44& b) {
271 SkMScalar result[4][4];
272 for (int i = 0; i < 4; i++) {
273 for (int j = 0; j < 4; j++) {
274 double value = 0;
275 for (int k = 0; k < 4; k++) {
276 value += SkMScalarToDouble(a.fMat[k][i]) * b.fMat[j][k];
277 }
278 result[j][i] = SkDoubleToMScalar(value);
279 }
280 }
281 memcpy(fMat, result, sizeof(result));
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000282 fIdentity = false;
reed@google.com8260a892011-06-13 14:02:52 +0000283}
284
285///////////////////////////////////////////////////////////////////////////////
286
287static inline SkMScalar det2x2(double m00, double m01, double m10, double m11) {
bsalomon@google.com9d12f5c2011-09-29 18:08:18 +0000288 return SkDoubleToMScalar(m00 * m11 - m10 * m01);
reed@google.com8260a892011-06-13 14:02:52 +0000289}
290
291static inline double det3x3(double m00, double m01, double m02,
292 double m10, double m11, double m12,
293 double m20, double m21, double m22) {
294 return m00 * det2x2(m11, m12, m21, m22) -
295 m10 * det2x2(m01, m02, m21, m22) +
296 m20 * det2x2(m01, m02, m11, m12);
297}
298
299/** We always perform the calculation in doubles, to avoid prematurely losing
300 precision along the way. This relies on the compiler automatically
301 promoting our SkMScalar values to double (if needed).
302 */
303double SkMatrix44::determinant() const {
304 return fMat[0][0] * det3x3(fMat[1][1], fMat[1][2], fMat[1][3],
305 fMat[2][1], fMat[2][2], fMat[2][3],
306 fMat[3][1], fMat[3][2], fMat[3][3]) -
307 fMat[1][0] * det3x3(fMat[0][1], fMat[0][2], fMat[0][3],
308 fMat[2][1], fMat[2][2], fMat[2][3],
309 fMat[3][1], fMat[3][2], fMat[3][3]) +
310 fMat[2][0] * det3x3(fMat[0][1], fMat[0][2], fMat[0][3],
311 fMat[1][1], fMat[1][2], fMat[1][3],
312 fMat[3][1], fMat[3][2], fMat[3][3]) -
313 fMat[3][0] * det3x3(fMat[0][1], fMat[0][2], fMat[0][3],
314 fMat[1][1], fMat[1][2], fMat[1][3],
315 fMat[2][1], fMat[2][2], fMat[2][3]);
316}
317
318///////////////////////////////////////////////////////////////////////////////
319
320// just picked a small value. not sure how to pick the "right" one
321#define TOO_SMALL_FOR_DETERMINANT (1.e-8)
322
323static inline double dabs(double x) {
324 if (x < 0) {
325 x = -x;
326 }
327 return x;
328}
329
330bool SkMatrix44::invert(SkMatrix44* inverse) const {
331 double det = this->determinant();
332 if (dabs(det) < TOO_SMALL_FOR_DETERMINANT) {
333 return false;
334 }
335 if (NULL == inverse) {
336 return true;
337 }
338
339 // we explicitly promote to doubles to keep the intermediate values in
340 // higher precision (assuming SkMScalar isn't already a double)
341 double m00 = fMat[0][0];
342 double m01 = fMat[0][1];
343 double m02 = fMat[0][2];
344 double m03 = fMat[0][3];
345 double m10 = fMat[1][0];
346 double m11 = fMat[1][1];
347 double m12 = fMat[1][2];
348 double m13 = fMat[1][3];
349 double m20 = fMat[2][0];
350 double m21 = fMat[2][1];
351 double m22 = fMat[2][2];
352 double m23 = fMat[2][3];
353 double m30 = fMat[3][0];
354 double m31 = fMat[3][1];
355 double m32 = fMat[3][2];
356 double m33 = fMat[3][3];
357
358 double tmp[4][4];
359
360 tmp[0][0] = m12*m23*m31 - m13*m22*m31 + m13*m21*m32 - m11*m23*m32 - m12*m21*m33 + m11*m22*m33;
361 tmp[0][1] = m03*m22*m31 - m02*m23*m31 - m03*m21*m32 + m01*m23*m32 + m02*m21*m33 - m01*m22*m33;
362 tmp[0][2] = m02*m13*m31 - m03*m12*m31 + m03*m11*m32 - m01*m13*m32 - m02*m11*m33 + m01*m12*m33;
363 tmp[0][3] = m03*m12*m21 - m02*m13*m21 - m03*m11*m22 + m01*m13*m22 + m02*m11*m23 - m01*m12*m23;
364 tmp[1][0] = m13*m22*m30 - m12*m23*m30 - m13*m20*m32 + m10*m23*m32 + m12*m20*m33 - m10*m22*m33;
365 tmp[1][1] = m02*m23*m30 - m03*m22*m30 + m03*m20*m32 - m00*m23*m32 - m02*m20*m33 + m00*m22*m33;
366 tmp[1][2] = m03*m12*m30 - m02*m13*m30 - m03*m10*m32 + m00*m13*m32 + m02*m10*m33 - m00*m12*m33;
367 tmp[1][3] = m02*m13*m20 - m03*m12*m20 + m03*m10*m22 - m00*m13*m22 - m02*m10*m23 + m00*m12*m23;
368 tmp[2][0] = m11*m23*m30 - m13*m21*m30 + m13*m20*m31 - m10*m23*m31 - m11*m20*m33 + m10*m21*m33;
369 tmp[2][1] = m03*m21*m30 - m01*m23*m30 - m03*m20*m31 + m00*m23*m31 + m01*m20*m33 - m00*m21*m33;
370 tmp[2][2] = m01*m13*m30 - m03*m11*m30 + m03*m10*m31 - m00*m13*m31 - m01*m10*m33 + m00*m11*m33;
371 tmp[2][3] = m03*m11*m20 - m01*m13*m20 - m03*m10*m21 + m00*m13*m21 + m01*m10*m23 - m00*m11*m23;
372 tmp[3][0] = m12*m21*m30 - m11*m22*m30 - m12*m20*m31 + m10*m22*m31 + m11*m20*m32 - m10*m21*m32;
373 tmp[3][1] = m01*m22*m30 - m02*m21*m30 + m02*m20*m31 - m00*m22*m31 - m01*m20*m32 + m00*m21*m32;
374 tmp[3][2] = m02*m11*m30 - m01*m12*m30 - m02*m10*m31 + m00*m12*m31 + m01*m10*m32 - m00*m11*m32;
375 tmp[3][3] = m01*m12*m20 - m02*m11*m20 + m02*m10*m21 - m00*m12*m21 - m01*m10*m22 + m00*m11*m22;
376
377 double invDet = 1.0 / det;
378 for (int i = 0; i < 4; i++) {
379 for (int j = 0; j < 4; j++) {
380 inverse->fMat[i][j] = SkDoubleToMScalar(tmp[i][j] * invDet);
381 }
382 }
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000383 inverse->fIdentity = false;
reed@google.com8260a892011-06-13 14:02:52 +0000384 return true;
385}
386
387///////////////////////////////////////////////////////////////////////////////
388
vollick@chromium.org9b21c252012-11-14 21:33:55 +0000389void SkMatrix44::transpose() {
390 SkTSwap(fMat[0][1], fMat[1][0]);
391 SkTSwap(fMat[0][2], fMat[2][0]);
392 SkTSwap(fMat[0][3], fMat[3][0]);
393 SkTSwap(fMat[1][2], fMat[2][1]);
394 SkTSwap(fMat[1][3], fMat[3][1]);
395 SkTSwap(fMat[2][3], fMat[3][2]);
396}
397
398///////////////////////////////////////////////////////////////////////////////
399
reed@google.com1ea95be2012-11-09 21:39:48 +0000400void SkMatrix44::mapScalars(const SkScalar src[4], SkScalar dst[4]) const {
reed@google.com8260a892011-06-13 14:02:52 +0000401 SkScalar result[4];
402 for (int i = 0; i < 4; i++) {
403 SkMScalar value = 0;
404 for (int j = 0; j < 4; j++) {
405 value += fMat[j][i] * src[j];
406 }
bsalomon@google.com72e49b82011-10-27 21:47:03 +0000407 result[i] = SkMScalarToScalar(value);
reed@google.com8260a892011-06-13 14:02:52 +0000408 }
409 memcpy(dst, result, sizeof(result));
410}
411
reed@google.com1ea95be2012-11-09 21:39:48 +0000412#ifdef SK_MSCALAR_IS_DOUBLE
413void SkMatrix44::mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const {
414 SkMScalar result[4];
415 for (int i = 0; i < 4; i++) {
416 SkMScalar value = 0;
417 for (int j = 0; j < 4; j++) {
418 value += fMat[j][i] * src[j];
419 }
420 result[i] = SkMScalarToScalar(value);
421 }
422 memcpy(dst, result, sizeof(result));
423}
424#endif
425
reed@google.com8260a892011-06-13 14:02:52 +0000426///////////////////////////////////////////////////////////////////////////////
427
428void SkMatrix44::dump() const {
tomhudson@google.com9ac4a892011-06-28 13:53:13 +0000429 static const char* format =
430 "[%g %g %g %g][%g %g %g %g][%g %g %g %g][%g %g %g %g]\n";
reed@google.com8260a892011-06-13 14:02:52 +0000431#if 0
tomhudson@google.com9ac4a892011-06-28 13:53:13 +0000432 SkDebugf(format,
reed@google.com8260a892011-06-13 14:02:52 +0000433 fMat[0][0], fMat[1][0], fMat[2][0], fMat[3][0],
434 fMat[0][1], fMat[1][1], fMat[2][1], fMat[3][1],
435 fMat[0][2], fMat[1][2], fMat[2][2], fMat[3][2],
436 fMat[0][3], fMat[1][3], fMat[2][3], fMat[3][3]);
tomhudson@google.com9ac4a892011-06-28 13:53:13 +0000437#else
438 SkDebugf(format,
439 fMat[0][0], fMat[0][1], fMat[0][2], fMat[0][3],
440 fMat[1][0], fMat[1][1], fMat[1][2], fMat[1][3],
441 fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3],
442 fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]);
reed@google.com8260a892011-06-13 14:02:52 +0000443#endif
444}
445
446///////////////////////////////////////////////////////////////////////////////
447
448static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) {
449 sk_bzero(dst, 16 * sizeof(SkMScalar));
bsalomon@google.com72e49b82011-10-27 21:47:03 +0000450 dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]);
451 dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]);
452 dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]);
453 dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]);
454 dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]);
455 dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]);
reed@google.com8260a892011-06-13 14:02:52 +0000456 dst[2][2] = dst[3][3] = 1;
457}
458
459SkMatrix44::SkMatrix44(const SkMatrix& src) {
460 initFromMatrix(fMat, src);
461}
462
463SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) {
464 initFromMatrix(fMat, src);
jamesr@chromium.orgdeb4c162012-11-29 21:17:16 +0000465 fIdentity = src.isIdentity();
reed@google.com8260a892011-06-13 14:02:52 +0000466 return *this;
467}
468
469SkMatrix44::operator SkMatrix() const {
470 SkMatrix dst;
471 dst.reset(); // setup our perspective correctly for identity
472
bsalomon@google.com72e49b82011-10-27 21:47:03 +0000473 dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]);
474 dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]);
475 dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]);
reed@google.com8260a892011-06-13 14:02:52 +0000476
bsalomon@google.com72e49b82011-10-27 21:47:03 +0000477 dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]);
478 dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]);
479 dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]);
reed@google.com8260a892011-06-13 14:02:52 +0000480
481 return dst;
482}