Back to index

lightning-sunbird  0.9+nobinonly
nsSVGMatrix.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Mozilla SVG project.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Crocodile Clips Ltd..
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsSVGMatrix.h"
00040 #include "nsDOMError.h"
00041 #include "nsSVGValue.h"
00042 #include <math.h>
00043 #include "nsContentUtils.h"
00044 
00045 const double radPerDegree = 2.0*3.1415926535 / 360.0;
00046 
00047 class nsSVGMatrix : public nsIDOMSVGMatrix,
00048                     public nsSVGValue
00049 {
00050 public:
00051   nsSVGMatrix(float a, float b, float c, float d, float e, float f);
00052   
00053   // nsISupports interface:
00054   NS_DECL_ISUPPORTS
00055 
00056   // nsIDOMSVGMatrix interface:
00057   NS_DECL_NSIDOMSVGMATRIX
00058 
00059   // nsISVGValue interface:
00060   NS_IMETHOD SetValueString(const nsAString& aValue);
00061   NS_IMETHOD GetValueString(nsAString& aValue);
00062   
00063 protected:
00064   float mA, mB, mC, mD, mE, mF;
00065 };
00066 
00067 //----------------------------------------------------------------------
00068 // Implementation
00069 
00070 nsresult
00071 NS_NewSVGMatrix(nsIDOMSVGMatrix** result,
00072                 float a, float b, float c,
00073                 float d, float e, float f)
00074 {
00075   *result = new nsSVGMatrix(a, b, c, d, e, f);
00076   if (!*result)
00077     return NS_ERROR_OUT_OF_MEMORY;
00078   NS_ADDREF(*result);
00079   return NS_OK;
00080 }
00081 
00082 nsSVGMatrix::nsSVGMatrix(float a, float b, float c,
00083                          float d, float e, float f)
00084   : mA(a), mB(b), mC(c), mD(d), mE(e), mF(f)
00085 {
00086 }
00087 
00088 //----------------------------------------------------------------------
00089 // nsISupports methods:
00090 
00091 NS_IMPL_ADDREF(nsSVGMatrix)
00092 NS_IMPL_RELEASE(nsSVGMatrix)
00093 
00094 NS_INTERFACE_MAP_BEGIN(nsSVGMatrix)
00095   NS_INTERFACE_MAP_ENTRY(nsISVGValue)
00096   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGMatrix)
00097 //  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
00098 //  NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
00099   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGMatrix)
00100   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
00101 NS_INTERFACE_MAP_END
00102 
00103 
00104 //----------------------------------------------------------------------
00105 // nsIDOMSVGMatrix methods:
00106 
00107 /* attribute float a; */
00108 NS_IMETHODIMP nsSVGMatrix::GetA(float *aA)
00109 {
00110   *aA = mA;
00111   return NS_OK;
00112 }
00113 NS_IMETHODIMP nsSVGMatrix::SetA(float aA)
00114 {
00115   WillModify();
00116   mA = aA;
00117   DidModify();
00118   return NS_OK;
00119 }
00120 
00121 /* attribute float b; */
00122 NS_IMETHODIMP nsSVGMatrix::GetB(float *aB)
00123 {
00124   *aB = mB;
00125   return NS_OK;
00126 }
00127 NS_IMETHODIMP nsSVGMatrix::SetB(float aB)
00128 {
00129   WillModify();
00130   mB = aB;
00131   DidModify();
00132   return NS_OK;
00133 }
00134 
00135 /* attribute float c; */
00136 NS_IMETHODIMP nsSVGMatrix::GetC(float *aC)
00137 {
00138   *aC = mC;
00139   return NS_OK;
00140 }
00141 NS_IMETHODIMP nsSVGMatrix::SetC(float aC)
00142 {
00143   WillModify();
00144   mC = aC;
00145   DidModify();
00146   return NS_OK;
00147 }
00148 
00149 /* attribute float d; */
00150 NS_IMETHODIMP nsSVGMatrix::GetD(float *aD)
00151 {
00152   *aD = mD;
00153   return NS_OK;
00154 }
00155 NS_IMETHODIMP nsSVGMatrix::SetD(float aD)
00156 {
00157   WillModify();
00158   mD = aD;
00159   DidModify();
00160   return NS_OK;
00161 }
00162 
00163 /* attribute float e; */
00164 NS_IMETHODIMP nsSVGMatrix::GetE(float *aE)
00165 {
00166   *aE = mE;
00167   return NS_OK;
00168 }
00169 NS_IMETHODIMP nsSVGMatrix::SetE(float aE)
00170 {
00171   WillModify();
00172   mE = aE;
00173   DidModify();
00174   return NS_OK;
00175 }
00176 
00177 /* attribute float f; */
00178 NS_IMETHODIMP nsSVGMatrix::GetF(float *aF)
00179 {
00180   *aF = mF;
00181   return NS_OK;
00182 }
00183 NS_IMETHODIMP nsSVGMatrix::SetF(float aF)
00184 {
00185   WillModify();
00186   mF = aF;
00187   DidModify();
00188   return NS_OK;
00189 }
00190 
00191 /* nsIDOMSVGMatrix multiply (in nsIDOMSVGMatrix secondMatrix); */
00192 NS_IMETHODIMP nsSVGMatrix::Multiply(nsIDOMSVGMatrix *secondMatrix,
00193                                     nsIDOMSVGMatrix **_retval)
00194 {
00195   if (!secondMatrix)
00196     return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
00197 
00198   float sa,sb,sc,sd,se,sf;
00199   secondMatrix->GetA(&sa);
00200   secondMatrix->GetB(&sb);
00201   secondMatrix->GetC(&sc);
00202   secondMatrix->GetD(&sd);
00203   secondMatrix->GetE(&se);
00204   secondMatrix->GetF(&sf);
00205 
00206   return NS_NewSVGMatrix(_retval,
00207                          mA*sa + mC*sb,      mB*sa + mD*sb,
00208                          mA*sc + mC*sd,      mB*sc + mD*sd,
00209                          mA*se + mC*sf + mE, mB*se + mD*sf + mF);
00210 }
00211 
00212 /* nsIDOMSVGMatrix inverse (); */
00213 NS_IMETHODIMP nsSVGMatrix::Inverse(nsIDOMSVGMatrix **_retval)
00214 {
00215   double det = mA*mD - mC*mB;
00216   if (det == 0.0)
00217     return NS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE;
00218 
00219   return NS_NewSVGMatrix(_retval,
00220                          (float)( mD/det),             (float)(-mB/det),
00221                          (float)(-mC/det),             (float)( mA/det),
00222                          (float)((mC*mF - mE*mD)/det), (float)((mE*mB - mA*mF)/det));
00223 }
00224 
00225 /* nsIDOMSVGMatrix translate (in float x, in float y); */
00226 NS_IMETHODIMP nsSVGMatrix::Translate(float x, float y, nsIDOMSVGMatrix **_retval)
00227 {
00228   return NS_NewSVGMatrix(_retval,
00229                          mA,               mB,
00230                          mC,               mD,
00231                          mA*x + mC*y + mE, mB*x + mD*y + mF);
00232 }
00233 
00234 /* nsIDOMSVGMatrix scale (in float scaleFactor); */
00235 NS_IMETHODIMP nsSVGMatrix::Scale(float scaleFactor, nsIDOMSVGMatrix **_retval)
00236 {
00237   return NS_NewSVGMatrix(_retval,
00238                          mA*scaleFactor, mB*scaleFactor,
00239                          mC*scaleFactor, mD*scaleFactor,
00240                          mE,             mF);  
00241 }
00242 
00243 /* nsIDOMSVGMatrix scaleNonUniform (in float scaleFactorX, in float scaleFactorY); */
00244 NS_IMETHODIMP nsSVGMatrix::ScaleNonUniform(float scaleFactorX, float scaleFactorY, nsIDOMSVGMatrix **_retval)
00245 {
00246   return NS_NewSVGMatrix(_retval,
00247                          mA*scaleFactorX, mB*scaleFactorX,
00248                          mC*scaleFactorY, mD*scaleFactorY,
00249                          mE,              mF);  
00250 }
00251 
00252 /* nsIDOMSVGMatrix rotate (in float angle); */
00253 NS_IMETHODIMP nsSVGMatrix::Rotate(float angle, nsIDOMSVGMatrix **_retval)
00254 {
00255   double ca = cos( angle*radPerDegree );
00256   double sa = sin( angle*radPerDegree );
00257   
00258   return NS_NewSVGMatrix(_retval,
00259                          (float) (mA*ca + mC*sa), (float) (mB*ca + mD*sa),
00260                          (float) (mC*ca - mA*sa), (float) (mD*ca - mB*sa),
00261                          mE,                      mF);  
00262 }
00263 
00264 /* nsIDOMSVGMatrix rotateFromVector (in float x, in float y); */
00265 NS_IMETHODIMP nsSVGMatrix::RotateFromVector(float x, float y, nsIDOMSVGMatrix **_retval)
00266 {
00267   NS_NOTYETIMPLEMENTED("nsSVGMatrix::RotateFromVector");
00268   return NS_ERROR_NOT_IMPLEMENTED;
00269 }
00270 
00271 /* nsIDOMSVGMatrix flipX (); */
00272 NS_IMETHODIMP nsSVGMatrix::FlipX(nsIDOMSVGMatrix **_retval)
00273 {
00274   NS_NOTYETIMPLEMENTED("nsSVGMatrix::FlipX");
00275   return NS_ERROR_NOT_IMPLEMENTED;
00276 }
00277 
00278 /* nsIDOMSVGMatrix flipY (); */
00279 NS_IMETHODIMP nsSVGMatrix::FlipY(nsIDOMSVGMatrix **_retval)
00280 {
00281   NS_NOTYETIMPLEMENTED("nsSVGMatrix::FlipY");
00282   return NS_ERROR_NOT_IMPLEMENTED;
00283 }
00284 
00285 /* nsIDOMSVGMatrix skewX (in float angle); */
00286 NS_IMETHODIMP nsSVGMatrix::SkewX(float angle, nsIDOMSVGMatrix **_retval)
00287 {
00288   double ta = tan( angle*radPerDegree );
00289 
00290   return NS_NewSVGMatrix(_retval,
00291                          mA,                    mB,
00292                          (float) ( mC + mA*ta), (float) ( mD + mB*ta),
00293                          mE,                    mF);
00294 }
00295 
00296 /* nsIDOMSVGMatrix skewY (in float angle); */
00297 NS_IMETHODIMP nsSVGMatrix::SkewY(float angle, nsIDOMSVGMatrix **_retval)
00298 {
00299   double ta = tan( angle*radPerDegree );
00300 
00301   return NS_NewSVGMatrix(_retval,
00302                          (float) (mA + mC*ta), (float) (mB + mD*ta),
00303                          mC,                    mD,
00304                          mE,                    mF);
00305 }
00306 
00307 
00308 //----------------------------------------------------------------------
00309 // nsISVGValue methods:
00310 NS_IMETHODIMP
00311 nsSVGMatrix::SetValueString(const nsAString& aValue)
00312 {
00313   NS_NOTYETIMPLEMENTED("nsSVGMatrix::SetValueString");
00314   return NS_ERROR_NOT_IMPLEMENTED;
00315 }
00316 
00317 NS_IMETHODIMP
00318 nsSVGMatrix::GetValueString(nsAString& aValue)
00319 {
00320   NS_NOTYETIMPLEMENTED("nsSVGMatrix::GetValueString");
00321   return NS_ERROR_NOT_IMPLEMENTED;
00322 }