LCOV - code coverage report
Current view: top level - dom/base - DOMMatrix.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 358 0.3 %
Date: 2017-07-14 16:53:18 Functions: 2 52 3.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/dom/BindingUtils.h"
       8             : #include "mozilla/dom/DOMMatrixBinding.h"
       9             : #include "mozilla/dom/DOMPointBinding.h"
      10             : #include "mozilla/dom/BindingDeclarations.h"
      11             : #include "mozilla/dom/ToJSValue.h"
      12             : 
      13             : #include "mozilla/dom/DOMPoint.h"
      14             : #include "mozilla/dom/DOMMatrix.h"
      15             : 
      16             : #include "SVGTransformListParser.h"
      17             : #include "SVGTransform.h"
      18             : 
      19             : #include <math.h>
      20             : 
      21             : namespace mozilla {
      22             : namespace dom {
      23             : 
      24             : static const double radPerDegree = 2.0 * M_PI / 360.0;
      25             : 
      26           0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMMatrixReadOnly, mParent)
      27             : 
      28           0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMatrixReadOnly, AddRef)
      29           0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMatrixReadOnly, Release)
      30             : 
      31             : already_AddRefed<DOMMatrix>
      32           0 : DOMMatrixReadOnly::Translate(double aTx,
      33             :                              double aTy,
      34             :                              double aTz) const
      35             : {
      36           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
      37           0 :   retval->TranslateSelf(aTx, aTy, aTz);
      38             : 
      39           0 :   return retval.forget();
      40             : }
      41             : 
      42             : already_AddRefed<DOMMatrix>
      43           0 : DOMMatrixReadOnly::Scale(double aScale,
      44             :                          double aOriginX,
      45             :                          double aOriginY) const
      46             : {
      47           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
      48           0 :   retval->ScaleSelf(aScale, aOriginX, aOriginY);
      49             : 
      50           0 :   return retval.forget();
      51             : }
      52             : 
      53             : already_AddRefed<DOMMatrix>
      54           0 : DOMMatrixReadOnly::Scale3d(double aScale,
      55             :                            double aOriginX,
      56             :                            double aOriginY,
      57             :                            double aOriginZ) const
      58             : {
      59           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
      60           0 :   retval->Scale3dSelf(aScale, aOriginX, aOriginY, aOriginZ);
      61             : 
      62           0 :   return retval.forget();
      63             : }
      64             : 
      65             : already_AddRefed<DOMMatrix>
      66           0 : DOMMatrixReadOnly::ScaleNonUniform(double aScaleX,
      67             :                                    double aScaleY,
      68             :                                    double aScaleZ,
      69             :                                    double aOriginX,
      70             :                                    double aOriginY,
      71             :                                    double aOriginZ) const
      72             : {
      73           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
      74           0 :   retval->ScaleNonUniformSelf(aScaleX, aScaleY, aScaleZ, aOriginX, aOriginY, aOriginZ);
      75             : 
      76           0 :   return retval.forget();
      77             : }
      78             : 
      79             : already_AddRefed<DOMMatrix>
      80           0 : DOMMatrixReadOnly::Rotate(double aAngle,
      81             :                           double aOriginX ,
      82             :                           double aOriginY) const
      83             : {
      84           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
      85           0 :   retval->RotateSelf(aAngle, aOriginX, aOriginY);
      86             : 
      87           0 :   return retval.forget();
      88             : }
      89             : 
      90             : already_AddRefed<DOMMatrix>
      91           0 : DOMMatrixReadOnly::RotateFromVector(double x,
      92             :                                     double y) const
      93             : {
      94           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
      95           0 :   retval->RotateFromVectorSelf(x, y);
      96             : 
      97           0 :   return retval.forget();
      98             : }
      99             : 
     100             : already_AddRefed<DOMMatrix>
     101           0 : DOMMatrixReadOnly::RotateAxisAngle(double aX,
     102             :                                    double aY,
     103             :                                    double aZ,
     104             :                                    double aAngle) const
     105             : {
     106           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
     107           0 :   retval->RotateAxisAngleSelf(aX, aY, aZ, aAngle);
     108             : 
     109           0 :   return retval.forget();
     110             : }
     111             : 
     112             : already_AddRefed<DOMMatrix>
     113           0 : DOMMatrixReadOnly::SkewX(double aSx) const
     114             : {
     115           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
     116           0 :   retval->SkewXSelf(aSx);
     117             : 
     118           0 :   return retval.forget();
     119             : }
     120             : 
     121             : already_AddRefed<DOMMatrix>
     122           0 : DOMMatrixReadOnly::SkewY(double aSy) const
     123             : {
     124           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
     125           0 :   retval->SkewYSelf(aSy);
     126             : 
     127           0 :   return retval.forget();
     128             : }
     129             : 
     130             : already_AddRefed<DOMMatrix>
     131           0 : DOMMatrixReadOnly::Multiply(const DOMMatrix& other) const
     132             : {
     133           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
     134           0 :   retval->MultiplySelf(other);
     135             : 
     136           0 :   return retval.forget();
     137             : }
     138             : 
     139             : already_AddRefed<DOMMatrix>
     140           0 : DOMMatrixReadOnly::FlipX() const
     141             : {
     142           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
     143           0 :   if (mMatrix3D) {
     144           0 :     gfx::Matrix4x4 m;
     145           0 :     m._11 = -1;
     146           0 :     retval->mMatrix3D = new gfx::Matrix4x4(m * *mMatrix3D);
     147             :   } else {
     148           0 :     gfx::Matrix m;
     149           0 :     m._11 = -1;
     150           0 :     retval->mMatrix2D = new gfx::Matrix(mMatrix2D ? m * *mMatrix2D : m);
     151             :   }
     152             : 
     153           0 :   return retval.forget();
     154             : }
     155             : 
     156             : already_AddRefed<DOMMatrix>
     157           0 : DOMMatrixReadOnly::FlipY() const
     158             : {
     159           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
     160           0 :   if (mMatrix3D) {
     161           0 :     gfx::Matrix4x4 m;
     162           0 :     m._22 = -1;
     163           0 :     retval->mMatrix3D = new gfx::Matrix4x4(m * *mMatrix3D);
     164             :   } else {
     165           0 :     gfx::Matrix m;
     166           0 :     m._22 = -1;
     167           0 :     retval->mMatrix2D = new gfx::Matrix(mMatrix2D ? m * *mMatrix2D : m);
     168             :   }
     169             : 
     170           0 :   return retval.forget();
     171             : }
     172             : 
     173             : already_AddRefed<DOMMatrix>
     174           0 : DOMMatrixReadOnly::Inverse() const
     175             : {
     176           0 :   RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
     177           0 :   retval->InvertSelf();
     178             : 
     179           0 :   return retval.forget();
     180             : }
     181             : 
     182             : bool
     183           0 : DOMMatrixReadOnly::Is2D() const
     184             : {
     185           0 :   return !mMatrix3D;
     186             : }
     187             : 
     188             : bool
     189           0 : DOMMatrixReadOnly::Identity() const
     190             : {
     191           0 :   if (mMatrix3D) {
     192           0 :     return mMatrix3D->IsIdentity();
     193             :   }
     194             : 
     195           0 :   return mMatrix2D->IsIdentity();
     196             : }
     197             : 
     198             : already_AddRefed<DOMPoint>
     199           0 : DOMMatrixReadOnly::TransformPoint(const DOMPointInit& point) const
     200             : {
     201           0 :   RefPtr<DOMPoint> retval = new DOMPoint(mParent);
     202             : 
     203           0 :   if (mMatrix3D) {
     204           0 :     gfx::Point4D transformedPoint;
     205           0 :     transformedPoint.x = point.mX;
     206           0 :     transformedPoint.y = point.mY;
     207           0 :     transformedPoint.z = point.mZ;
     208           0 :     transformedPoint.w = point.mW;
     209             : 
     210           0 :     transformedPoint = mMatrix3D->TransformPoint(transformedPoint);
     211             : 
     212           0 :     retval->SetX(transformedPoint.x);
     213           0 :     retval->SetY(transformedPoint.y);
     214           0 :     retval->SetZ(transformedPoint.z);
     215           0 :     retval->SetW(transformedPoint.w);
     216           0 :   } else if (point.mZ != 0 || point.mW != 1.0) {
     217           0 :     gfx::Matrix4x4 tempMatrix(gfx::Matrix4x4::From2D(*mMatrix2D));
     218             : 
     219           0 :     gfx::Point4D transformedPoint;
     220           0 :     transformedPoint.x = point.mX;
     221           0 :     transformedPoint.y = point.mY;
     222           0 :     transformedPoint.z = point.mZ;
     223           0 :     transformedPoint.w = point.mW;
     224             : 
     225           0 :     transformedPoint = tempMatrix.TransformPoint(transformedPoint);
     226             : 
     227           0 :     retval->SetX(transformedPoint.x);
     228           0 :     retval->SetY(transformedPoint.y);
     229           0 :     retval->SetZ(transformedPoint.z);
     230           0 :     retval->SetW(transformedPoint.w);
     231             :   } else {
     232           0 :     gfx::Point transformedPoint;
     233           0 :     transformedPoint.x = point.mX;
     234           0 :     transformedPoint.y = point.mY;
     235             : 
     236           0 :     transformedPoint = mMatrix2D->TransformPoint(transformedPoint);
     237             : 
     238           0 :     retval->SetX(transformedPoint.x);
     239           0 :     retval->SetY(transformedPoint.y);
     240           0 :     retval->SetZ(point.mZ);
     241           0 :     retval->SetW(point.mW);
     242             :   }
     243           0 :   return retval.forget();
     244             : }
     245             : 
     246           0 : template <typename T> void GetDataFromMatrix(const DOMMatrixReadOnly* aMatrix, T* aData)
     247             : {
     248           0 :   aData[0] = static_cast<T>(aMatrix->M11());
     249           0 :   aData[1] = static_cast<T>(aMatrix->M12());
     250           0 :   aData[2] = static_cast<T>(aMatrix->M13());
     251           0 :   aData[3] = static_cast<T>(aMatrix->M14());
     252           0 :   aData[4] = static_cast<T>(aMatrix->M21());
     253           0 :   aData[5] = static_cast<T>(aMatrix->M22());
     254           0 :   aData[6] = static_cast<T>(aMatrix->M23());
     255           0 :   aData[7] = static_cast<T>(aMatrix->M24());
     256           0 :   aData[8] = static_cast<T>(aMatrix->M31());
     257           0 :   aData[9] = static_cast<T>(aMatrix->M32());
     258           0 :   aData[10] = static_cast<T>(aMatrix->M33());
     259           0 :   aData[11] = static_cast<T>(aMatrix->M34());
     260           0 :   aData[12] = static_cast<T>(aMatrix->M41());
     261           0 :   aData[13] = static_cast<T>(aMatrix->M42());
     262           0 :   aData[14] = static_cast<T>(aMatrix->M43());
     263           0 :   aData[15] = static_cast<T>(aMatrix->M44());
     264           0 : }
     265             : 
     266             : void
     267           0 : DOMMatrixReadOnly::ToFloat32Array(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv) const
     268             : {
     269           0 :   AutoTArray<float, 16> arr;
     270           0 :   arr.SetLength(16);
     271           0 :   GetDataFromMatrix(this, arr.Elements());
     272           0 :   JS::Rooted<JS::Value> value(aCx);
     273           0 :   if (!ToJSValue(aCx, TypedArrayCreator<Float32Array>(arr), &value)) {
     274           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     275           0 :     return;
     276             :   }
     277           0 :   aResult.set(&value.toObject());
     278             : }
     279             : 
     280             : void
     281           0 : DOMMatrixReadOnly::ToFloat64Array(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv) const
     282             : {
     283           0 :   AutoTArray<double, 16> arr;
     284           0 :   arr.SetLength(16);
     285           0 :   GetDataFromMatrix(this, arr.Elements());
     286           0 :   JS::Rooted<JS::Value> value(aCx);
     287           0 :   if (!ToJSValue(aCx, TypedArrayCreator<Float64Array>(arr), &value)) {
     288           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     289           0 :     return;
     290             :   }
     291           0 :   aResult.set(&value.toObject());
     292             : }
     293             : 
     294             : // Convenient way to append things as floats, not doubles.  We use this because
     295             : // we only want to output about 6 digits of precision for our matrix()
     296             : // functions, to preserve the behavior we used to have when we used
     297             : // AppendPrintf.
     298             : static void
     299           0 : AppendFloat(nsAString& aStr, float f)
     300             : {
     301           0 :   aStr.AppendFloat(f);
     302           0 : }
     303             : 
     304             : void
     305           0 : DOMMatrixReadOnly::Stringify(nsAString& aResult)
     306             : {
     307           0 :   nsAutoString matrixStr;
     308           0 :   if (mMatrix3D) {
     309             :     // We can't use AppendPrintf here, because it does locale-specific
     310             :     // formatting of floating-point values.
     311           0 :     matrixStr.AssignLiteral("matrix3d(");
     312           0 :     AppendFloat(matrixStr, M11()); matrixStr.AppendLiteral(", ");
     313           0 :     AppendFloat(matrixStr, M12()); matrixStr.AppendLiteral(", ");
     314           0 :     AppendFloat(matrixStr, M13()); matrixStr.AppendLiteral(", ");
     315           0 :     AppendFloat(matrixStr, M14()); matrixStr.AppendLiteral(", ");
     316           0 :     AppendFloat(matrixStr, M21()); matrixStr.AppendLiteral(", ");
     317           0 :     AppendFloat(matrixStr, M22()); matrixStr.AppendLiteral(", ");
     318           0 :     AppendFloat(matrixStr, M23()); matrixStr.AppendLiteral(", ");
     319           0 :     AppendFloat(matrixStr, M24()); matrixStr.AppendLiteral(", ");
     320           0 :     AppendFloat(matrixStr, M31()); matrixStr.AppendLiteral(", ");
     321           0 :     AppendFloat(matrixStr, M32()); matrixStr.AppendLiteral(", ");
     322           0 :     AppendFloat(matrixStr, M33()); matrixStr.AppendLiteral(", ");
     323           0 :     AppendFloat(matrixStr, M34()); matrixStr.AppendLiteral(", ");
     324           0 :     AppendFloat(matrixStr, M41()); matrixStr.AppendLiteral(", ");
     325           0 :     AppendFloat(matrixStr, M42()); matrixStr.AppendLiteral(", ");
     326           0 :     AppendFloat(matrixStr, M43()); matrixStr.AppendLiteral(", ");
     327           0 :     AppendFloat(matrixStr, M44());
     328           0 :     matrixStr.AppendLiteral(")");
     329             :   } else {
     330             :     // We can't use AppendPrintf here, because it does locale-specific
     331             :     // formatting of floating-point values.
     332           0 :     matrixStr.AssignLiteral("matrix(");
     333           0 :     AppendFloat(matrixStr, A()); matrixStr.AppendLiteral(", ");
     334           0 :     AppendFloat(matrixStr, B()); matrixStr.AppendLiteral(", ");
     335           0 :     AppendFloat(matrixStr, C()); matrixStr.AppendLiteral(", ");
     336           0 :     AppendFloat(matrixStr, D()); matrixStr.AppendLiteral(", ");
     337           0 :     AppendFloat(matrixStr, E()); matrixStr.AppendLiteral(", ");
     338           0 :     AppendFloat(matrixStr, F());
     339           0 :     matrixStr.AppendLiteral(")");
     340             :   }
     341             : 
     342           0 :   aResult = matrixStr;
     343           0 : }
     344             : 
     345             : already_AddRefed<DOMMatrix>
     346           0 : DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
     347             : {
     348           0 :   RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
     349           0 :   return obj.forget();
     350             : }
     351             : 
     352             : already_AddRefed<DOMMatrix>
     353           0 : DOMMatrix::Constructor(const GlobalObject& aGlobal, const nsAString& aTransformList, ErrorResult& aRv)
     354             : {
     355           0 :   RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
     356             : 
     357           0 :   obj = obj->SetMatrixValue(aTransformList, aRv);
     358           0 :   return obj.forget();
     359             : }
     360             : 
     361             : already_AddRefed<DOMMatrix>
     362           0 : DOMMatrix::Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOther, ErrorResult& aRv)
     363             : {
     364           0 :   RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports(), aOther);
     365           0 :   return obj.forget();
     366             : }
     367             : 
     368           0 : template <typename T> void SetDataInMatrix(DOMMatrix* aMatrix, const T* aData, int aLength, ErrorResult& aRv)
     369             : {
     370           0 :   if (aLength == 16) {
     371           0 :     aMatrix->SetM11(aData[0]);
     372           0 :     aMatrix->SetM12(aData[1]);
     373           0 :     aMatrix->SetM13(aData[2]);
     374           0 :     aMatrix->SetM14(aData[3]);
     375           0 :     aMatrix->SetM21(aData[4]);
     376           0 :     aMatrix->SetM22(aData[5]);
     377           0 :     aMatrix->SetM23(aData[6]);
     378           0 :     aMatrix->SetM24(aData[7]);
     379           0 :     aMatrix->SetM31(aData[8]);
     380           0 :     aMatrix->SetM32(aData[9]);
     381           0 :     aMatrix->SetM33(aData[10]);
     382           0 :     aMatrix->SetM34(aData[11]);
     383           0 :     aMatrix->SetM41(aData[12]);
     384           0 :     aMatrix->SetM42(aData[13]);
     385           0 :     aMatrix->SetM43(aData[14]);
     386           0 :     aMatrix->SetM44(aData[15]);
     387           0 :   } else if (aLength == 6) {
     388           0 :     aMatrix->SetA(aData[0]);
     389           0 :     aMatrix->SetB(aData[1]);
     390           0 :     aMatrix->SetC(aData[2]);
     391           0 :     aMatrix->SetD(aData[3]);
     392           0 :     aMatrix->SetE(aData[4]);
     393           0 :     aMatrix->SetF(aData[5]);
     394             :   } else {
     395           0 :     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     396             :   }
     397           0 : }
     398             : 
     399             : already_AddRefed<DOMMatrix>
     400           0 : DOMMatrix::Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv)
     401             : {
     402           0 :   RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
     403           0 :   aArray32.ComputeLengthAndData();
     404           0 :   SetDataInMatrix(obj, aArray32.Data(), aArray32.Length(), aRv);
     405             : 
     406           0 :   return obj.forget();
     407             : }
     408             : 
     409             : already_AddRefed<DOMMatrix>
     410           0 : DOMMatrix::Constructor(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv)
     411             : {
     412           0 :   RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
     413           0 :   aArray64.ComputeLengthAndData();
     414           0 :   SetDataInMatrix(obj, aArray64.Data(), aArray64.Length(), aRv);
     415             : 
     416           0 :   return obj.forget();
     417             : }
     418             : 
     419             : already_AddRefed<DOMMatrix>
     420           0 : DOMMatrix::Constructor(const GlobalObject& aGlobal, const Sequence<double>& aNumberSequence, ErrorResult& aRv)
     421             : {
     422           0 :   RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports());
     423           0 :   SetDataInMatrix(obj, aNumberSequence.Elements(), aNumberSequence.Length(), aRv);
     424             : 
     425           0 :   return obj.forget();
     426             : }
     427             : 
     428           0 : void DOMMatrix::Ensure3DMatrix()
     429             : {
     430           0 :   if (!mMatrix3D) {
     431           0 :     mMatrix3D = new gfx::Matrix4x4(gfx::Matrix4x4::From2D(*mMatrix2D));
     432           0 :     mMatrix2D = nullptr;
     433             :   }
     434           0 : }
     435             : 
     436             : DOMMatrix*
     437           0 : DOMMatrix::MultiplySelf(const DOMMatrix& aOther)
     438             : {
     439           0 :   if (aOther.Identity()) {
     440           0 :     return this;
     441             :   }
     442             : 
     443           0 :   if (aOther.Is2D()) {
     444           0 :     if (mMatrix3D) {
     445           0 :       *mMatrix3D = gfx::Matrix4x4::From2D(*aOther.mMatrix2D) * *mMatrix3D;
     446             :     } else {
     447           0 :       *mMatrix2D = *aOther.mMatrix2D * *mMatrix2D;
     448             :     }
     449             :   } else {
     450           0 :     Ensure3DMatrix();
     451           0 :     *mMatrix3D = *aOther.mMatrix3D * *mMatrix3D;
     452             :   }
     453             : 
     454           0 :   return this;
     455             : }
     456             : 
     457             : DOMMatrix*
     458           0 : DOMMatrix::PreMultiplySelf(const DOMMatrix& aOther)
     459             : {
     460           0 :   if (aOther.Identity()) {
     461           0 :     return this;
     462             :   }
     463             : 
     464           0 :   if (aOther.Is2D()) {
     465           0 :     if (mMatrix3D) {
     466           0 :       *mMatrix3D = *mMatrix3D * gfx::Matrix4x4::From2D(*aOther.mMatrix2D);
     467             :     } else {
     468           0 :       *mMatrix2D = *mMatrix2D * *aOther.mMatrix2D;
     469             :     }
     470             :   } else {
     471           0 :     Ensure3DMatrix();
     472           0 :     *mMatrix3D = *mMatrix3D * *aOther.mMatrix3D;
     473             :   }
     474             : 
     475           0 :   return this;
     476             : }
     477             : 
     478             : DOMMatrix*
     479           0 : DOMMatrix::TranslateSelf(double aTx,
     480             :                          double aTy,
     481             :                          double aTz)
     482             : {
     483           0 :   if (aTx == 0 && aTy == 0 && aTz == 0) {
     484           0 :     return this;
     485             :   }
     486             : 
     487           0 :   if (mMatrix3D || aTz != 0) {
     488           0 :     Ensure3DMatrix();
     489           0 :     mMatrix3D->PreTranslate(aTx, aTy, aTz);
     490             :   } else {
     491           0 :     mMatrix2D->PreTranslate(aTx, aTy);
     492             :   }
     493             : 
     494           0 :   return this;
     495             : }
     496             : 
     497             : DOMMatrix*
     498           0 : DOMMatrix::ScaleSelf(double aScale, double aOriginX, double aOriginY)
     499             : {
     500           0 :   ScaleNonUniformSelf(aScale, aScale, 1.0, aOriginX, aOriginY, 0);
     501             : 
     502           0 :   return this;
     503             : }
     504             : 
     505             : DOMMatrix*
     506           0 : DOMMatrix::Scale3dSelf(double aScale, double aOriginX,
     507             :                        double aOriginY, double aOriginZ)
     508             : {
     509           0 :   ScaleNonUniformSelf(aScale, aScale, aScale, aOriginX, aOriginY, aOriginZ);
     510             : 
     511           0 :   return this;
     512             : }
     513             : 
     514             : DOMMatrix*
     515           0 : DOMMatrix::ScaleNonUniformSelf(double aScaleX,
     516             :                                double aScaleY,
     517             :                                double aScaleZ,
     518             :                                double aOriginX,
     519             :                                double aOriginY,
     520             :                                double aOriginZ)
     521             : {
     522           0 :   if (aScaleX == 1.0 && aScaleY == 1.0 && aScaleZ == 1.0) {
     523           0 :     return this;
     524             :   }
     525             : 
     526           0 :   TranslateSelf(aOriginX, aOriginY, aOriginZ);
     527             : 
     528           0 :   if (mMatrix3D || aScaleZ != 1.0 || aOriginZ != 0) {
     529           0 :     Ensure3DMatrix();
     530           0 :     gfx::Matrix4x4 m;
     531           0 :     m._11 = aScaleX;
     532           0 :     m._22 = aScaleY;
     533           0 :     m._33 = aScaleZ;
     534           0 :     *mMatrix3D = m * *mMatrix3D;
     535             :   } else {
     536           0 :     gfx::Matrix m;
     537           0 :     m._11 = aScaleX;
     538           0 :     m._22 = aScaleY;
     539           0 :     *mMatrix2D = m * *mMatrix2D;
     540             :   }
     541             : 
     542           0 :   TranslateSelf(-aOriginX, -aOriginY, -aOriginZ);
     543             : 
     544           0 :   return this;
     545             : }
     546             : 
     547             : DOMMatrix*
     548           0 : DOMMatrix::RotateFromVectorSelf(double aX, double aY)
     549             : {
     550           0 :   if (aX == 0.0 || aY == 0.0) {
     551           0 :     return this;
     552             :   }
     553             : 
     554           0 :   RotateSelf(atan2(aY, aX) / radPerDegree);
     555             : 
     556           0 :   return this;
     557             : }
     558             : 
     559             : DOMMatrix*
     560           0 : DOMMatrix::RotateSelf(double aAngle, double aOriginX, double aOriginY)
     561             : {
     562           0 :   if (fmod(aAngle, 360) == 0) {
     563           0 :     return this;
     564             :   }
     565             : 
     566           0 :   TranslateSelf(aOriginX, aOriginY);
     567             : 
     568           0 :   if (mMatrix3D) {
     569           0 :     RotateAxisAngleSelf(0, 0, 1, aAngle);
     570             :   } else {
     571           0 :     *mMatrix2D = mMatrix2D->PreRotate(aAngle * radPerDegree);
     572             :   }
     573             : 
     574           0 :   TranslateSelf(-aOriginX, -aOriginY);
     575             : 
     576           0 :   return this;
     577             : }
     578             : 
     579             : DOMMatrix*
     580           0 : DOMMatrix::RotateAxisAngleSelf(double aX, double aY,
     581             :                                double aZ, double aAngle)
     582             : {
     583           0 :   if (fmod(aAngle, 360) == 0) {
     584           0 :     return this;
     585             :   }
     586             : 
     587           0 :   aAngle *= radPerDegree;
     588             : 
     589           0 :   Ensure3DMatrix();
     590           0 :   gfx::Matrix4x4 m;
     591           0 :   m.SetRotateAxisAngle(aX, aY, aZ, aAngle);
     592             : 
     593           0 :   *mMatrix3D = m * *mMatrix3D;
     594             : 
     595           0 :   return this;
     596             : }
     597             : 
     598             : DOMMatrix*
     599           0 : DOMMatrix::SkewXSelf(double aSx)
     600             : {
     601           0 :   if (fmod(aSx, 360) == 0) {
     602           0 :     return this;
     603             :   }
     604             : 
     605           0 :   if (mMatrix3D) {
     606           0 :     gfx::Matrix4x4 m;
     607           0 :     m._21 = tan(aSx * radPerDegree);
     608           0 :     *mMatrix3D = m * *mMatrix3D;
     609             :   } else {
     610           0 :     gfx::Matrix m;
     611           0 :     m._21 = tan(aSx * radPerDegree);
     612           0 :     *mMatrix2D = m * *mMatrix2D;
     613             :   }
     614             : 
     615           0 :   return this;
     616             : }
     617             : 
     618             : DOMMatrix*
     619           0 : DOMMatrix::SkewYSelf(double aSy)
     620             : {
     621           0 :   if (fmod(aSy, 360) == 0) {
     622           0 :     return this;
     623             :   }
     624             : 
     625           0 :   if (mMatrix3D) {
     626           0 :     gfx::Matrix4x4 m;
     627           0 :     m._12 = tan(aSy * radPerDegree);
     628           0 :     *mMatrix3D = m * *mMatrix3D;
     629             :   } else {
     630           0 :     gfx::Matrix m;
     631           0 :     m._12 = tan(aSy * radPerDegree);
     632           0 :     *mMatrix2D = m * *mMatrix2D;
     633             :   }
     634             : 
     635           0 :   return this;
     636             : }
     637             : 
     638             : DOMMatrix*
     639           0 : DOMMatrix::InvertSelf()
     640             : {
     641           0 :   if (mMatrix3D) {
     642           0 :     if (!mMatrix3D->Invert()) {
     643           0 :       mMatrix3D->SetNAN();
     644             :     }
     645           0 :   } else if (!mMatrix2D->Invert()) {
     646           0 :     mMatrix2D = nullptr;
     647             : 
     648           0 :     mMatrix3D = new gfx::Matrix4x4();
     649           0 :     mMatrix3D->SetNAN();
     650             :   }
     651             : 
     652           0 :   return this;
     653             : }
     654             : 
     655             : DOMMatrix*
     656           0 : DOMMatrix::SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv)
     657             : {
     658           0 :   SVGTransformListParser parser(aTransformList);
     659           0 :   if (!parser.Parse()) {
     660           0 :     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     661             :   } else {
     662           0 :     mMatrix3D = nullptr;
     663           0 :     mMatrix2D = new gfx::Matrix();
     664           0 :     gfxMatrix result;
     665           0 :     const nsTArray<nsSVGTransform>& mItems = parser.GetTransformList();
     666             : 
     667           0 :     for (uint32_t i = 0; i < mItems.Length(); ++i) {
     668           0 :       result.PreMultiply(mItems[i].GetMatrix());
     669             :     }
     670             : 
     671           0 :     SetA(result._11);
     672           0 :     SetB(result._12);
     673           0 :     SetC(result._21);
     674           0 :     SetD(result._22);
     675           0 :     SetE(result._31);
     676           0 :     SetF(result._32);
     677             :   }
     678             : 
     679           0 :   return this;
     680             : }
     681             : 
     682             : JSObject*
     683           0 : DOMMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     684             : {
     685           0 :   return DOMMatrixBinding::Wrap(aCx, this, aGivenProto);
     686             : }
     687             : 
     688             : } // namespace dom
     689           9 : } // namespace mozilla

Generated by: LCOV version 1.13