gfx/skia/trunk/src/utils/SkMatrix44.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2011 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkMatrix44.h"
    10 static inline bool eq4(const SkMScalar* SK_RESTRICT a,
    11                       const SkMScalar* SK_RESTRICT b) {
    12     return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]) & (a[3] == b[3]);
    13 }
    15 bool SkMatrix44::operator==(const SkMatrix44& other) const {
    16     if (this == &other) {
    17         return true;
    18     }
    20     if (this->isTriviallyIdentity() && other.isTriviallyIdentity()) {
    21         return true;
    22     }
    24     const SkMScalar* SK_RESTRICT a = &fMat[0][0];
    25     const SkMScalar* SK_RESTRICT b = &other.fMat[0][0];
    27 #if 0
    28     for (int i = 0; i < 16; ++i) {
    29         if (a[i] != b[i]) {
    30             return false;
    31         }
    32     }
    33     return true;
    34 #else
    35     // to reduce branch instructions, we compare 4 at a time.
    36     // see bench/Matrix44Bench.cpp for test.
    37     if (!eq4(&a[0], &b[0])) {
    38         return false;
    39     }
    40     if (!eq4(&a[4], &b[4])) {
    41         return false;
    42     }
    43     if (!eq4(&a[8], &b[8])) {
    44         return false;
    45     }
    46     return eq4(&a[12], &b[12]);
    47 #endif
    48 }
    50 ///////////////////////////////////////////////////////////////////////////////
    52 int SkMatrix44::computeTypeMask() const {
    53     unsigned mask = 0;
    55     if (0 != perspX() || 0 != perspY() || 0 != perspZ() || 1 != fMat[3][3]) {
    56         return kTranslate_Mask | kScale_Mask | kAffine_Mask | kPerspective_Mask;
    57     }
    59     if (0 != transX() || 0 != transY() || 0 != transZ()) {
    60         mask |= kTranslate_Mask;
    61     }
    63     if (1 != scaleX() || 1 != scaleY() || 1 != scaleZ()) {
    64         mask |= kScale_Mask;
    65     }
    67     if (0 != fMat[1][0] || 0 != fMat[0][1] || 0 != fMat[0][2] ||
    68         0 != fMat[2][0] || 0 != fMat[1][2] || 0 != fMat[2][1]) {
    69             mask |= kAffine_Mask;
    70     }
    72     return mask;
    73 }
    75 ///////////////////////////////////////////////////////////////////////////////
    77 void SkMatrix44::asColMajorf(float dst[]) const {
    78     const SkMScalar* src = &fMat[0][0];
    79 #ifdef SK_MSCALAR_IS_DOUBLE
    80     for (int i = 0; i < 16; ++i) {
    81         dst[i] = SkMScalarToFloat(src[i]);
    82     }
    83 #elif defined SK_MSCALAR_IS_FLOAT
    84     memcpy(dst, src, 16 * sizeof(float));
    85 #endif
    86 }
    88 void SkMatrix44::asColMajord(double dst[]) const {
    89     const SkMScalar* src = &fMat[0][0];
    90 #ifdef SK_MSCALAR_IS_DOUBLE
    91     memcpy(dst, src, 16 * sizeof(double));
    92 #elif defined SK_MSCALAR_IS_FLOAT
    93     for (int i = 0; i < 16; ++i) {
    94         dst[i] = SkMScalarToDouble(src[i]);
    95     }
    96 #endif
    97 }
    99 void SkMatrix44::asRowMajorf(float dst[]) const {
   100     const SkMScalar* src = &fMat[0][0];
   101     for (int i = 0; i < 4; ++i) {
   102         dst[0] = SkMScalarToFloat(src[0]);
   103         dst[4] = SkMScalarToFloat(src[1]);
   104         dst[8] = SkMScalarToFloat(src[2]);
   105         dst[12] = SkMScalarToFloat(src[3]);
   106         src += 4;
   107         dst += 1;
   108     }
   109 }
   111 void SkMatrix44::asRowMajord(double dst[]) const {
   112     const SkMScalar* src = &fMat[0][0];
   113     for (int i = 0; i < 4; ++i) {
   114         dst[0] = SkMScalarToDouble(src[0]);
   115         dst[4] = SkMScalarToDouble(src[1]);
   116         dst[8] = SkMScalarToDouble(src[2]);
   117         dst[12] = SkMScalarToDouble(src[3]);
   118         src += 4;
   119         dst += 1;
   120     }
   121 }
   123 void SkMatrix44::setColMajorf(const float src[]) {
   124     SkMScalar* dst = &fMat[0][0];
   125 #ifdef SK_MSCALAR_IS_DOUBLE
   126     for (int i = 0; i < 16; ++i) {
   127         dst[i] = SkMScalarToFloat(src[i]);
   128     }
   129 #elif defined SK_MSCALAR_IS_FLOAT
   130     memcpy(dst, src, 16 * sizeof(float));
   131 #endif
   133     this->dirtyTypeMask();
   134 }
   136 void SkMatrix44::setColMajord(const double src[]) {
   137     SkMScalar* dst = &fMat[0][0];
   138 #ifdef SK_MSCALAR_IS_DOUBLE
   139     memcpy(dst, src, 16 * sizeof(double));
   140 #elif defined SK_MSCALAR_IS_FLOAT
   141     for (int i = 0; i < 16; ++i) {
   142         dst[i] = SkDoubleToMScalar(src[i]);
   143     }
   144 #endif
   146     this->dirtyTypeMask();
   147 }
   149 void SkMatrix44::setRowMajorf(const float src[]) {
   150     SkMScalar* dst = &fMat[0][0];
   151     for (int i = 0; i < 4; ++i) {
   152         dst[0] = SkMScalarToFloat(src[0]);
   153         dst[4] = SkMScalarToFloat(src[1]);
   154         dst[8] = SkMScalarToFloat(src[2]);
   155         dst[12] = SkMScalarToFloat(src[3]);
   156         src += 4;
   157         dst += 1;
   158     }
   159     this->dirtyTypeMask();
   160 }
   162 void SkMatrix44::setRowMajord(const double src[]) {
   163     SkMScalar* dst = &fMat[0][0];
   164     for (int i = 0; i < 4; ++i) {
   165         dst[0] = SkDoubleToMScalar(src[0]);
   166         dst[4] = SkDoubleToMScalar(src[1]);
   167         dst[8] = SkDoubleToMScalar(src[2]);
   168         dst[12] = SkDoubleToMScalar(src[3]);
   169         src += 4;
   170         dst += 1;
   171     }
   172     this->dirtyTypeMask();
   173 }
   175 ///////////////////////////////////////////////////////////////////////////////
   177 const SkMatrix44& SkMatrix44::I() {
   178     static const SkMatrix44 gIdentity44(kIdentity_Constructor);
   179     return gIdentity44;
   180 }
   182 void SkMatrix44::setIdentity() {
   183     fMat[0][0] = 1;
   184     fMat[0][1] = 0;
   185     fMat[0][2] = 0;
   186     fMat[0][3] = 0;
   187     fMat[1][0] = 0;
   188     fMat[1][1] = 1;
   189     fMat[1][2] = 0;
   190     fMat[1][3] = 0;
   191     fMat[2][0] = 0;
   192     fMat[2][1] = 0;
   193     fMat[2][2] = 1;
   194     fMat[2][3] = 0;
   195     fMat[3][0] = 0;
   196     fMat[3][1] = 0;
   197     fMat[3][2] = 0;
   198     fMat[3][3] = 1;
   199     this->setTypeMask(kIdentity_Mask);
   200 }
   202 void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
   203                         SkMScalar m10, SkMScalar m11, SkMScalar m12,
   204                         SkMScalar m20, SkMScalar m21, SkMScalar m22) {
   205     fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0;
   206     fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0;
   207     fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0;
   208     fMat[3][0] = 0;   fMat[3][1] = 0;   fMat[3][2] = 0;   fMat[3][3] = 1;
   209     this->dirtyTypeMask();
   210 }
   212 ///////////////////////////////////////////////////////////////////////////////
   214 void SkMatrix44::setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
   215     this->setIdentity();
   217     if (!dx && !dy && !dz) {
   218         return;
   219     }
   221     fMat[3][0] = dx;
   222     fMat[3][1] = dy;
   223     fMat[3][2] = dz;
   224     this->setTypeMask(kTranslate_Mask);
   225 }
   227 void SkMatrix44::preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
   228     if (!dx && !dy && !dz) {
   229         return;
   230     }
   232     for (int i = 0; i < 4; ++i) {
   233         fMat[3][i] = fMat[0][i] * dx + fMat[1][i] * dy + fMat[2][i] * dz + fMat[3][i];
   234     }
   235     this->dirtyTypeMask();
   236 }
   238 void SkMatrix44::postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
   239     if (!dx && !dy && !dz) {
   240         return;
   241     }
   243     if (this->getType() & kPerspective_Mask) {
   244         for (int i = 0; i < 4; ++i) {
   245             fMat[i][0] += fMat[i][3] * dx;
   246             fMat[i][1] += fMat[i][3] * dy;
   247             fMat[i][2] += fMat[i][3] * dz;
   248         }
   249     } else {
   250         fMat[3][0] += dx;
   251         fMat[3][1] += dy;
   252         fMat[3][2] += dz;
   253         this->dirtyTypeMask();
   254     }
   255 }
   257 ///////////////////////////////////////////////////////////////////////////////
   259 void SkMatrix44::setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
   260     this->setIdentity();
   262     if (1 == sx && 1 == sy && 1 == sz) {
   263         return;
   264     }
   266     fMat[0][0] = sx;
   267     fMat[1][1] = sy;
   268     fMat[2][2] = sz;
   269     this->setTypeMask(kScale_Mask);
   270 }
   272 void SkMatrix44::preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
   273     if (1 == sx && 1 == sy && 1 == sz) {
   274         return;
   275     }
   277     // The implementation matrix * pureScale can be shortcut
   278     // by knowing that pureScale components effectively scale
   279     // the columns of the original matrix.
   280     for (int i = 0; i < 4; i++) {
   281         fMat[0][i] *= sx;
   282         fMat[1][i] *= sy;
   283         fMat[2][i] *= sz;
   284     }
   285     this->dirtyTypeMask();
   286 }
   288 void SkMatrix44::postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
   289     if (1 == sx && 1 == sy && 1 == sz) {
   290         return;
   291     }
   293     for (int i = 0; i < 4; i++) {
   294         fMat[i][0] *= sx;
   295         fMat[i][1] *= sy;
   296         fMat[i][2] *= sz;
   297     }
   298     this->dirtyTypeMask();
   299 }
   301 ///////////////////////////////////////////////////////////////////////////////
   303 void SkMatrix44::setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
   304                                 SkMScalar radians) {
   305     double len2 = (double)x * x + (double)y * y + (double)z * z;
   306     if (1 != len2) {
   307         if (0 == len2) {
   308             this->setIdentity();
   309             return;
   310         }
   311         double scale = 1 / sqrt(len2);
   312         x = SkDoubleToMScalar(x * scale);
   313         y = SkDoubleToMScalar(y * scale);
   314         z = SkDoubleToMScalar(z * scale);
   315     }
   316     this->setRotateAboutUnit(x, y, z, radians);
   317 }
   319 void SkMatrix44::setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
   320                                     SkMScalar radians) {
   321     double c = cos(radians);
   322     double s = sin(radians);
   323     double C = 1 - c;
   324     double xs = x * s;
   325     double ys = y * s;
   326     double zs = z * s;
   327     double xC = x * C;
   328     double yC = y * C;
   329     double zC = z * C;
   330     double xyC = x * yC;
   331     double yzC = y * zC;
   332     double zxC = z * xC;
   334     // if you're looking at wikipedia, remember that we're column major.
   335     this->set3x3(SkDoubleToMScalar(x * xC + c),     // scale x
   336                  SkDoubleToMScalar(xyC + zs),       // skew x
   337                  SkDoubleToMScalar(zxC - ys),       // trans x
   339                  SkDoubleToMScalar(xyC - zs),       // skew y
   340                  SkDoubleToMScalar(y * yC + c),     // scale y
   341                  SkDoubleToMScalar(yzC + xs),       // trans y
   343                  SkDoubleToMScalar(zxC + ys),       // persp x
   344                  SkDoubleToMScalar(yzC - xs),       // persp y
   345                  SkDoubleToMScalar(z * zC + c));    // persp 2
   346 }
   348 ///////////////////////////////////////////////////////////////////////////////
   350 static bool bits_isonly(int value, int mask) {
   351     return 0 == (value & ~mask);
   352 }
   354 void SkMatrix44::setConcat(const SkMatrix44& a, const SkMatrix44& b) {
   355     const SkMatrix44::TypeMask a_mask = a.getType();
   356     const SkMatrix44::TypeMask b_mask = b.getType();
   358     if (kIdentity_Mask == a_mask) {
   359         *this = b;
   360         return;
   361     }
   362     if (kIdentity_Mask == b_mask) {
   363         *this = a;
   364         return;
   365     }
   367     bool useStorage = (this == &a || this == &b);
   368     SkMScalar storage[16];
   369     SkMScalar* result = useStorage ? storage : &fMat[0][0];
   371     // Both matrices are at most scale+translate
   372     if (bits_isonly(a_mask | b_mask, kScale_Mask | kTranslate_Mask)) {
   373         result[0] = a.fMat[0][0] * b.fMat[0][0];
   374         result[1] = result[2] = result[3] = result[4] = 0;
   375         result[5] = a.fMat[1][1] * b.fMat[1][1];
   376         result[6] = result[7] = result[8] = result[9] = 0;
   377         result[10] = a.fMat[2][2] * b.fMat[2][2];
   378         result[11] = 0;
   379         result[12] = a.fMat[0][0] * b.fMat[3][0] + a.fMat[3][0];
   380         result[13] = a.fMat[1][1] * b.fMat[3][1] + a.fMat[3][1];
   381         result[14] = a.fMat[2][2] * b.fMat[3][2] + a.fMat[3][2];
   382         result[15] = 1;
   383     } else {
   384         for (int j = 0; j < 4; j++) {
   385             for (int i = 0; i < 4; i++) {
   386                 double value = 0;
   387                 for (int k = 0; k < 4; k++) {
   388                     value += SkMScalarToDouble(a.fMat[k][i]) * b.fMat[j][k];
   389                 }
   390                 *result++ = SkDoubleToMScalar(value);
   391             }
   392         }
   393     }
   395     if (useStorage) {
   396         memcpy(fMat, storage, sizeof(storage));
   397     }
   398     this->dirtyTypeMask();
   399 }
   401 ///////////////////////////////////////////////////////////////////////////////
   403 /** We always perform the calculation in doubles, to avoid prematurely losing
   404     precision along the way. This relies on the compiler automatically
   405     promoting our SkMScalar values to double (if needed).
   406  */
   407 double SkMatrix44::determinant() const {
   408     if (this->isIdentity()) {
   409         return 1;
   410     }
   411     if (this->isScaleTranslate()) {
   412         return fMat[0][0] * fMat[1][1] * fMat[2][2] * fMat[3][3];
   413     }
   415     double a00 = fMat[0][0];
   416     double a01 = fMat[0][1];
   417     double a02 = fMat[0][2];
   418     double a03 = fMat[0][3];
   419     double a10 = fMat[1][0];
   420     double a11 = fMat[1][1];
   421     double a12 = fMat[1][2];
   422     double a13 = fMat[1][3];
   423     double a20 = fMat[2][0];
   424     double a21 = fMat[2][1];
   425     double a22 = fMat[2][2];
   426     double a23 = fMat[2][3];
   427     double a30 = fMat[3][0];
   428     double a31 = fMat[3][1];
   429     double a32 = fMat[3][2];
   430     double a33 = fMat[3][3];
   432     double b00 = a00 * a11 - a01 * a10;
   433     double b01 = a00 * a12 - a02 * a10;
   434     double b02 = a00 * a13 - a03 * a10;
   435     double b03 = a01 * a12 - a02 * a11;
   436     double b04 = a01 * a13 - a03 * a11;
   437     double b05 = a02 * a13 - a03 * a12;
   438     double b06 = a20 * a31 - a21 * a30;
   439     double b07 = a20 * a32 - a22 * a30;
   440     double b08 = a20 * a33 - a23 * a30;
   441     double b09 = a21 * a32 - a22 * a31;
   442     double b10 = a21 * a33 - a23 * a31;
   443     double b11 = a22 * a33 - a23 * a32;
   445     // Calculate the determinant
   446     return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
   447 }
   449 ///////////////////////////////////////////////////////////////////////////////
   451 bool SkMatrix44::invert(SkMatrix44* inverse) const {
   452     if (this->isIdentity()) {
   453         if (inverse) {
   454             inverse->setIdentity();
   455         }
   456         return true;
   457     }
   459     if (this->isTranslate()) {
   460         if (inverse) {
   461             inverse->setTranslate(-fMat[3][0], -fMat[3][1], -fMat[3][2]);
   462         }
   463         return true;
   464     }
   466     if (this->isScaleTranslate()) {
   467         if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) {
   468             return false;
   469         }
   471         if (inverse) {
   472             double invXScale = 1 / fMat[0][0];
   473             double invYScale = 1 / fMat[1][1];
   474             double invZScale = 1 / fMat[2][2];
   476             inverse->fMat[0][0] = invXScale;
   477             inverse->fMat[0][1] = 0;
   478             inverse->fMat[0][2] = 0;
   479             inverse->fMat[0][3] = 0;
   481             inverse->fMat[1][0] = 0;
   482             inverse->fMat[1][1] = invYScale;
   483             inverse->fMat[1][2] = 0;
   484             inverse->fMat[1][3] = 0;
   486             inverse->fMat[2][0] = 0;
   487             inverse->fMat[2][1] = 0;
   488             inverse->fMat[2][2] = invZScale;
   489             inverse->fMat[2][3] = 0;
   491             inverse->fMat[3][0] = -fMat[3][0] * invXScale;
   492             inverse->fMat[3][1] = -fMat[3][1] * invYScale;
   493             inverse->fMat[3][2] = -fMat[3][2] * invZScale;
   494             inverse->fMat[3][3] = 1;
   496             inverse->setTypeMask(this->getType());
   497         }
   499         return true;
   500     }
   502     double a00 = fMat[0][0];
   503     double a01 = fMat[0][1];
   504     double a02 = fMat[0][2];
   505     double a03 = fMat[0][3];
   506     double a10 = fMat[1][0];
   507     double a11 = fMat[1][1];
   508     double a12 = fMat[1][2];
   509     double a13 = fMat[1][3];
   510     double a20 = fMat[2][0];
   511     double a21 = fMat[2][1];
   512     double a22 = fMat[2][2];
   513     double a23 = fMat[2][3];
   514     double a30 = fMat[3][0];
   515     double a31 = fMat[3][1];
   516     double a32 = fMat[3][2];
   517     double a33 = fMat[3][3];
   519     if (!(this->getType() & kPerspective_Mask)) {
   520         // If we know the matrix has no perspective, then the perspective
   521         // component is (0, 0, 0, 1). We can use this information to save a lot
   522         // of arithmetic that would otherwise be spent to compute the inverse
   523         // of a general matrix.
   525         SkASSERT(a03 == 0);
   526         SkASSERT(a13 == 0);
   527         SkASSERT(a23 == 0);
   528         SkASSERT(a33 == 1);
   530         double b00 = a00 * a11 - a01 * a10;
   531         double b01 = a00 * a12 - a02 * a10;
   532         double b03 = a01 * a12 - a02 * a11;
   533         double b06 = a20 * a31 - a21 * a30;
   534         double b07 = a20 * a32 - a22 * a30;
   535         double b08 = a20;
   536         double b09 = a21 * a32 - a22 * a31;
   537         double b10 = a21;
   538         double b11 = a22;
   540         // Calculate the determinant
   541         double det = b00 * b11 - b01 * b10 + b03 * b08;
   543         double invdet = 1.0 / det;
   544         // If det is zero, we want to return false. However, we also want to return false
   545         // if 1/det overflows to infinity (i.e. det is denormalized). Both of these are
   546         // handled by checking that 1/det is finite.
   547         if (!sk_float_isfinite(invdet)) {
   548             return false;
   549         }
   550         if (NULL == inverse) {
   551             return true;
   552         }
   554         b00 *= invdet;
   555         b01 *= invdet;
   556         b03 *= invdet;
   557         b06 *= invdet;
   558         b07 *= invdet;
   559         b08 *= invdet;
   560         b09 *= invdet;
   561         b10 *= invdet;
   562         b11 *= invdet;
   564         inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10);
   565         inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11);
   566         inverse->fMat[0][2] = SkDoubleToMScalar(b03);
   567         inverse->fMat[0][3] = 0;
   568         inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11);
   569         inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08);
   570         inverse->fMat[1][2] = SkDoubleToMScalar(-b01);
   571         inverse->fMat[1][3] = 0;
   572         inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08);
   573         inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10);
   574         inverse->fMat[2][2] = SkDoubleToMScalar(b00);
   575         inverse->fMat[2][3] = 0;
   576         inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06);
   577         inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06);
   578         inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00);
   579         inverse->fMat[3][3] = 1;
   581         inverse->setTypeMask(this->getType());
   582         return true;
   583     }
   585     double b00 = a00 * a11 - a01 * a10;
   586     double b01 = a00 * a12 - a02 * a10;
   587     double b02 = a00 * a13 - a03 * a10;
   588     double b03 = a01 * a12 - a02 * a11;
   589     double b04 = a01 * a13 - a03 * a11;
   590     double b05 = a02 * a13 - a03 * a12;
   591     double b06 = a20 * a31 - a21 * a30;
   592     double b07 = a20 * a32 - a22 * a30;
   593     double b08 = a20 * a33 - a23 * a30;
   594     double b09 = a21 * a32 - a22 * a31;
   595     double b10 = a21 * a33 - a23 * a31;
   596     double b11 = a22 * a33 - a23 * a32;
   598     // Calculate the determinant
   599     double det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
   601     double invdet = 1.0 / det;
   602     // If det is zero, we want to return false. However, we also want to return false
   603     // if 1/det overflows to infinity (i.e. det is denormalized). Both of these are
   604     // handled by checking that 1/det is finite.
   605     if (!sk_float_isfinite(invdet)) {
   606         return false;
   607     }
   608     if (NULL == inverse) {
   609         return true;
   610     }
   612     b00 *= invdet;
   613     b01 *= invdet;
   614     b02 *= invdet;
   615     b03 *= invdet;
   616     b04 *= invdet;
   617     b05 *= invdet;
   618     b06 *= invdet;
   619     b07 *= invdet;
   620     b08 *= invdet;
   621     b09 *= invdet;
   622     b10 *= invdet;
   623     b11 *= invdet;
   625     inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11 - a12 * b10 + a13 * b09);
   626     inverse->fMat[0][1] = SkDoubleToMScalar(a02 * b10 - a01 * b11 - a03 * b09);
   627     inverse->fMat[0][2] = SkDoubleToMScalar(a31 * b05 - a32 * b04 + a33 * b03);
   628     inverse->fMat[0][3] = SkDoubleToMScalar(a22 * b04 - a21 * b05 - a23 * b03);
   629     inverse->fMat[1][0] = SkDoubleToMScalar(a12 * b08 - a10 * b11 - a13 * b07);
   630     inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11 - a02 * b08 + a03 * b07);
   631     inverse->fMat[1][2] = SkDoubleToMScalar(a32 * b02 - a30 * b05 - a33 * b01);
   632     inverse->fMat[1][3] = SkDoubleToMScalar(a20 * b05 - a22 * b02 + a23 * b01);
   633     inverse->fMat[2][0] = SkDoubleToMScalar(a10 * b10 - a11 * b08 + a13 * b06);
   634     inverse->fMat[2][1] = SkDoubleToMScalar(a01 * b08 - a00 * b10 - a03 * b06);
   635     inverse->fMat[2][2] = SkDoubleToMScalar(a30 * b04 - a31 * b02 + a33 * b00);
   636     inverse->fMat[2][3] = SkDoubleToMScalar(a21 * b02 - a20 * b04 - a23 * b00);
   637     inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07 - a10 * b09 - a12 * b06);
   638     inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09 - a01 * b07 + a02 * b06);
   639     inverse->fMat[3][2] = SkDoubleToMScalar(a31 * b01 - a30 * b03 - a32 * b00);
   640     inverse->fMat[3][3] = SkDoubleToMScalar(a20 * b03 - a21 * b01 + a22 * b00);
   641     inverse->dirtyTypeMask();
   643     return true;
   644 }
   646 ///////////////////////////////////////////////////////////////////////////////
   648 void SkMatrix44::transpose() {
   649     SkTSwap(fMat[0][1], fMat[1][0]);
   650     SkTSwap(fMat[0][2], fMat[2][0]);
   651     SkTSwap(fMat[0][3], fMat[3][0]);
   652     SkTSwap(fMat[1][2], fMat[2][1]);
   653     SkTSwap(fMat[1][3], fMat[3][1]);
   654     SkTSwap(fMat[2][3], fMat[3][2]);
   656     if (!this->isTriviallyIdentity()) {
   657         this->dirtyTypeMask();
   658     }
   659 }
   661 ///////////////////////////////////////////////////////////////////////////////
   663 void SkMatrix44::mapScalars(const SkScalar src[4], SkScalar dst[4]) const {
   664     SkScalar storage[4];
   665     SkScalar* result = (src == dst) ? storage : dst;
   667     for (int i = 0; i < 4; i++) {
   668         SkMScalar value = 0;
   669         for (int j = 0; j < 4; j++) {
   670             value += fMat[j][i] * src[j];
   671         }
   672         result[i] = SkMScalarToScalar(value);
   673     }
   675     if (storage == result) {
   676         memcpy(dst, storage, sizeof(storage));
   677     }
   678 }
   680 #ifdef SK_MSCALAR_IS_DOUBLE
   682 void SkMatrix44::mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const {
   683     SkMScalar storage[4];
   684     SkMScalar* result = (src == dst) ? storage : dst;
   686     for (int i = 0; i < 4; i++) {
   687         SkMScalar value = 0;
   688         for (int j = 0; j < 4; j++) {
   689             value += fMat[j][i] * src[j];
   690         }
   691         result[i] = value;
   692     }
   694     if (storage == result) {
   695         memcpy(dst, storage, sizeof(storage));
   696     }
   697 }
   699 #endif
   701 typedef void (*Map2Procf)(const SkMScalar mat[][4], const float src2[], int count, float dst4[]);
   702 typedef void (*Map2Procd)(const SkMScalar mat[][4], const double src2[], int count, double dst4[]);
   704 static void map2_if(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
   705                     int count, float* SK_RESTRICT dst4) {
   706     for (int i = 0; i < count; ++i) {
   707         dst4[0] = src2[0];
   708         dst4[1] = src2[1];
   709         dst4[2] = 0;
   710         dst4[3] = 1;
   711         src2 += 2;
   712         dst4 += 4;
   713     }
   714 }
   716 static void map2_id(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
   717                     int count, double* SK_RESTRICT dst4) {
   718     for (int i = 0; i < count; ++i) {
   719         dst4[0] = src2[0];
   720         dst4[1] = src2[1];
   721         dst4[2] = 0;
   722         dst4[3] = 1;
   723         src2 += 2;
   724         dst4 += 4;
   725     }
   726 }
   728 static void map2_tf(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
   729                     int count, float* SK_RESTRICT dst4) {
   730     const float mat30 = SkMScalarToFloat(mat[3][0]);
   731     const float mat31 = SkMScalarToFloat(mat[3][1]);
   732     const float mat32 = SkMScalarToFloat(mat[3][2]);
   733     for (int n = 0; n < count; ++n) {
   734         dst4[0] = src2[0] + mat30;
   735         dst4[1] = src2[1] + mat31;
   736         dst4[2] = mat32;
   737         dst4[3] = 1;
   738         src2 += 2;
   739         dst4 += 4;
   740     }
   741 }
   743 static void map2_td(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
   744                     int count, double* SK_RESTRICT dst4) {
   745     for (int n = 0; n < count; ++n) {
   746         dst4[0] = src2[0] + mat[3][0];
   747         dst4[1] = src2[1] + mat[3][1];
   748         dst4[2] = mat[3][2];
   749         dst4[3] = 1;
   750         src2 += 2;
   751         dst4 += 4;
   752     }
   753 }
   755 static void map2_sf(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
   756                     int count, float* SK_RESTRICT dst4) {
   757     const float mat32 = SkMScalarToFloat(mat[3][2]);
   758     for (int n = 0; n < count; ++n) {
   759         dst4[0] = SkMScalarToFloat(mat[0][0] * src2[0] + mat[3][0]);
   760         dst4[1] = SkMScalarToFloat(mat[1][1] * src2[1] + mat[3][1]);
   761         dst4[2] = mat32;
   762         dst4[3] = 1;
   763         src2 += 2;
   764         dst4 += 4;
   765     }
   766 }
   768 static void map2_sd(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
   769                     int count, double* SK_RESTRICT dst4) {
   770     for (int n = 0; n < count; ++n) {
   771         dst4[0] = mat[0][0] * src2[0] + mat[3][0];
   772         dst4[1] = mat[1][1] * src2[1] + mat[3][1];
   773         dst4[2] = mat[3][2];
   774         dst4[3] = 1;
   775         src2 += 2;
   776         dst4 += 4;
   777     }
   778 }
   780 static void map2_af(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
   781                     int count, float* SK_RESTRICT dst4) {
   782     SkMScalar r;
   783     for (int n = 0; n < count; ++n) {
   784         SkMScalar sx = SkFloatToMScalar(src2[0]);
   785         SkMScalar sy = SkFloatToMScalar(src2[1]);
   786         r = mat[0][0] * sx + mat[1][0] * sy + mat[3][0];
   787         dst4[0] = SkMScalarToFloat(r);
   788         r = mat[0][1] * sx + mat[1][1] * sy + mat[3][1];
   789         dst4[1] = SkMScalarToFloat(r);
   790         r = mat[0][2] * sx + mat[1][2] * sy + mat[3][2];
   791         dst4[2] = SkMScalarToFloat(r);
   792         dst4[3] = 1;
   793         src2 += 2;
   794         dst4 += 4;
   795     }
   796 }
   798 static void map2_ad(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
   799                     int count, double* SK_RESTRICT dst4) {
   800     for (int n = 0; n < count; ++n) {
   801         double sx = src2[0];
   802         double sy = src2[1];
   803         dst4[0] = mat[0][0] * sx + mat[1][0] * sy + mat[3][0];
   804         dst4[1] = mat[0][1] * sx + mat[1][1] * sy + mat[3][1];
   805         dst4[2] = mat[0][2] * sx + mat[1][2] * sy + mat[3][2];
   806         dst4[3] = 1;
   807         src2 += 2;
   808         dst4 += 4;
   809     }
   810 }
   812 static void map2_pf(const SkMScalar mat[][4], const float* SK_RESTRICT src2,
   813                     int count, float* SK_RESTRICT dst4) {
   814     SkMScalar r;
   815     for (int n = 0; n < count; ++n) {
   816         SkMScalar sx = SkFloatToMScalar(src2[0]);
   817         SkMScalar sy = SkFloatToMScalar(src2[1]);
   818         for (int i = 0; i < 4; i++) {
   819             r = mat[0][i] * sx + mat[1][i] * sy + mat[3][i];
   820             dst4[i] = SkMScalarToFloat(r);
   821         }
   822         src2 += 2;
   823         dst4 += 4;
   824     }
   825 }
   827 static void map2_pd(const SkMScalar mat[][4], const double* SK_RESTRICT src2,
   828                     int count, double* SK_RESTRICT dst4) {
   829     for (int n = 0; n < count; ++n) {
   830         double sx = src2[0];
   831         double sy = src2[1];
   832         for (int i = 0; i < 4; i++) {
   833             dst4[i] = mat[0][i] * sx + mat[1][i] * sy + mat[3][i];
   834         }
   835         src2 += 2;
   836         dst4 += 4;
   837     }
   838 }
   840 void SkMatrix44::map2(const float src2[], int count, float dst4[]) const {
   841     static const Map2Procf gProc[] = {
   842         map2_if, map2_tf, map2_sf, map2_sf, map2_af, map2_af, map2_af, map2_af
   843     };
   845     TypeMask mask = this->getType();
   846     Map2Procf proc = (mask & kPerspective_Mask) ? map2_pf : gProc[mask];
   847     proc(fMat, src2, count, dst4);
   848 }
   850 void SkMatrix44::map2(const double src2[], int count, double dst4[]) const {
   851     static const Map2Procd gProc[] = {
   852         map2_id, map2_td, map2_sd, map2_sd, map2_ad, map2_ad, map2_ad, map2_ad
   853     };
   855     TypeMask mask = this->getType();
   856     Map2Procd proc = (mask & kPerspective_Mask) ? map2_pd : gProc[mask];
   857     proc(fMat, src2, count, dst4);
   858 }
   860 ///////////////////////////////////////////////////////////////////////////////
   862 void SkMatrix44::dump() const {
   863     static const char* format =
   864         "[%g %g %g %g][%g %g %g %g][%g %g %g %g][%g %g %g %g]\n";
   865 #if 0
   866     SkDebugf(format,
   867              fMat[0][0], fMat[1][0], fMat[2][0], fMat[3][0],
   868              fMat[0][1], fMat[1][1], fMat[2][1], fMat[3][1],
   869              fMat[0][2], fMat[1][2], fMat[2][2], fMat[3][2],
   870              fMat[0][3], fMat[1][3], fMat[2][3], fMat[3][3]);
   871 #else
   872     SkDebugf(format,
   873              fMat[0][0], fMat[0][1], fMat[0][2], fMat[0][3],
   874              fMat[1][0], fMat[1][1], fMat[1][2], fMat[1][3],
   875              fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3],
   876              fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]);
   877 #endif
   878 }
   880 ///////////////////////////////////////////////////////////////////////////////
   882 static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) {
   883     dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]);
   884     dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]);
   885     dst[2][0] = 0;
   886     dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]);
   887     dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]);
   888     dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]);
   889     dst[2][1] = 0;
   890     dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]);
   891     dst[0][2] = 0;
   892     dst[1][2] = 0;
   893     dst[2][2] = 1;
   894     dst[3][2] = 0;
   895     dst[0][3] = SkScalarToMScalar(src[SkMatrix::kMPersp0]);
   896     dst[1][3] = SkScalarToMScalar(src[SkMatrix::kMPersp1]);
   897     dst[2][3] = 0;
   898     dst[3][3] = SkScalarToMScalar(src[SkMatrix::kMPersp2]);
   899 }
   901 SkMatrix44::SkMatrix44(const SkMatrix& src) {
   902     initFromMatrix(fMat, src);
   903 }
   905 SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) {
   906     initFromMatrix(fMat, src);
   908     if (src.isIdentity()) {
   909         this->setTypeMask(kIdentity_Mask);
   910     } else {
   911         this->dirtyTypeMask();
   912     }
   913     return *this;
   914 }
   916 SkMatrix44::operator SkMatrix() const {
   917     SkMatrix dst;
   919     dst[SkMatrix::kMScaleX]  = SkMScalarToScalar(fMat[0][0]);
   920     dst[SkMatrix::kMSkewX]  = SkMScalarToScalar(fMat[1][0]);
   921     dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]);
   923     dst[SkMatrix::kMSkewY]  = SkMScalarToScalar(fMat[0][1]);
   924     dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]);
   925     dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]);
   927     dst[SkMatrix::kMPersp0] = SkMScalarToScalar(fMat[0][3]);
   928     dst[SkMatrix::kMPersp1] = SkMScalarToScalar(fMat[1][3]);
   929     dst[SkMatrix::kMPersp2] = SkMScalarToScalar(fMat[3][3]);
   931     return dst;
   932 }

mercurial