Bug 542731, Patch C: Clean up nsSVGTransformSMIL* classes. r=roc
authorDaniel Holbert <dholbert@cs.stanford.edu>
Mon, 01 Feb 2010 18:46:13 -0800
changeset 37811 5f645dd4152ad918ee42f7cfd957c4a0aed80624
parent 37810 0a80ce4e66921afd1d6fc9f1a63db803be696269
child 37812 d9afac0e24583c862b617fe1be2362abba2a5461
push id11446
push userdholbert@mozilla.com
push dateTue, 02 Feb 2010 02:47:21 +0000
treeherdermozilla-central@9ade02035cbd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs542731
milestone1.9.3a1pre
Bug 542731, Patch C: Clean up nsSVGTransformSMIL* classes. r=roc
content/svg/content/src/nsSVGTransformSMILAttr.cpp
content/svg/content/src/nsSVGTransformSMILAttr.h
content/svg/content/src/nsSVGTransformSMILType.cpp
content/svg/content/src/nsSVGTransformSMILType.h
--- a/content/svg/content/src/nsSVGTransformSMILAttr.cpp
+++ b/content/svg/content/src/nsSVGTransformSMILAttr.cpp
@@ -45,68 +45,51 @@
 #include "nsSVGMatrix.h"
 #include "nsSMILValue.h"
 #include "nsSMILNullType.h"
 #include "nsISMILAnimationElement.h"
 #include "nsSVGElement.h"
 #include "nsISVGValue.h"
 #include "prdtoa.h"
 
-nsISMILType*
-nsSVGTransformSMILAttr::GetSMILType() const
-{
-  return &nsSVGTransformSMILType::sSingleton;
-}
-
 nsresult
 nsSVGTransformSMILAttr::ValueFromString(const nsAString& aStr,
                                      const nsISMILAnimationElement* aSrcElement,
                                      nsSMILValue& aValue) const
 {
   NS_ENSURE_TRUE(aSrcElement, NS_ERROR_FAILURE);
   NS_ASSERTION(aValue.IsNull(),
     "aValue should have been cleared before calling ValueFromString");
 
-  nsSMILValue val(&nsSVGTransformSMILType::sSingleton);
-  if (val.IsNull())
-    return NS_ERROR_FAILURE;
-
   const nsAttrValue* typeAttr = aSrcElement->GetAnimAttr(nsGkAtoms::type);
-
   const nsIAtom* transformType = typeAttr
                                ? typeAttr->GetAtomValue()
                                : nsGkAtoms::translate;
 
-  nsresult rv = ParseValue(aStr, transformType, val);
-  if (NS_FAILED(rv))
-    return rv;
-
-  aValue = val;
-
-  return NS_OK;
+  ParseValue(aStr, transformType, aValue);
+  return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
 }
 
 nsSMILValue
 nsSVGTransformSMILAttr::GetBaseValue() const
 {
-  nsSVGTransformSMILType *type = &nsSVGTransformSMILType::sSingleton;
-  nsSMILValue val(type);
+  nsSMILValue val(&nsSVGTransformSMILType::sSingleton);
   if (val.IsNull())
-    return val;
+    return val; // Initialization failed
 
   nsIDOMSVGTransformList *list = mVal->mBaseVal.get();
 
   PRUint32 numItems = 0;
   list->GetNumberOfItems(&numItems);
   for (PRUint32 i = 0; i < numItems; i++) {
     nsCOMPtr<nsIDOMSVGTransform> transform;
     nsresult rv = list->GetItem(i, getter_AddRefs(transform));
     if (NS_SUCCEEDED(rv) && transform) {
       rv = AppendSVGTransformToSMILValue(transform.get(), val);
-      NS_ENSURE_SUCCESS(rv,nsSMILValue());
+      NS_ENSURE_SUCCESS(rv, nsSMILValue());
     }
   }
 
   return val;
 }
 
 void
 nsSVGTransformSMILAttr::ClearAnimValue()
