Bug 952977: Switch PrependSVGTransform to gfx::Matrix r=nical
☠☠ backed out by 8eacfa0523bd ☠ ☠
authorDavid Zbarsky <dzbarsky@gmail.com>
Thu, 26 Dec 2013 13:06:54 -0500
changeset 161796 b04bd18e5692e4f86815b6d0652c3843069784d7
parent 161795 4ce43cb764d51b7c7907e6db85848afe22b16f77
child 161797 4a2a444ec574320919843d360535e0c2ee97fd6f
push id25902
push userphilringnalda@gmail.com
push dateFri, 27 Dec 2013 03:30:13 +0000
treeherdermozilla-central@07f7597000b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs952977
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 952977: Switch PrependSVGTransform to gfx::Matrix r=nical
content/svg/content/src/SVGContentUtils.cpp
content/svg/content/src/SVGForeignObjectElement.cpp
content/svg/content/src/SVGForeignObjectElement.h
content/svg/content/src/SVGMotionSMILAttr.cpp
content/svg/content/src/SVGPathElement.cpp
content/svg/content/src/SVGSVGElement.cpp
content/svg/content/src/SVGSVGElement.h
content/svg/content/src/SVGTransformableElement.cpp
content/svg/content/src/SVGTransformableElement.h
content/svg/content/src/SVGUseElement.cpp
content/svg/content/src/SVGUseElement.h
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGAFrame.cpp
layout/svg/nsSVGClipPathFrame.cpp
layout/svg/nsSVGContainerFrame.cpp
layout/svg/nsSVGFilterFrame.cpp
layout/svg/nsSVGForeignObjectFrame.cpp
layout/svg/nsSVGGFrame.cpp
layout/svg/nsSVGInnerSVGFrame.cpp
layout/svg/nsSVGOuterSVGFrame.cpp
layout/svg/nsSVGPathGeometryFrame.cpp
layout/svg/nsSVGSwitchFrame.cpp
layout/svg/nsSVGUtils.cpp
--- a/content/svg/content/src/SVGContentUtils.cpp
+++ b/content/svg/content/src/SVGContentUtils.cpp
@@ -13,16 +13,17 @@
 #include "nsComputedDOMStyle.h"
 #include "nsFontMetrics.h"
 #include "nsIFrame.h"
 #include "nsIScriptError.h"
 #include "nsLayoutUtils.h"
 #include "SVGAnimationElement.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "nsContentUtils.h"
+#include "gfx2DGlue.h"
 #include "mozilla/gfx/2D.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 SVGSVGElement*
 SVGContentUtils::GetOuterSVGElement(nsSVGElement *aSVGElement)
 {
@@ -175,33 +176,33 @@ SVGContentUtils::GetNearestViewportEleme
     element = element->GetFlattenedTreeParent();
   }
   return nullptr;
 }
 
 static gfxMatrix
 GetCTMInternal(nsSVGElement *aElement, bool aScreenCTM, bool aHaveRecursed)
 {
-  gfxMatrix matrix = aElement->PrependLocalTransformsTo(gfxMatrix(),
+  gfx::Matrix matrix = aElement->PrependLocalTransformsTo(gfx::Matrix(),
     aHaveRecursed ? nsSVGElement::eAllTransforms : nsSVGElement::eUserSpaceToParent);
   nsSVGElement *element = aElement;
   nsIContent *ancestor = aElement->GetFlattenedTreeParent();
 
   while (ancestor && ancestor->IsSVG() &&
                      ancestor->Tag() != nsGkAtoms::foreignObject) {
     element = static_cast<nsSVGElement*>(ancestor);
-    matrix *= element->PrependLocalTransformsTo(gfxMatrix()); // i.e. *A*ppend
+    matrix *= element->PrependLocalTransformsTo(gfx::Matrix()); // i.e. *A*ppend
     if (!aScreenCTM && SVGContentUtils::EstablishesViewport(element)) {
       if (!element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG) &&
           !element->NodeInfo()->Equals(nsGkAtoms::symbol, kNameSpaceID_SVG)) {
         NS_ERROR("New (SVG > 1.1) SVG viewport establishing element?");
         return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
       }
       // XXX spec seems to say x,y translation should be undone for IsInnerSVG
-      return matrix;
+      return ThebesMatrix(matrix);
     }
     ancestor = ancestor->GetFlattenedTreeParent();
   }
   if (!aScreenCTM) {
     // didn't find a nearestViewportElement
     return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
   }
   if (element->Tag() != nsGkAtoms::svg) {
@@ -210,24 +211,24 @@ GetCTMInternal(nsSVGElement *aElement, b
   }
   if (element == aElement && !aHaveRecursed) {
     // We get here when getScreenCTM() is called on an outer-<svg>.
     // Consistency with other elements would have us include only the
     // eFromUserSpace transforms, but we include the eAllTransforms
     // transforms in this case since that's what we've been doing for
     // a while, and it keeps us consistent with WebKit and Opera (if not
     // really with the ambiguous spec).
-    matrix = aElement->PrependLocalTransformsTo(gfxMatrix());
+    matrix = aElement->PrependLocalTransformsTo(gfx::Matrix());
   }
   if (!ancestor || !ancestor->IsElement()) {
-    return matrix;
+    return ThebesMatrix(matrix);
   }
   if (ancestor->IsSVG()) {
     return
-      matrix * GetCTMInternal(static_cast<nsSVGElement*>(ancestor), true, true);
+      ThebesMatrix(matrix) * GetCTMInternal(static_cast<nsSVGElement*>(ancestor), true, true);
   }
 
   // XXX this does not take into account CSS transform, or that the non-SVG
   // content that we've hit may itself be inside an SVG foreignObject higher up
   nsIDocument* currentDoc = aElement->GetCurrentDoc();
   float x = 0.0f, y = 0.0f;
   if (currentDoc && element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG)) {
     nsIPresShell *presShell = currentDoc->GetShell();
@@ -236,17 +237,17 @@ GetCTMInternal(nsSVGElement *aElement, b
       nsIFrame* ancestorFrame = presShell->GetRootFrame();
       if (frame && ancestorFrame) {
         nsPoint point = frame->GetOffsetTo(ancestorFrame);
         x = nsPresContext::AppUnitsToFloatCSSPixels(point.x);
         y = nsPresContext::AppUnitsToFloatCSSPixels(point.y);
       }
     }
   }
-  return matrix * gfxMatrix().Translate(gfxPoint(x, y));
+  return ThebesMatrix(matrix * gfx::Matrix().Translate(x, y));
 }
 
 gfxMatrix
 SVGContentUtils::GetCTM(nsSVGElement *aElement, bool aScreenCTM)
 {
   return GetCTMInternal(aElement, aScreenCTM, false);
 }
 
--- a/content/svg/content/src/SVGForeignObjectElement.cpp
+++ b/content/svg/content/src/SVGForeignObjectElement.cpp
@@ -65,34 +65,34 @@ already_AddRefed<SVGAnimatedLength>
 SVGForeignObjectElement::Height()
 {
   return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this);
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
-/* virtual */ gfxMatrix
-SVGForeignObjectElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+/* virtual */ gfx::Matrix
+SVGForeignObjectElement::PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                                                   TransformTypes aWhich) const
 {
   NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
                     "Skipping eUserSpaceToParent transforms makes no sense");
 
   // 'transform' attribute:
-  gfxMatrix fromUserSpace =
+  gfx::Matrix fromUserSpace =
     SVGGraphicsElement::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
   // our 'x' and 'y' attributes:
   float x, y;
   const_cast<SVGForeignObjectElement*>(this)->
     GetAnimatedLengthValues(&x, &y, nullptr);
-  gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
+  gfx::Matrix toUserSpace = gfx::Matrix().Translate(x, y);
   if (aWhich == eChildToUserSpace) {
     return toUserSpace;
   }
   NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
   return toUserSpace * fromUserSpace;
 }
 
 /* virtual */ bool
--- a/content/svg/content/src/SVGForeignObjectElement.h
+++ b/content/svg/content/src/SVGForeignObjectElement.h
@@ -25,17 +25,17 @@ protected:
   friend nsresult (::NS_NewSVGForeignObjectElement(nsIContent **aResult,
                                                    already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGForeignObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsSVGElement specializations:
-  virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+  virtual gfx::Matrix PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
   virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
--- a/content/svg/content/src/SVGMotionSMILAttr.cpp
+++ b/content/svg/content/src/SVGMotionSMILAttr.cpp
@@ -6,16 +6,17 @@
 /* representation of a dummy attribute targeted by <animateMotion> element */
 
 #include "SVGMotionSMILAttr.h"
 #include "SVGMotionSMILType.h"
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "nsSMILValue.h"
 #include "nsDebug.h"
 #include "nsSVGElement.h"
+#include "gfx2DGlue.h"
 
 namespace mozilla {
 
 nsresult
 SVGMotionSMILAttr::ValueFromString(const nsAString& aStr,
                                    const dom::SVGAnimationElement* aSrcElement,
                                    nsSMILValue& aValue,
                                    bool& aPreventCachingOfSandwich) const
@@ -35,17 +36,17 @@ void
 SVGMotionSMILAttr::ClearAnimValue()
 {
   mSVGElement->SetAnimateMotionTransform(nullptr);
 }
 
 nsresult
 SVGMotionSMILAttr::SetAnimValue(const nsSMILValue& aValue)
 {
-  gfxMatrix matrix = SVGMotionSMILType::CreateMatrix(aValue);
+  gfx::Matrix matrix = gfx::ToMatrix(SVGMotionSMILType::CreateMatrix(aValue));
   mSVGElement->SetAnimateMotionTransform(&matrix);
   return NS_OK;
 }
 
 const nsIContent*
 SVGMotionSMILAttr::GetTargetNode() const
 {
   return mSVGElement;
--- a/content/svg/content/src/SVGPathElement.cpp
+++ b/content/svg/content/src/SVGPathElement.cpp
@@ -343,20 +343,19 @@ SVGPathElement::GetPathLengthScale(PathL
     float authorsPathLengthEstimate = mPathLength.GetAnimValue();
     if (authorsPathLengthEstimate > 0) {
       RefPtr<Path> path = GetPathForLengthOrPositionMeasuring();
 
       if (aFor == eForTextPath) {
         // For textPath, a transform on the referenced path affects the
         // textPath layout, so when calculating the actual path length
         // we need to take that into account.
-        gfxMatrix matrix = PrependLocalTransformsTo(gfxMatrix());
+        gfx::Matrix matrix = PrependLocalTransformsTo(gfx::Matrix());
         if (!matrix.IsIdentity()) {
-          RefPtr<PathBuilder> builder =
-            path->TransformedCopyToBuilder(ToMatrix(matrix));
+          RefPtr<PathBuilder> builder = path->TransformedCopyToBuilder(matrix);
           path = builder->Finish();
         }
       }
 
       if (path) {
         return path->ComputeLength() / authorsPathLengthEstimate;
       }
     }
--- a/content/svg/content/src/SVGSVGElement.cpp
+++ b/content/svg/content/src/SVGSVGElement.cpp
@@ -941,50 +941,50 @@ SVGSVGElement::GetLength(uint8_t aCtxTyp
     return float(SVGContentUtils::ComputeNormalizedHypotenuse(w, h));
   }
   return 0;
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
-/* virtual */ gfxMatrix
-SVGSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+/* virtual */ gfx::Matrix
+SVGSVGElement::PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                                         TransformTypes aWhich) const
 {
   NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
                     "Skipping eUserSpaceToParent transforms makes no sense");
 
   // 'transform' attribute:
-  gfxMatrix fromUserSpace =
+  gfx::Matrix fromUserSpace =
     SVGSVGElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
 
   if (IsInner()) {
     float x, y;
     const_cast<SVGSVGElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
     if (aWhich == eAllTransforms) {
       // the common case
-      return GetViewBoxTransform() * gfxMatrix().Translate(gfxPoint(x, y)) * fromUserSpace;
+      return gfx::ToMatrix(GetViewBoxTransform()) * gfx::Matrix().Translate(x, y) * fromUserSpace;
     }
     NS_ABORT_IF_FALSE(aWhich == eChildToUserSpace, "Unknown TransformTypes");
-    return GetViewBoxTransform() * gfxMatrix().Translate(gfxPoint(x, y));
+    return gfx::ToMatrix(GetViewBoxTransform()) * gfx::Matrix().Translate(x, y);
   }
 
   if (IsRoot()) {
-    gfxMatrix zoomPanTM;
-    zoomPanTM.Translate(gfxPoint(mCurrentTranslate.GetX(), mCurrentTranslate.GetY()));
+    gfx::Matrix zoomPanTM;
+    zoomPanTM.Translate(mCurrentTranslate.GetX(), mCurrentTranslate.GetY());
     zoomPanTM.Scale(mCurrentScale, mCurrentScale);
-    return GetViewBoxTransform() * zoomPanTM * fromUserSpace;
+    return gfx::ToMatrix(GetViewBoxTransform()) * zoomPanTM * fromUserSpace;
   }
 
   // outer-<svg>, but inline in some other content:
-  return GetViewBoxTransform() * fromUserSpace;
+  return gfx::ToMatrix(GetViewBoxTransform()) * fromUserSpace;
 }
 
 /* virtual */ bool
 SVGSVGElement::HasValidDimensions() const
 {
   return !IsInner() ||
     ((!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
        mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
--- a/content/svg/content/src/SVGSVGElement.h
+++ b/content/svg/content/src/SVGSVGElement.h
@@ -127,17 +127,17 @@ public:
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
   // nsSVGElement specializations:
-  virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+  virtual gfx::Matrix PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
   virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // SVGSVGElement methods:
   float GetLength(uint8_t mCtxType);
 
   // public helpers:
 
--- a/content/svg/content/src/SVGTransformableElement.cpp
+++ b/content/svg/content/src/SVGTransformableElement.cpp
@@ -80,64 +80,64 @@ bool
 SVGTransformableElement::IsEventAttributeName(nsIAtom* aName)
 {
   return nsContentUtils::IsEventAttributeName(aName, EventNameType_SVGGraphic);
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement overrides
 
-gfxMatrix
-SVGTransformableElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+gfx::Matrix
+SVGTransformableElement::PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                                                   TransformTypes aWhich) const
 {
   NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
                     "Skipping eUserSpaceToParent transforms makes no sense");
 
-  gfxMatrix result(aMatrix);
+  gfx::Matrix result(aMatrix);
 
   if (aWhich == eChildToUserSpace) {
     // We don't have anything to prepend.
     // eChildToUserSpace is not the common case, which is why we return
     // 'result' to benefit from NRVO rather than returning aMatrix before
     // creating 'result'.
     return result;
   }
 
   NS_ABORT_IF_FALSE(aWhich == eAllTransforms || aWhich == eUserSpaceToParent,
                     "Unknown TransformTypes");
 
   // animateMotion's resulting transform is supposed to apply *on top of*
   // any transformations from the |transform| attribute. So since we're
   // PRE-multiplying, we need to apply the animateMotion transform *first*.
   if (mAnimateMotionTransform) {
-    result.PreMultiply(*mAnimateMotionTransform);
+    result = *mAnimateMotionTransform * result;
   }
 
   if (mTransforms) {
-    result.PreMultiply(mTransforms->GetAnimValue().GetConsolidationMatrix());
+    result = gfx::ToMatrix(mTransforms->GetAnimValue().GetConsolidationMatrix()) * result;
   }
 
   return result;
 }
 
-const gfxMatrix*
+const gfx::Matrix*
 SVGTransformableElement::GetAnimateMotionTransform() const
 {
   return mAnimateMotionTransform.get();
 }
 
 void
-SVGTransformableElement::SetAnimateMotionTransform(const gfxMatrix* aMatrix)
+SVGTransformableElement::SetAnimateMotionTransform(const gfx::Matrix* aMatrix)
 {
   if ((!aMatrix && !mAnimateMotionTransform) ||
       (aMatrix && mAnimateMotionTransform && *aMatrix == *mAnimateMotionTransform)) {
     return;
   }
-  mAnimateMotionTransform = aMatrix ? new gfxMatrix(*aMatrix) : nullptr;
+  mAnimateMotionTransform = aMatrix ? new gfx::Matrix(*aMatrix) : nullptr;
   DidAnimateTransformList();
   nsIFrame* frame = GetPrimaryFrame();
   if (frame) {
     // If the result of this transform and any other transforms on this frame
     // is the identity matrix, then DoApplyRenderingChangeToTree won't handle
     // our nsChangeHint_UpdateTransformLayer hint since aFrame->IsTransformed()
     // will return false. That's fine, but we still need to schedule a repaint,
     // and that won't otherwise happen. Since it's cheap to call SchedulePaint,
--- a/content/svg/content/src/SVGTransformableElement.h
+++ b/content/svg/content/src/SVGTransformableElement.h
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SVGTransformableElement_h
 #define SVGTransformableElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsSVGAnimatedTransformList.h"
 #include "nsSVGElement.h"
-#include "gfxMatrix.h"
+#include "mozilla/gfx/Matrix.h"
 
 namespace mozilla {
 namespace dom {
 
 class SVGAnimatedTransformList;
 class SVGGraphicsElement;
 class SVGMatrix;
 class SVGIRect;
@@ -43,35 +43,35 @@ public:
 
   nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                       int32_t aModType) const MOZ_OVERRIDE;
 
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
 
-  virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+  virtual gfx::Matrix PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
-  virtual const gfxMatrix* GetAnimateMotionTransform() const MOZ_OVERRIDE;
-  virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix) MOZ_OVERRIDE;
+  virtual const gfx::Matrix* GetAnimateMotionTransform() const MOZ_OVERRIDE;
+  virtual void SetAnimateMotionTransform(const gfx::Matrix* aMatrix) MOZ_OVERRIDE;
 
   virtual nsSVGAnimatedTransformList*
     GetAnimatedTransformList(uint32_t aFlags = 0) MOZ_OVERRIDE;
   virtual nsIAtom* GetTransformListAttrName() const MOZ_OVERRIDE {
     return nsGkAtoms::transform;
   }
 
   virtual bool IsTransformable() MOZ_OVERRIDE { return true; }
 
 protected:
   // nsSVGElement overrides
 
   nsAutoPtr<nsSVGAnimatedTransformList> mTransforms;
 
   // XXX maybe move this to property table, to save space on un-animated elems?
-  nsAutoPtr<gfxMatrix> mAnimateMotionTransform;
+  nsAutoPtr<gfx::Matrix> mAnimateMotionTransform;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // SVGTransformableElement_h
 
--- a/content/svg/content/src/SVGUseElement.cpp
+++ b/content/svg/content/src/SVGUseElement.cpp
@@ -416,33 +416,33 @@ SVGUseElement::UnlinkSource()
     mSource.get()->RemoveMutationObserver(this);
   }
   mSource.Unlink();
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
-/* virtual */ gfxMatrix
-SVGUseElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+/* virtual */ gfx::Matrix
+SVGUseElement::PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                                         TransformTypes aWhich) const
 {
   NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
                     "Skipping eUserSpaceToParent transforms makes no sense");
 
   // 'transform' attribute:
-  gfxMatrix fromUserSpace =
+  gfx::Matrix fromUserSpace =
     SVGUseElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
   // our 'x' and 'y' attributes:
   float x, y;
   const_cast<SVGUseElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
-  gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
+  gfx::Matrix toUserSpace = gfx::Matrix().Translate(x, y);
   if (aWhich == eChildToUserSpace) {
     return toUserSpace;
   }
   NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
   return toUserSpace * fromUserSpace;
 }
 
 /* virtual */ bool
--- a/content/svg/content/src/SVGUseElement.h
+++ b/content/svg/content/src/SVGUseElement.h
@@ -56,17 +56,17 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 
   // for nsSVGUseFrame's nsIAnonymousContentCreator implementation.
   nsIContent* CreateAnonymousContent();
   nsIContent* GetAnonymousContent() const { return mClone; }
   void DestroyAnonymousContent();
 
   // nsSVGElement specializations:
-  virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+  virtual gfx::Matrix PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
   virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsIContent interface
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   // WebIDL
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1555,18 +1555,18 @@ nsSVGElement::GetCtx() const
     }
     ancestor = ancestor->GetFlattenedTreeParent();
   }
 
   // we don't have an ancestor <svg> element...
   return nullptr;
 }
 
-/* virtual */ gfxMatrix
-nsSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+/* virtual */ gfx::Matrix
+nsSVGElement::PrependLocalTransformsTo(const gfx::Matrix &aMatrix,
                                        TransformTypes aWhich) const
 {
   return aMatrix;
 }
 
 nsSVGElement::LengthAttributesInfo
 nsSVGElement::GetLengthInfo()
 {
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -52,19 +52,23 @@ class SVGNumberList;
 class SVGAnimatedLengthList;
 class SVGUserUnitList;
 class SVGAnimatedPointList;
 class SVGAnimatedPathSegList;
 class SVGAnimatedPreserveAspectRatio;
 class nsSVGAnimatedTransformList;
 class SVGStringList;
 class DOMSVGStringList;
+
+namespace gfx {
+class Matrix;
 }
 
-struct gfxMatrix;
+}
+
 struct nsSVGEnumMapping;
 
 typedef nsStyledElementNotElementCSSInlineStyle nsSVGElementBase;
 
 class nsSVGElement : public nsSVGElementBase    // nsIContent
                    , public nsIDOMSVGElement
 {
 protected:
@@ -157,24 +161,24 @@ public:
    * coordinates on an element apply.)
    *
    * If aWhich is eChildToUserSpace, then only the transforms from the
    * coordinate space established by this element for its childre to this
    * elements userspace are included. This includes any offsets due to e.g.
    * 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
    * does not include any transforms due to the 'transform' attribute.
    */
-  virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
+  virtual mozilla::gfx::Matrix PrependLocalTransformsTo(const mozilla::gfx::Matrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const;
 
   // Setter for to set the current <animateMotion> transformation
   // Only visible for nsSVGGraphicElement, so it's a no-op here, and that
   // subclass has the useful implementation.
-  virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix) {/*no-op*/}
-  virtual const gfxMatrix* GetAnimateMotionTransform() const { return nullptr; }
+  virtual void SetAnimateMotionTransform(const mozilla::gfx::Matrix* aMatrix) {/*no-op*/}
+  virtual const mozilla::gfx::Matrix* GetAnimateMotionTransform() const { return nullptr; }
 
   bool IsStringAnimatable(uint8_t aAttrEnum) {
     return GetStringInfo().mStringInfo[aAttrEnum].mIsAnimatable;
   }
   bool NumberAttrAllowsPercentage(uint8_t aAttrEnum) {
     return GetNumberInfo().mNumberInfo[aAttrEnum].mPercentagesAllowed;
   }
   virtual bool HasValidDimensions() const {
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3840,21 +3840,21 @@ SVGTextFrame::GetCanvasTM(uint32_t aFor,
     NS_ASSERTION(!(aFor == FOR_OUTERSVG_TM &&
                    (GetStateBits() & NS_FRAME_IS_NONDISPLAY)),
                  "should not call GetCanvasTM(FOR_OUTERSVG_TM) when we are "
                  "non-display");
 
     nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent);
     dom::SVGTextContentElement *content = static_cast<dom::SVGTextContentElement*>(mContent);
 
-    gfxMatrix tm = content->PrependLocalTransformsTo(
-        this == aTransformRoot ? gfxMatrix() :
-                                 parent->GetCanvasTM(aFor, aTransformRoot));
-
-    mCanvasTM = new gfxMatrix(tm);
+    gfx::Matrix tm = content->PrependLocalTransformsTo(
+        this == aTransformRoot ? gfx::Matrix() :
+                                 gfx::ToMatrix(parent->GetCanvasTM(aFor, aTransformRoot)));
+
+    mCanvasTM = new gfxMatrix(ThebesMatrix(tm));
   }
   return *mCanvasTM;
 }
 
 //----------------------------------------------------------------------
 // SVGTextFrame SVG DOM methods
 
 /**
@@ -4726,20 +4726,19 @@ SVGTextFrame::GetTextPath(nsIFrame* aTex
   nsSVGPathGeometryElement *element =
     static_cast<nsSVGPathGeometryElement*>(pathFrame->GetContent());
 
   RefPtr<Path> path = element->GetPathForLengthOrPositionMeasuring();
   if (!path) {
     return nullptr;
   }
 
-  gfxMatrix matrix = element->PrependLocalTransformsTo(gfxMatrix());
+  gfx::Matrix matrix = element->PrependLocalTransformsTo(gfx::Matrix());
   if (!matrix.IsIdentity()) {
-    RefPtr<PathBuilder> builder =
-      path->TransformedCopyToBuilder(ToMatrix(matrix));
+    RefPtr<PathBuilder> builder = path->TransformedCopyToBuilder(matrix);
     path = builder->Finish();
   }
 
   return path.forget();
 }
 
 gfxFloat
 SVGTextFrame::GetOffsetScale(nsIFrame* aTextPathFrame)
--- a/layout/svg/nsSVGAFrame.cpp
+++ b/layout/svg/nsSVGAFrame.cpp
@@ -141,17 +141,17 @@ nsSVGAFrame::GetCanvasTM(uint32_t aFor, 
     }
   }
   if (!mCanvasTM) {
     NS_ASSERTION(mParent, "null parent");
 
     nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent);
     dom::SVGAElement *content = static_cast<dom::SVGAElement*>(mContent);
 
-    gfxMatrix tm = content->PrependLocalTransformsTo(
-        this == aTransformRoot ? gfxMatrix() :
-                                 parent->GetCanvasTM(aFor, aTransformRoot));
+    gfx::Matrix tm = content->PrependLocalTransformsTo(
+        this == aTransformRoot ? gfx::Matrix() :
+                                 gfx::ToMatrix(parent->GetCanvasTM(aFor, aTransformRoot)));
 
-    mCanvasTM = new gfxMatrix(tm);
+    mCanvasTM = new gfxMatrix(ThebesMatrix(tm));
   }
 
   return *mCanvasTM;
 }
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -9,16 +9,17 @@
 // Keep others in (case-insensitive) order:
 #include "gfxContext.h"
 #include "nsGkAtoms.h"
 #include "nsRenderingContext.h"
 #include "mozilla/dom/SVGClipPathElement.h"
 #include "nsSVGEffects.h"
 #include "nsSVGUtils.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsIFrame*
 NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
@@ -312,16 +313,16 @@ nsSVGClipPathFrame::GetType() const
   return nsGkAtoms::svgClipPathFrame;
 }
 
 gfxMatrix
 nsSVGClipPathFrame::GetCanvasTM(uint32_t aFor, nsIFrame* aTransformRoot)
 {
   SVGClipPathElement *content = static_cast<SVGClipPathElement*>(mContent);
 
-  gfxMatrix tm =
+  gfx::Matrix tm =
     content->PrependLocalTransformsTo(mClipParentMatrix ?
-                                      *mClipParentMatrix : gfxMatrix());
+                                      gfx::ToMatrix(*mClipParentMatrix) : gfx::Matrix());
 
-  return nsSVGUtils::AdjustMatrixForUnits(tm,
+  return nsSVGUtils::AdjustMatrixForUnits(ThebesMatrix(tm),
                                           &content->mEnumAttributes[SVGClipPathElement::CLIPPATHUNITS],
                                           mClipParent);
 }
--- a/layout/svg/nsSVGContainerFrame.cpp
+++ b/layout/svg/nsSVGContainerFrame.cpp
@@ -235,18 +235,18 @@ nsSVGDisplayContainerFrame::IsSVGTransfo
 
   if (mContent->IsSVG()) {
     nsSVGElement *content = static_cast<nsSVGElement*>(mContent);
     nsSVGAnimatedTransformList* transformList =
       content->GetAnimatedTransformList();
     if ((transformList && transformList->HasTransform()) ||
         content->GetAnimateMotionTransform()) {
       if (aOwnTransform) {
-        *aOwnTransform = content->PrependLocalTransformsTo(gfxMatrix(),
-                                    nsSVGElement::eUserSpaceToParent);
+        *aOwnTransform = ThebesMatrix(content->PrependLocalTransformsTo(gfx::Matrix(),
+                                    nsSVGElement::eUserSpaceToParent));
       }
       foundTransform = true;
     }
   }
   return foundTransform;
 }
 
 //----------------------------------------------------------------------
@@ -396,23 +396,22 @@ nsSVGDisplayContainerFrame::GetBBoxContr
   uint32_t aFlags)
 {
   SVGBBox bboxUnion;
 
   nsIFrame* kid = mFrames.FirstChild();
   while (kid) {
     nsISVGChildFrame* svgKid = do_QueryFrame(kid);
     if (svgKid) {
-      gfxMatrix transform = aToBBoxUserspace;
+      gfx::Matrix transform = gfx::ToMatrix(aToBBoxUserspace);
       nsIContent *content = kid->GetContent();
       if (content->IsSVG()) {
-        transform = static_cast<nsSVGElement*>(content)->
-                      PrependLocalTransformsTo(aToBBoxUserspace);
+        transform = static_cast<nsSVGElement*>(content)->PrependLocalTransformsTo(transform);
       }
       // We need to include zero width/height vertical/horizontal lines, so we have
       // to use UnionEdges.
-      bboxUnion.UnionEdges(svgKid->GetBBoxContribution(transform, aFlags));
+      bboxUnion.UnionEdges(svgKid->GetBBoxContribution(ThebesMatrix(transform), aFlags));
     }
     kid = kid->GetNextSibling();
   }
 
   return bboxUnion;
 }
--- a/layout/svg/nsSVGFilterFrame.cpp
+++ b/layout/svg/nsSVGFilterFrame.cpp
@@ -14,17 +14,19 @@
 #include "nsSVGEffects.h"
 #include "nsSVGElement.h"
 #include "mozilla/dom/SVGFilterElement.h"
 #include "nsSVGFilterInstance.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
 #include "nsContentUtils.h"
+#include "mozilla/gfx/Matrix.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 nsIFrame*
 NS_NewSVGFilterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSVGFilterFrame(aContext);
 }
 
@@ -64,43 +66,44 @@ MapFrameRectToFilterSpace(const nsRect* 
 /**
  * Returns the transform from frame space to the coordinate space that
  * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the
  * top-left corner of its border box, aka the top left corner of its mRect.
  */
 static gfxMatrix
 GetUserToFrameSpaceInCSSPxTransform(nsIFrame *aFrame)
 {
-  gfxMatrix userToFrameSpaceInCSSPx;
+  gfx::Matrix userToFrameSpaceInCSSPx;
 
   if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     int32_t appUnitsPerCSSPx = aFrame->PresContext()->AppUnitsPerCSSPixel();
     // As currently implemented by Mozilla for the purposes of filters, user
     // space is the coordinate system established by GetCanvasTM(), since
     // that's what we use to set filterToDeviceSpace above. In other words,
     // for SVG, user space is actually the coordinate system aTarget
     // establishes for _its_ children (i.e. after taking account of any x/y
     // and viewBox attributes), not the coordinate system that is established
     // for it by its 'transform' attribute (or by its _parent_) as it's
     // normally defined. (XXX We should think about fixing this.) The only
     // frame type for which these extra transforms are not simply an x/y
     // translation is nsSVGInnerSVGFrame, hence we treat it specially here.
     if (aFrame->GetType() == nsGkAtoms::svgInnerSVGFrame) {
       userToFrameSpaceInCSSPx =
         static_cast<nsSVGElement*>(aFrame->GetContent())->
-          PrependLocalTransformsTo(gfxMatrix());
+          PrependLocalTransformsTo(gfx::Matrix());
     } else {
       gfxPoint targetsUserSpaceOffset =
         nsLayoutUtils::RectToGfxRect(aFrame->GetRect(), appUnitsPerCSSPx).
                          TopLeft();
-      userToFrameSpaceInCSSPx.Translate(-targetsUserSpaceOffset);
+      userToFrameSpaceInCSSPx.Translate(-targetsUserSpaceOffset.x,
+                                        -targetsUserSpaceOffset.y);
     }
   }
   // else, for all other frames, leave as the identity matrix