@@ -144,88 +127,87 @@ nsSVGTransformSMILAttr::SetAnimValue(con
 
   mVal->DidModify(nsISVGValue::mod_other);
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // Implementation helpers
 
-nsresult
+void
 nsSVGTransformSMILAttr::ParseValue(const nsAString& aSpec,
                                    const nsIAtom* aTransformType,
-                                   nsSMILValue& aResult) const
+                                   nsSMILValue& aResult)
 {
-  nsSVGTransformSMILType* type = &nsSVGTransformSMILType::sSingleton;
-  NS_ASSERTION(
-      type == static_cast<nsSVGTransformSMILType const *>(aResult.mType),
-      "Unexpected type for SMIL value result");
-
-  // Reset the result so we can just append to it
-  nsresult rv = type->Init(aResult);
-  NS_ENSURE_SUCCESS(rv,rv);
+  NS_ASSERTION(aResult.IsNull(), "Unexpected type for SMIL value");
 
   float params[3] = { 0.f };
   PRInt32 numParsed = ParseParameterList(aSpec, params, 3);
   nsSVGSMILTransform::TransformType transformType;
 
   if (aTransformType == nsGkAtoms::translate) {
     // tx [ty=0]
     if (numParsed != 1 && numParsed != 2)
-      return NS_ERROR_FAILURE;
+      return;
     transformType = nsSVGSMILTransform::TRANSFORM_TRANSLATE;
   } else if (aTransformType == nsGkAtoms::scale) {
     // sx [sy=sx]
     if (numParsed != 1 && numParsed != 2)
-      return NS_ERROR_FAILURE;
+      return;
     if (numParsed == 1) {
       params[1] = params[0];
     }
     transformType = nsSVGSMILTransform::TRANSFORM_SCALE;
   } else if (aTransformType == nsGkAtoms::rotate) {
     // r [cx=0 cy=0]
     if (numParsed != 1 && numParsed != 3)
-      return NS_ERROR_FAILURE;
+      return;
     transformType = nsSVGSMILTransform::TRANSFORM_ROTATE;
   } else if (aTransformType == nsGkAtoms::skewX) {
     // x-angle
     if (numParsed != 1)
-      return NS_ERROR_FAILURE;
+      return;
     transformType = nsSVGSMILTransform::TRANSFORM_SKEWX;
   } else if (aTransformType == nsGkAtoms::skewY) {
     // y-angle
     if (numParsed != 1)
-      return NS_ERROR_FAILURE;
+      return;
     transformType = nsSVGSMILTransform::TRANSFORM_SKEWY;
   } else {
-    return NS_ERROR_FAILURE;
+    return;
   }
 
-  return type->AppendTransform(nsSVGSMILTransform(transformType, params),
-                               aResult);
+  nsSMILValue val(&nsSVGTransformSMILType::sSingleton);
+  nsSVGSMILTransform transform(transformType, params);
+  if (NS_FAILED(nsSVGTransformSMILType::AppendTransform(transform, val))) {
+    return;
+  }
+
+  // Success! Initialize our outparam with parsed value.
+  aResult = val;
 }
 
 inline PRBool
-nsSVGTransformSMILAttr::IsSpace(const char c) const
+IsSpace(const char c)
 {
   return (c == 0x9 || c == 0xA || c == 0xD || c == 0x20);
 }
 
 inline void
-nsSVGTransformSMILAttr::SkipWsp(nsACString::const_iterator& aIter,
-                               const nsACString::const_iterator& aIterEnd) const
+SkipWsp(nsACString::const_iterator& aIter,
+        const nsACString::const_iterator& aIterEnd)
 {
   while (aIter != aIterEnd && IsSpace(*aIter))
     ++aIter;
 }
 
 PRInt32
 nsSVGTransformSMILAttr::ParseParameterList(const nsAString& aSpec,
                                            float* aVars,
-                                           PRInt32 aNVars) const
+                                           PRInt32 aNVars)
 {
   NS_ConvertUTF16toUTF8 spec(aSpec);
 
   nsACString::const_iterator start, end;
   spec.BeginReading(start);
   spec.EndReading(end);
 
   SkipWsp(start, end);
@@ -253,19 +235,20 @@ nsSVGTransformSMILAttr::ParseParameterLi
     }
   }
 
   return numArgsFound;
 }
 
 nsresult
 nsSVGTransformSMILAttr::AppendSVGTransformToSMILValue(
-  nsIDOMSVGTransform* aTransform, nsSMILValue& aValue) const
+  nsIDOMSVGTransform* aTransform, nsSMILValue& aValue)
 {
-  nsSVGTransformSMILType* type = &nsSVGTransformSMILType::sSingleton;
+  NS_ASSERTION(aValue.mType == &nsSVGTransformSMILType::sSingleton,
+               "Unexpected type for SMIL value");
 
   PRUint16 svgTransformType = nsIDOMSVGTransform::SVG_TRANSFORM_MATRIX;
   aTransform->GetType(&svgTransformType);
 
   nsCOMPtr<nsIDOMSVGMatrix> matrix;
   nsresult rv = aTransform->GetMatrix(getter_AddRefs(matrix));
   if (NS_FAILED(rv) || !matrix)
     return NS_ERROR_FAILURE;
@@ -323,36 +306,34 @@ nsSVGTransformSMILAttr::AppendSVGTransfo
       {
         float mx[6];
         matrix->GetA(&mx[0]);
         matrix->GetB(&mx[1]);
         matrix->GetC(&mx[2]);
         matrix->GetD(&mx[3]);
         matrix->GetE(&mx[4]);
         matrix->GetF(&mx[5]);
-        rv = type->AppendTransform(nsSVGSMILTransform(mx), aValue);
-        transformType = nsSVGSMILTransform::TRANSFORM_MATRIX;
+        return nsSVGTransformSMILType::AppendTransform(nsSVGSMILTransform(mx),
+                                                       aValue);
       }
-      break;
 
     case nsIDOMSVGTransform::SVG_TRANSFORM_UNKNOWN:
       // If it's 'unknown', it's probably not initialised, so just skip it.
       return NS_OK;
 
     default:
       NS_WARNING("Trying to convert unrecognised SVG transform type");
       return NS_ERROR_FAILURE;
   }
 
-  if (transformType != nsSVGSMILTransform::TRANSFORM_MATRIX) {
-    rv =
-      type->AppendTransform(nsSVGSMILTransform(transformType, params), aValue);
-  }
+  NS_ABORT_IF_FALSE(transformType != nsSVGSMILTransform::TRANSFORM_MATRIX,
+                    "generalized matrix case should have returned above");
 