-  return userToFrameSpaceInCSSPx;
+  return ThebesMatrix(userToFrameSpaceInCSSPx);
 }
 
 class nsSVGFilterFrame::AutoFilterReferencer
 {
 public:
   AutoFilterReferencer(nsSVGFilterFrame *aFrame)
     : mFrame(aFrame)
   {
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -179,18 +179,18 @@ nsSVGForeignObjectFrame::IsSVGTransforme
   }
 
   nsSVGElement *content = static_cast<nsSVGElement*>(mContent);
   nsSVGAnimatedTransformList* transformList =
     content->GetAnimatedTransformList();
   if ((transformList && transformList->HasTransform()) ||
       content->GetAnimateMotionTransform()) {
     if (aOwnTransform) {
-      *aOwnTransform = content->PrependLocalTransformsTo(gfxMatrix(),
-                                  nsSVGElement::eUserSpaceToParent);
+      *aOwnTransform = ThebesMatrix(content->PrependLocalTransformsTo(gfx::Matrix(),
+                                  nsSVGElement::eUserSpaceToParent));
     }
     foundTransform = true;
   }
   return foundTransform;
 }
 
 NS_IMETHODIMP
 nsSVGForeignObjectFrame::PaintSVG(nsRenderingContext *aContext,
@@ -497,21 +497,21 @@ nsSVGForeignObjectFrame::GetCanvasTM(uin
   }
   if (!mCanvasTM) {
     NS_ASSERTION(mParent, "null parent");
 
     nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent);
     SVGForeignObjectElement *content =
       static_cast<SVGForeignObjectElement*>(mContent);
 
-    gfxMatrix tm = content->PrependLocalTransformsTo(
-        this == aTransformRoot ? gfxMatrix() :
-                                 parent->GetCanvasTM(aFor, aTransformRoot));
+    gfx::Matrix tm = content->PrependLocalTransformsTo(
+        this == aTransformRoot ? gfx::Matrix() :
+                                 gfx::ToMatrix(parent->GetCanvasTM(aFor, aTransformRoot)));
 
-    mCanvasTM = new gfxMatrix(tm);
+    mCanvasTM = new gfxMatrix(ThebesMatrix(tm));
   }
   return *mCanvasTM;
 }
 
 //----------------------------------------------------------------------
 // Implementation helpers
 
 void nsSVGForeignObjectFrame::RequestReflow(nsIPresShell::IntrinsicDirty aType)