-  return rv;
+  return nsSVGTransformSMILType::
+    AppendTransform(nsSVGSMILTransform(transformType, params), aValue);
 }
 
 nsresult
 nsSVGTransformSMILAttr::UpdateFromSMILValue(
   nsIDOMSVGTransformList* aTransformList, const nsSMILValue& aValue)
 {
   PRUint32 svgLength = -1;
   aTransformList->GetNumberOfItems(&svgLength);
@@ -391,57 +372,53 @@ nsSVGTransformSMILAttr::UpdateFromSMILVa
   }
 
   return NS_OK;
 }
 
 nsresult
 nsSVGTransformSMILAttr::GetSVGTransformFromSMILValue(
     const nsSVGSMILTransform& aSMILTransform,
-    nsIDOMSVGTransform* aSVGTransform) const
+    nsIDOMSVGTransform* aSVGTransform)
 {
-  nsresult rv = NS_ERROR_FAILURE;
-
   switch (aSMILTransform.mTransformType)
   {
     case nsSVGSMILTransform::TRANSFORM_TRANSLATE:
-      rv = aSVGTransform->SetTranslate(aSMILTransform.mParams[0],
-                                       aSMILTransform.mParams[1]);
-      break;
+      return aSVGTransform->SetTranslate(aSMILTransform.mParams[0],
+                                         aSMILTransform.mParams[1]);
 
     case nsSVGSMILTransform::TRANSFORM_SCALE:
-      rv = aSVGTransform->SetScale(aSMILTransform.mParams[0],
+      return aSVGTransform->SetScale(aSMILTransform.mParams[0],
                                    aSMILTransform.mParams[1]);
-      break;
 
     case nsSVGSMILTransform::TRANSFORM_ROTATE:
-      rv = aSVGTransform->SetRotate(aSMILTransform.mParams[0],
-                                    aSMILTransform.mParams[1],
-                                    aSMILTransform.mParams[2]);
-      break;
+      return aSVGTransform->SetRotate(aSMILTransform.mParams[0],
+                                      aSMILTransform.mParams[1],
+                                      aSMILTransform.mParams[2]);
 
     case nsSVGSMILTransform::TRANSFORM_SKEWX:
-      rv = aSVGTransform->SetSkewX(aSMILTransform.mParams[0]);
-      break;
+      return aSVGTransform->SetSkewX(aSMILTransform.mParams[0]);
 
     case nsSVGSMILTransform::TRANSFORM_SKEWY:
-      rv = aSVGTransform->SetSkewY(aSMILTransform.mParams[0]);
-      break;
+      return aSVGTransform->SetSkewY(aSMILTransform.mParams[0]);
 
     case nsSVGSMILTransform::TRANSFORM_MATRIX:
-      {
-        nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
-        rv = NS_NewSVGMatrix(getter_AddRefs(svgMatrix),
-                             aSMILTransform.mParams[0],
-                             aSMILTransform.mParams[1],
-                             aSMILTransform.mParams[2],
-                             aSMILTransform.mParams[3],
-                             aSMILTransform.mParams[4],
-                             aSMILTransform.mParams[5]);
-        NS_ENSURE_SUCCESS(rv,rv);
-        NS_ENSURE_TRUE(svgMatrix,NS_ERROR_FAILURE);
-        rv = aSVGTransform->SetMatrix(svgMatrix);
-      }
-      break;
+    {
+      nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
+      nsresult rv =
+        NS_NewSVGMatrix(getter_AddRefs(svgMatrix),
+                        aSMILTransform.mParams[0],
+                        aSMILTransform.mParams[1],
+                        aSMILTransform.mParams[2],
+                        aSMILTransform.mParams[3],
+                        aSMILTransform.mParams[4],
+                        aSMILTransform.mParams[5]);
+      NS_ENSURE_SUCCESS(rv, rv);
+      NS_ABORT_IF_FALSE(svgMatrix,
+                        "NS_NewSVGMatrix succeeded, so it should have "
+                        "given us a non-null result");
+      return aSVGTransform->SetMatrix(svgMatrix);
+    }
+    default:
+      NS_WARNING("Unexpected transform type");
+      return NS_ERROR_FAILURE;
   }
-
-  return rv;
 }
--- a/content/svg/content/src/nsSVGTransformSMILAttr.h
+++ b/content/svg/content/src/nsSVGTransformSMILAttr.h
@@ -49,48 +49,40 @@ class nsIDOMSVGTransform;
 class nsIDOMSVGTransformList;
 class nsSVGSMILTransform;
 
 class nsSVGTransformSMILAttr : public nsISMILAttr
 {
 public:
   nsSVGTransformSMILAttr(nsSVGAnimatedTransformList* aTransform,
                          nsSVGElement* aSVGElement)
-    : mVal(aTransform),
-      mSVGElement(aSVGElement) {}
+    : mVal(aTransform) {}
 
   // nsISMILAttr methods
-  virtual nsISMILType* GetSMILType() const;
   virtual nsresult     ValueFromString(const nsAString& aStr,
                                    const nsISMILAnimationElement* aSrcElement,
                                    nsSMILValue& aValue) const;
   virtual nsSMILValue  GetBaseValue() const;
   virtual void         ClearAnimValue();
   virtual nsresult     SetAnimValue(const nsSMILValue& aValue);
 
 protected:
-  nsresult ParseValue(const nsAString& aSpec,
-                      const nsIAtom* aTransformType,
-                      nsSMILValue& aResult) const;
-  PRInt32  ParseParameterList(const nsAString& aSpec, float* aVars,
-                              PRInt32 aNVars) const;
-  PRBool   IsSpace(const char c) const;
-  void     SkipWsp(nsACString::const_iterator& aIter,
-                   const nsACString::const_iterator& aIterEnd) const;
-  nsresult AppendSVGTransformToSMILValue(nsIDOMSVGTransform* transform,
-                                         nsSMILValue& aValue) const;
-  nsresult UpdateFromSMILValue(nsIDOMSVGTransformList* aTransformList,
-                               const nsSMILValue& aValue);
-  nsresult GetSVGTransformFromSMILValue(
-                        const nsSVGSMILTransform& aSMILTransform,
-                        nsIDOMSVGTransform* aSVGTransform) const;
-  already_AddRefed<nsIDOMSVGTransform> GetSVGTransformFromSMILValue(
-                                        const nsSMILValue& aValue) const;
+  static void ParseValue(const nsAString& aSpec,
+                         const nsIAtom* aTransformType,
+                         nsSMILValue& aResult);
+  static PRInt32  ParseParameterList(const nsAString& aSpec, float* aVars,
+                                     PRInt32 aNVars);
+  static nsresult AppendSVGTransformToSMILValue(nsIDOMSVGTransform* transform,
+                                                nsSMILValue& aValue);
+  static nsresult UpdateFromSMILValue(nsIDOMSVGTransformList* aTransformList,
+                                      const nsSMILValue& aValue);
+  static nsresult GetSVGTransformFromSMILValue(
+                    const nsSVGSMILTransform& aSMILTransform,
+                    nsIDOMSVGTransform* aSVGTransform);
 
 private:
   // Raw pointers are OK here because this nsSVGTransformSMILAttr is both
   // created & destroyed during a SMIL sample-step, during which time the DOM
   // isn't modified.
   nsSVGAnimatedTransformList* mVal;
-  nsSVGElement* mSVGElement;
 };
 
 #endif // NS_SVGTRANSFORMSMILATTR_H_
--- a/content/svg/content/src/nsSVGTransformSMILType.cpp
+++ b/content/svg/content/src/nsSVGTransformSMILType.cpp
@@ -37,38 +37,30 @@
 
 #include "nsSVGTransformSMILType.h"
 #include "nsSMILValue.h"
 #include "nsCRT.h"
 #include <math.h>
 
 /*static*/ nsSVGTransformSMILType nsSVGTransformSMILType::sSingleton;
 
+typedef nsTArray<nsSVGSMILTransform> TransformArray;
+
 //----------------------------------------------------------------------
 // nsISMILType implementation
 
 nsresult
 nsSVGTransformSMILType::Init(nsSMILValue &aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this || aValue.IsNull(),
-                  "Unexpected value type");
-  NS_ASSERTION(aValue.mType != this || aValue.mU.mPtr,
-               "Invalid nsSMILValue of SVG transform type: NULL data member");
+  NS_PRECONDITION(aValue.IsNull(), "Unexpected value type");
 
-  if (aValue.mType != this || !aValue.mU.mPtr) {
-    // Different type, or no data member: allocate memory and set type
-    TransformArray* transforms = new TransformArray(1);
-    NS_ENSURE_TRUE(transforms, NS_ERROR_OUT_OF_MEMORY);
-    aValue.mU.mPtr = transforms;
-    aValue.mType = this;
-  } else {
-    // Same type, just set clear
-    TransformArray* transforms = static_cast<TransformArray*>(aValue.mU.mPtr);
-    transforms->Clear();
-  }
+  TransformArray* transforms = new TransformArray(1);
+  NS_ENSURE_TRUE(transforms, NS_ERROR_OUT_OF_MEMORY);
+  aValue.mU.mPtr = transforms;
+  aValue.mType = this;
 
   return NS_OK;
 }
 
 void
 nsSVGTransformSMILType::Destroy(nsSMILValue& aValue) const
 {
   NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type");
@@ -308,49 +300,49 @@ nsSVGTransformSMILType::Interpolate(cons
   NS_ENSURE_TRUE(transform,NS_ERROR_OUT_OF_MEMORY);
 
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // Transform array accessors
 
+// static
 PRUint32
-nsSVGTransformSMILType::GetNumTransforms(const nsSMILValue& aValue) const
+nsSVGTransformSMILType::GetNumTransforms(const nsSMILValue& aValue)
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  NS_PRECONDITION(aValue.mType == &sSingleton, "Unexpected SMIL value type");
 
   const TransformArray& transforms =
     *static_cast<const TransformArray*>(aValue.mU.mPtr);
 
   return transforms.Length();
 }
 
+// static
 const nsSVGSMILTransform*
 nsSVGTransformSMILType::GetTransformAt(PRUint32 aIndex,
-                                       const nsSMILValue& aValue) const
+                                       const nsSMILValue& aValue)
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  NS_PRECONDITION(aValue.mType == &sSingleton, "Unexpected SMIL value type");
 
   const TransformArray& transforms =
     *static_cast<const TransformArray*>(aValue.mU.mPtr);
 
   if (aIndex >= transforms.Length()) {
     NS_ERROR("Attempting to access invalid transform");
     return nsnull;
   }
 
   return &transforms[aIndex];
 }
 