--- a/layout/svg/nsSVGGFrame.cpp
+++ b/layout/svg/nsSVGGFrame.cpp
@@ -9,16 +9,17 @@
 // Keep others in (case-insensitive) order:
 #include "nsGkAtoms.h"
 #include "SVGTransformableElement.h"
 #include "nsIFrame.h"
 #include "SVGGraphicsElement.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsIFrame*
 NS_NewSVGGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {  
@@ -73,21 +74,21 @@ nsSVGGFrame::GetCanvasTM(uint32_t aFor, 
       return nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(this);
     }
   }
   if (!mCanvasTM) {
     NS_ASSERTION(mParent, "null parent");
 
     nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent);
     SVGGraphicsElement *content = static_cast<SVGGraphicsElement*>(mContent);
-    gfxMatrix tm = content->PrependLocalTransformsTo(
-        this == aTransformRoot ? gfxMatrix() :
-                                 parent->GetCanvasTM(aFor, aTransformRoot));
+    gfx::Matrix tm = content->PrependLocalTransformsTo(
+        this == aTransformRoot ? gfx::Matrix() :
+                                 gfx::ToMatrix(parent->GetCanvasTM(aFor, aTransformRoot)));
 
-    mCanvasTM = new gfxMatrix(tm);
+    mCanvasTM = new gfxMatrix(ThebesMatrix(tm));
   }
   return *mCanvasTM;
 }
 
 NS_IMETHODIMP
 nsSVGGFrame::AttributeChanged(int32_t         aNameSpaceID,
                               nsIAtom*        aAttribute,
                               int32_t         aModType)
--- a/layout/svg/nsSVGInnerSVGFrame.cpp
+++ b/layout/svg/nsSVGInnerSVGFrame.cpp
@@ -278,21 +278,21 @@ nsSVGInnerSVGFrame::GetCanvasTM(uint32_t
     }
   }
   if (!mCanvasTM) {
     NS_ASSERTION(mParent, "null parent");
 
     nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent);
     SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
 
-    gfxMatrix tm = content->PrependLocalTransformsTo(
-        this == aTransformRoot ? gfxMatrix() :
-                                 parent->GetCanvasTM(aFor, aTransformRoot));
+    gfx::Matrix tm = content->PrependLocalTransformsTo(
+        this == aTransformRoot ? gfx::Matrix() :
+                                 gfx::ToMatrix(parent->GetCanvasTM(aFor, aTransformRoot)));
 
-    mCanvasTM = new gfxMatrix(tm);
+    mCanvasTM = new gfxMatrix(ThebesMatrix(tm));
   }
   return *mCanvasTM;
 }
 
 bool
 nsSVGInnerSVGFrame::HasChildrenOnlyTransform(gfxMatrix *aTransform) const
 {
   SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -834,19 +834,19 @@ nsSVGOuterSVGFrame::GetCanvasTM(uint32_t
   if (!mCanvasTM) {
     NS_ASSERTION(!aTransformRoot, "transform root will be ignored here");
     SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
 
     float devPxPerCSSPx =
       1.0f / PresContext()->AppUnitsToFloatCSSPixels(
                                 PresContext()->AppUnitsPerDevPixel());
 
-    gfxMatrix tm = content->PrependLocalTransformsTo(
-                     gfxMatrix().Scale(devPxPerCSSPx, devPxPerCSSPx));
-    mCanvasTM = new gfxMatrix(tm);
+    gfx::Matrix tm = content->PrependLocalTransformsTo(
+                     gfx::Matrix().Scale(devPxPerCSSPx, devPxPerCSSPx));
+    mCanvasTM = new gfxMatrix(ThebesMatrix(tm));
   }
   return *mCanvasTM;
 }
 
 //----------------------------------------------------------------------
 // Implementation helpers
 
 bool
@@ -938,16 +938,15 @@ nsSVGOuterSVGAnonChildFrame::HasChildren
   // so that the children we are used to wrap are transformed properly.
 
   SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
 
   bool hasTransform = content->HasChildrenOnlyTransform();
 
   if (hasTransform && aTransform) {
     // Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
-    gfxMatrix identity;
-    *aTransform =
-      content->PrependLocalTransformsTo(identity,
-                                        nsSVGElement::eChildToUserSpace);
+    *aTransform = ThebesMatrix(
+      content->PrependLocalTransformsTo(gfx::Matrix(),
+                                        nsSVGElement::eChildToUserSpace));
   }
 
   return hasTransform;
 }
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -158,18 +158,18 @@ nsSVGPathGeometryFrame::IsSVGTransformed
   }
 
   nsSVGElement *content = static_cast<nsSVGElement*>(mContent);
   nsSVGAnimatedTransformList* transformList =
     content->GetAnimatedTransformList();
   if ((transformList && transformList->HasTransform()) ||
       content->GetAnimateMotionTransform()) {
     if (aOwnTransform) {
-      *aOwnTransform = content->PrependLocalTransformsTo(gfxMatrix(),
-                                  nsSVGElement::eUserSpaceToParent);
+      *aOwnTransform = ThebesMatrix(content->PrependLocalTransformsTo(gfx::Matrix(),
+                                               nsSVGElement::eUserSpaceToParent));
     }
     foundTransform = true;
   }
   return foundTransform;
 }
 
 void
 nsSVGPathGeometryFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