+// static
 nsresult
 nsSVGTransformSMILType::AppendTransform(const nsSVGSMILTransform& aTransform,
-                                        nsSMILValue& aValue) const
+                                        nsSMILValue& aValue)
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  NS_PRECONDITION(aValue.mType == &sSingleton, "Unexpected SMIL value type");
 
   TransformArray& transforms = *static_cast<TransformArray*>(aValue.mU.mPtr);
-
-  nsSVGSMILTransform* transform = transforms.AppendElement(aTransform);
-  NS_ENSURE_TRUE(transform,NS_ERROR_OUT_OF_MEMORY);
-
-  return NS_OK;
+  return transforms.AppendElement(aTransform) ?
+    NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
--- a/content/svg/content/src/nsSVGTransformSMILType.h
+++ b/content/svg/content/src/nsSVGTransformSMILType.h
@@ -117,25 +117,24 @@ public:
                                const nsSMILValue& aValueToAdd) const;
   virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    double& aDistance) const;
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
                                nsSMILValue& aResult) const;
+
   // Transform array accessors
-  PRUint32 GetNumTransforms(const nsSMILValue& aValue) const;
-  const nsSVGSMILTransform* GetTransformAt(PRUint32 aIndex,
-                                           const nsSMILValue& aValue) const;
-  nsresult AppendTransform(const nsSVGSMILTransform& aTransform,
-                           nsSMILValue& aValue) const;
+  static PRUint32 GetNumTransforms(const nsSMILValue& aValue);
+  static const nsSVGSMILTransform* GetTransformAt(PRUint32 aIndex,
+                                                  const nsSMILValue& aValue);
+  static nsresult AppendTransform(const nsSVGSMILTransform& aTransform,
+                                  nsSMILValue& aValue);
+
 
   static nsSVGTransformSMILType sSingleton;
 
-protected:
-  typedef nsTArray<nsSVGSMILTransform> TransformArray;
-
 private:
   nsSVGTransformSMILType() {}
 };
 
 #endif // NS_SVGTRANSFORMSMILTYPE_H_