@@ -507,19 +507,19 @@ nsSVGPathGeometryFrame::GetCanvasTM(uint
     }
   }
 
   NS_ASSERTION(mParent, "null parent");
 
   nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent);
   dom::SVGGraphicsElement *content = static_cast<dom::SVGGraphicsElement*>(mContent);
 
-  return content->PrependLocalTransformsTo(
-      this == aTransformRoot ? gfxMatrix() :
-                               parent->GetCanvasTM(aFor, aTransformRoot));
+  return ThebesMatrix(content->PrependLocalTransformsTo(
+      this == aTransformRoot ? gfx::Matrix() :
+                               gfx::ToMatrix(parent->GetCanvasTM(aFor, aTransformRoot))));
 }
 
 //----------------------------------------------------------------------
 // nsSVGPathGeometryFrame methods:
 
 nsSVGPathGeometryFrame::MarkerProperties
 nsSVGPathGeometryFrame::GetMarkerProperties(nsSVGPathGeometryFrame *aFrame)
 {
--- a/layout/svg/nsSVGSwitchFrame.cpp
+++ b/layout/svg/nsSVGSwitchFrame.cpp
@@ -8,16 +8,18 @@
 #include "gfxRect.h"
 #include "nsSVGEffects.h"
 #include "nsSVGGFrame.h"
 #include "mozilla/dom/SVGSwitchElement.h"
 #include "nsSVGUtils.h"
 
 class nsRenderingContext;
 
+using namespace mozilla;
+
 typedef nsSVGGFrame nsSVGSwitchFrameBase;
 
 class nsSVGSwitchFrame : public nsSVGSwitchFrameBase
 {
   friend nsIFrame*
   NS_NewSVGSwitchFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   nsSVGSwitchFrame(nsStyleContext* aContext) :
@@ -225,22 +227,22 @@ SVGBBox
 nsSVGSwitchFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
                                       uint32_t aFlags)
 {
   nsIFrame* kid = GetActiveChildFrame();
   if (kid) {
     nsISVGChildFrame* svgKid = do_QueryFrame(kid);
     if (svgKid) {
       nsIContent *content = kid->GetContent();
-      gfxMatrix transform = aToBBoxUserspace;
+      gfx::Matrix transform = gfx::ToMatrix(aToBBoxUserspace);
       if (content->IsSVG()) {
         transform = static_cast<nsSVGElement*>(content)->
-                      PrependLocalTransformsTo(aToBBoxUserspace);
+                      PrependLocalTransformsTo(transform);
       }
-      return svgKid->GetBBoxContribution(transform, aFlags);
+      return svgKid->GetBBoxContribution(ThebesMatrix(transform), aFlags);
     }
   }
   return SVGBBox();
 }
 
 nsIFrame *
 nsSVGSwitchFrame::GetActiveChildFrame()
 {
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -639,24 +639,24 @@ gfxMatrix
 nsSVGUtils::GetUserToCanvasTM(nsIFrame *aFrame, uint32_t aFor)
 {
   NS_ASSERTION(aFor == nsISVGChildFrame::FOR_OUTERSVG_TM,
                "Unexpected aFor?");
 
   nsISVGChildFrame* svgFrame = do_QueryFrame(aFrame);
   NS_ASSERTION(svgFrame, "bad frame");
 
-  gfxMatrix tm;
+  gfx::Matrix tm;
   if (svgFrame) {
     nsSVGElement *content = static_cast<nsSVGElement*>(aFrame->GetContent());
     tm = content->PrependLocalTransformsTo(
-                    GetCanvasTM(aFrame->GetParent(), aFor),
+                    gfx::ToMatrix(GetCanvasTM(aFrame->GetParent(), aFor)),
                     nsSVGElement::eUserSpaceToParent);
   }
-  return tm;
+  return ThebesMatrix(tm);
 }
 
 void 
 nsSVGUtils::NotifyChildrenOfSVGChange(nsIFrame *aFrame, uint32_t aFlags)
 {
   nsIFrame *kid = aFrame->GetFirstPrincipalChild();
 
   while (kid) {
@@ -1180,27 +1180,27 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, ui
       }
       svg = do_QueryFrame(ancestor);
     }
     nsIContent* content = aFrame->GetContent();
     if (content->IsSVG() &&
         !static_cast<const nsSVGElement*>(content)->HasValidDimensions()) {
       return bbox;
     }
-    gfxMatrix matrix;
+    gfx::Matrix matrix;
     if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame) {
       // The spec says getBBox "Returns the tight bounding box in *current user
       // space*". So we should really be doing this for all elements, but that
       // needs investigation to check that we won't break too much content.
       NS_ABORT_IF_FALSE(content->IsSVG(), "bad cast");
       nsSVGElement *element = static_cast<nsSVGElement*>(content);
       matrix = element->PrependLocalTransformsTo(matrix,
                           nsSVGElement::eChildToUserSpace);
     }
-    return svg->GetBBoxContribution(matrix, aFlags).ToThebesRect();
+    return svg->GetBBoxContribution(ThebesMatrix(matrix), aFlags).ToThebesRect();
   }
   return nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(aFrame);
 }
 
 gfxRect
 nsSVGUtils::GetRelativeRect(uint16_t aUnits, const nsSVGLength2 *aXYWH,
                             const gfxRect &aBBox, nsIFrame *aFrame)
 {
@@ -1792,24 +1792,23 @@ nsSVGUtils::GetSVGGlyphExtents(Element* 
                                gfxRect* aResult)
 {
   nsIFrame* frame = aElement->GetPrimaryFrame();
   nsISVGChildFrame* svgFrame = do_QueryFrame(frame);
   if (!svgFrame) {
     return false;
   }
 
-  gfxMatrix transform(aSVGToAppSpace);
+  gfx::Matrix transform = gfx::ToMatrix(aSVGToAppSpace);
   nsIContent* content = frame->GetContent();
   if (content->IsSVG()) {
-    transform = static_cast<nsSVGElement*>(content)->
-                  PrependLocalTransformsTo(aSVGToAppSpace);
+    transform = static_cast<nsSVGElement*>(content)->PrependLocalTransformsTo(transform);
   }
 
-  *aResult = svgFrame->GetBBoxContribution(transform,
+  *aResult = svgFrame->GetBBoxContribution(ThebesMatrix(transform),
     nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeFillGeometry |
     nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIncludeStrokeGeometry |
     nsSVGUtils::eBBoxIncludeMarkers).ToThebesRect();
   return true;
 }
 
 nsRect
 nsSVGUtils::ToCanvasBounds(const gfxRect &aUserspaceRect,