Bug 1301027 - Remove the matrix * point operator and replace it with TransformPoint methods. r=Bas
authorNicolas Silva <nsilva@mozilla.com>
Thu, 08 Sep 2016 18:26:03 +0200
changeset 354614 418d4cce23a41952d339d9ee06a40d029ba2a0fd
parent 354613 90f8edf13ee46f030df9c967f7d44d56cb0047d5
child 354615 f9bd32e801c86965d6e153d8a0d3cc101f1d80e1
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1301027
milestone51.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 1301027 - Remove the matrix * point operator and replace it with TransformPoint methods. r=Bas
dom/base/DOMMatrix.cpp
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/CanvasRenderingContext2D.h
dom/svg/DOMSVGPoint.cpp
dom/svg/SVGCircleElement.cpp
dom/svg/SVGEllipseElement.cpp
dom/svg/SVGLineElement.cpp
dom/svg/SVGMarkerElement.cpp
dom/svg/nsSVGPolyElement.cpp
gfx/2d/DrawCommand.h
gfx/2d/HelpersD2D.h
gfx/2d/Matrix.cpp
gfx/2d/Matrix.h
gfx/2d/PathCG.cpp
gfx/2d/PathCairo.cpp
gfx/2d/PathD2D.cpp
gfx/2d/PathHelpers.h
gfx/2d/PathRecording.cpp
gfx/2d/PathSkia.cpp
gfx/layers/LayerSorter.cpp
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/apz/test/gtest/TestHitTesting.cpp
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxFont.cpp
layout/base/UnitTransforms.h
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGPathGeometryFrame.cpp
layout/svg/nsSVGUtils.cpp
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -202,43 +202,43 @@ DOMMatrixReadOnly::TransformPoint(const 
 
   if (mMatrix3D) {
     gfx::Point4D transformedPoint;
     transformedPoint.x = point.mX;
     transformedPoint.y = point.mY;
     transformedPoint.z = point.mZ;
     transformedPoint.w = point.mW;
 
-    transformedPoint = *mMatrix3D * transformedPoint;
+    transformedPoint = mMatrix3D->TransformPoint(transformedPoint);
 
     retval->SetX(transformedPoint.x);
     retval->SetY(transformedPoint.y);
     retval->SetZ(transformedPoint.z);
     retval->SetW(transformedPoint.w);
   } else if (point.mZ != 0 || point.mW != 1.0) {
     gfx::Matrix4x4 tempMatrix(gfx::Matrix4x4::From2D(*mMatrix2D));
 
     gfx::Point4D transformedPoint;
     transformedPoint.x = point.mX;
     transformedPoint.y = point.mY;
     transformedPoint.z = point.mZ;
     transformedPoint.w = point.mW;
 
-    transformedPoint = tempMatrix * transformedPoint;
+    transformedPoint = tempMatrix.TransformPoint(transformedPoint);
 
     retval->SetX(transformedPoint.x);
     retval->SetY(transformedPoint.y);
     retval->SetZ(transformedPoint.z);
     retval->SetW(transformedPoint.w);
   } else {
     gfx::Point transformedPoint;
     transformedPoint.x = point.mX;
     transformedPoint.y = point.mY;
 
-    transformedPoint = *mMatrix2D * transformedPoint;
+    transformedPoint = mMatrix2D->TransformPoint(transformedPoint);
 
     retval->SetX(transformedPoint.x);
     retval->SetY(transformedPoint.y);
     retval->SetZ(point.mZ);
     retval->SetW(point.mW);
   }
   return retval.forget();
 }
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -3305,17 +3305,17 @@ CanvasRenderingContext2D::ArcTo(double a
   if (mPathBuilder) {
     p0 = mPathBuilder->CurrentPoint();
   } else {
     Matrix invTransform = mTarget->GetTransform();
     if (!invTransform.Invert()) {
       return;
     }
 
-    p0 = invTransform * mDSPathBuilder->CurrentPoint();
+    p0 = invTransform.TransformPoint(mDSPathBuilder->CurrentPoint());
   }
 
   Point p1(aX1, aY1);
   Point p2(aX2, aY2);
 
   // Execute these calculations in double precision to avoid cumulative
   // rounding errors.
   double dir, a2, b2, c2, cosx, sinx, d, anx, any,
@@ -3388,20 +3388,20 @@ CanvasRenderingContext2D::Rect(double aX
 
   if (mPathBuilder) {
     mPathBuilder->MoveTo(Point(aX, aY));
     mPathBuilder->LineTo(Point(aX + aW, aY));
     mPathBuilder->LineTo(Point(aX + aW, aY + aH));
     mPathBuilder->LineTo(Point(aX, aY + aH));
     mPathBuilder->Close();
   } else {
-    mDSPathBuilder->MoveTo(mTarget->GetTransform() * Point(aX, aY));
-    mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(aX + aW, aY));
-    mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(aX + aW, aY + aH));
-    mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(aX, aY + aH));
+    mDSPathBuilder->MoveTo(mTarget->GetTransform().TransformPoint(Point(aX, aY)));
+    mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(Point(aX + aW, aY)));
+    mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(Point(aX + aW, aY + aH)));
+    mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(Point(aX, aY + aH)));
     mDSPathBuilder->Close();
   }
 }
 
 void
 CanvasRenderingContext2D::Ellipse(double aX, double aY, double aRadiusX, double aRadiusY,
                                   double aRotation, double aStartAngle, double aEndAngle,
                                   bool aAnticlockwise, ErrorResult& aError)
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -300,18 +300,18 @@ public:
 
   void MoveTo(double aX, double aY)
   {
     EnsureWritablePath();
 
     if (mPathBuilder) {
       mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
     } else {
-      mDSPathBuilder->MoveTo(mTarget->GetTransform() *
-                             mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
+      mDSPathBuilder->MoveTo(mTarget->GetTransform().TransformPoint(
+                             mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))));
     }
   }
 
   void LineTo(double aX, double aY)
   {
     EnsureWritablePath();
 
     LineTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
@@ -321,20 +321,20 @@ public:
   {
     EnsureWritablePath();
 
     if (mPathBuilder) {
       mPathBuilder->QuadraticBezierTo(mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy)),
                                       mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
     } else {
       mozilla::gfx::Matrix transform = mTarget->GetTransform();
-      mDSPathBuilder->QuadraticBezierTo(transform *
-                                        mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy)),
-                                        transform *
-                                        mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)));
+      mDSPathBuilder->QuadraticBezierTo(transform.TransformPoint(
+                                          mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy))),
+                                        transform.TransformPoint(
+                                          mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))));
     }
   }
 
   void BezierCurveTo(double aCp1x, double aCp1y, double aCp2x, double aCp2y, double aX, double aY)
   {
     EnsureWritablePath();
 
     BezierTo(mozilla::gfx::Point(ToFloat(aCp1x), ToFloat(aCp1y)),
@@ -512,31 +512,31 @@ public:
     return mCanvasElement;
   }
 
   void LineTo(const mozilla::gfx::Point& aPoint)
   {
     if (mPathBuilder) {
       mPathBuilder->LineTo(aPoint);
     } else {
-      mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
+      mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(aPoint));
     }
   }
 
   void BezierTo(const mozilla::gfx::Point& aCP1,
                 const mozilla::gfx::Point& aCP2,
                 const mozilla::gfx::Point& aCP3)
   {
     if (mPathBuilder) {
       mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
     } else {
       mozilla::gfx::Matrix transform = mTarget->GetTransform();
-      mDSPathBuilder->BezierTo(transform * aCP1,
-                                transform * aCP2,
-                                transform * aCP3);
+      mDSPathBuilder->BezierTo(transform.TransformPoint(aCP1),
+                               transform.TransformPoint(aCP2),
+                               transform.TransformPoint(aCP3));
     }
   }
 
   friend class CanvasRenderingContext2DUserData;
 
   virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aFormat) override;
 
 
--- a/dom/svg/DOMSVGPoint.cpp
+++ b/dom/svg/DOMSVGPoint.cpp
@@ -110,12 +110,12 @@ DOMSVGPoint::SetY(float aY, ErrorResult&
 }
 
 already_AddRefed<nsISVGPoint>
 DOMSVGPoint::MatrixTransform(dom::SVGMatrix& matrix)
 {
   float x = HasOwner() ? InternalItem().mX : mPt.mX;
   float y = HasOwner() ? InternalItem().mY : mPt.mY;
 
-  Point pt = ToMatrix(matrix.GetMatrix()) * Point(x, y);
+  Point pt = ToMatrix(matrix.GetMatrix()).TransformPoint(Point(x, y));
   nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt);
   return newPoint.forget();
 }
--- a/dom/svg/SVGCircleElement.cpp
+++ b/dom/svg/SVGCircleElement.cpp
@@ -88,17 +88,17 @@ SVGCircleElement::GetGeometryBounds(Rect
                                     const Matrix& aToBoundsSpace,
                                     const Matrix* aToNonScalingStrokeSpace)
 {
   float x, y, r;
   GetAnimatedLengthValues(&x, &y, &r, nullptr);
 
   if (r <= 0.f) {
     // Rendering of the element is disabled
-    *aBounds = Rect(aToBoundsSpace * Point(x, y), Size());
+    *aBounds = Rect(aToBoundsSpace.TransformPoint(Point(x, y)), Size());
     return true;
   }
 
   if (aToBoundsSpace.IsRectilinear()) {
     // Optimize the case where we can treat the circle as a rectangle and
     // still get tight bounds.
     if (aStrokeOptions.mLineWidth > 0.f) {
       if (aToNonScalingStrokeSpace) {
--- a/dom/svg/SVGEllipseElement.cpp
+++ b/dom/svg/SVGEllipseElement.cpp
@@ -99,17 +99,17 @@ SVGEllipseElement::GetGeometryBounds(Rec
                                      const Matrix& aToBoundsSpace,
                                      const Matrix* aToNonScalingStrokeSpace)
 {
   float x, y, rx, ry;
   GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
 
   if (rx <= 0.f || ry <= 0.f) {
     // Rendering of the element is disabled
-    *aBounds = Rect(aToBoundsSpace * Point(x, y), Size());
+    *aBounds = Rect(aToBoundsSpace.TransformPoint(Point(x, y)), Size());
     return true;
   }
 
   if (aToBoundsSpace.IsRectilinear()) {
     // Optimize the case where we can treat the ellipse as a rectangle and
     // still get tight bounds.
     if (aStrokeOptions.mLineWidth > 0.f) {
       if (aToNonScalingStrokeSpace) {
--- a/dom/svg/SVGLineElement.cpp
+++ b/dom/svg/SVGLineElement.cpp
@@ -152,18 +152,18 @@ SVGLineElement::GetGeometryBounds(Rect* 
                                   const StrokeOptions& aStrokeOptions,
                                   const Matrix& aToBoundsSpace,
                                   const Matrix* aToNonScalingStrokeSpace)
 {
   float x1, y1, x2, y2;
   GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nullptr);
 
   if (aStrokeOptions.mLineWidth <= 0) {
-    *aBounds = Rect(aToBoundsSpace * Point(x1, y1), Size());
-    aBounds->ExpandToEnclose(aToBoundsSpace * Point(x2, y2));
+    *aBounds = Rect(aToBoundsSpace.TransformPoint(Point(x1, y1)), Size());
+    aBounds->ExpandToEnclose(aToBoundsSpace.TransformPoint(Point(x2, y2)));
     return true;
   }
 
   // transform from non-scaling-stroke space to the space in which we compute
   // bounds
   Matrix nonScalingToBounds;
   if (aToNonScalingStrokeSpace) {
     MOZ_ASSERT(!aToNonScalingStrokeSpace->IsSingular());
@@ -193,18 +193,18 @@ SVGLineElement::GetGeometryBounds(Rect* 
 
   // Handle butt and square linecap, normal and non-scaling stroke cases
   // together: start with endpoints (x1, y1), (x2, y2) in the stroke space,
   // compute the four corners of the stroked line, transform the corners to
   // bounds space, and compute bounds there.
 
   if (aToNonScalingStrokeSpace) {
     Point nonScalingSpaceP1, nonScalingSpaceP2;
-    nonScalingSpaceP1 = *aToNonScalingStrokeSpace * Point(x1, y1);
-    nonScalingSpaceP2 = *aToNonScalingStrokeSpace * Point(x2, y2);
+    nonScalingSpaceP1 = aToNonScalingStrokeSpace->TransformPoint(Point(x1, y1));
+    nonScalingSpaceP2 = aToNonScalingStrokeSpace->TransformPoint(Point(x2, y2));
     x1 = nonScalingSpaceP1.x;
     y1 = nonScalingSpaceP1.y;
     x2 = nonScalingSpaceP2.x;
     y2 = nonScalingSpaceP2.y;
   }
 
   Float length = Float(NS_hypot(x2 - x1, y2 - y1));
   Float xDelta;
@@ -240,18 +240,18 @@ SVGLineElement::GetGeometryBounds(Rect* 
       points[2] = Point(x2 + yDelta + xDelta, y2 + xDelta - yDelta);
       points[3] = Point(x2 + yDelta - xDelta, y2 + xDelta + yDelta);
     }
   }
 
   const Matrix& toBoundsSpace = aToNonScalingStrokeSpace ?
     nonScalingToBounds : aToBoundsSpace;
 
-  *aBounds = Rect(toBoundsSpace * points[0], Size());
+  *aBounds = Rect(toBoundsSpace.TransformPoint(points[0]), Size());
   for (uint32_t i = 1; i < 4; ++i) {
-    aBounds->ExpandToEnclose(toBoundsSpace * points[i]);
+    aBounds->ExpandToEnclose(toBoundsSpace.TransformPoint(points[i]));
   }
 
   return true;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/svg/SVGMarkerElement.cpp
+++ b/dom/svg/SVGMarkerElement.cpp
@@ -357,17 +357,17 @@ SVGMarkerElement::GetViewBoxTransform()
       SVGContentUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
                                            viewbox.x, viewbox.y,
                                            viewbox.width, viewbox.height,
                                            mPreserveAspectRatio);
 
     float refX = mLengthAttributes[REFX].GetAnimValue(mCoordCtx);
     float refY = mLengthAttributes[REFY].GetAnimValue(mCoordCtx);
 
-    gfx::Point ref = viewBoxTM * gfx::Point(refX, refY);
+    gfx::Point ref = viewBoxTM.TransformPoint(gfx::Point(refX, refY));
 
     Matrix TM = viewBoxTM;
     TM.PostTranslate(-ref.x, -ref.y);
 
     mViewBoxToViewportTransform = new gfx::Matrix(TM);
   }
 
   return *mViewBoxToViewportTransform;
--- a/dom/svg/nsSVGPolyElement.cpp
+++ b/dom/svg/nsSVGPolyElement.cpp
@@ -144,16 +144,16 @@ nsSVGPolyElement::GetGeometryBounds(Rect
     // We can avoid transforming each point and just transform the result.
     // Important for large point lists.
     Rect bounds(points[0], Size());
     for (uint32_t i = 1; i < points.Length(); ++i) {
       bounds.ExpandToEnclose(points[i]);
     }
     *aBounds = aToBoundsSpace.TransformBounds(bounds);
   } else {
-    *aBounds = Rect(aToBoundsSpace * points[0], Size());
+    *aBounds = Rect(aToBoundsSpace.TransformPoint(points[0]), Size());
     for (uint32_t i = 1; i < points.Length(); ++i) {
-      aBounds->ExpandToEnclose(aToBoundsSpace * points[i]);
+      aBounds->ExpandToEnclose(aToBoundsSpace.TransformPoint(points[i]));
     }
   }
   return true;
 }
 
--- a/gfx/2d/DrawCommand.h
+++ b/gfx/2d/DrawCommand.h
@@ -203,17 +203,17 @@ public:
   {
   }
 
   virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix* aTransform) const
   {
     MOZ_ASSERT(!aTransform || !aTransform->HasNonIntegerTranslation());
     Point dest(Float(mDestination.x), Float(mDestination.y));
     if (aTransform) {
-      dest = (*aTransform) * dest;
+      dest = aTransform->TransformPoint(dest);
     }
     aDT->CopySurface(mSurface, mSourceRect, IntPoint(uint32_t(dest.x), uint32_t(dest.y)));
   }
 
 private:
   RefPtr<SourceSurface> mSurface;
   IntRect mSourceRect;
   IntPoint mDestination;
--- a/gfx/2d/HelpersD2D.h
+++ b/gfx/2d/HelpersD2D.h
@@ -648,20 +648,20 @@ CreatePartialBitmapForSurface(DataSource
       // Scope to auto-Unmap() |mapping|.
       DataSourceSurface::ScopedMap mapping(aSurface, DataSourceSurface::READ);
       if (MOZ2D_WARN_IF(!mapping.IsMapped())) {
         return nullptr;
       }
       ImageHalfScaler scaler(mapping.GetData(), mapping.GetStride(), size);
 
       // Calculate the maximum width/height of the image post transform.
-      Point topRight = transform * Point(Float(size.width), 0);
-      Point topLeft = transform * Point(0, 0);
-      Point bottomRight = transform * Point(Float(size.width), Float(size.height));
-      Point bottomLeft = transform * Point(0, Float(size.height));
+      Point topRight = transform.TransformPoint(Point(Float(size.width), 0));
+      Point topLeft = transform.TransformPoint(Point(0, 0));
+      Point bottomRight = transform.TransformPoint(Point(Float(size.width), Float(size.height)));
+      Point bottomLeft = transform.TransformPoint(Point(0, Float(size.height)));
 
       IntSize scaleSize;
 
       scaleSize.width = int32_t(std::max(Distance(topRight, topLeft),
                                          Distance(bottomRight, bottomLeft)));
       scaleSize.height = int32_t(std::max(Distance(topRight, bottomRight),
                                           Distance(topLeft, bottomLeft)));
 
--- a/gfx/2d/Matrix.cpp
+++ b/gfx/2d/Matrix.cpp
@@ -90,20 +90,20 @@ Matrix::Rotation(Float aAngle)
 Rect
 Matrix::TransformBounds(const Rect &aRect) const
 {
   int i;
   Point quad[4];
   Float min_x, max_x;
   Float min_y, max_y;
 
-  quad[0] = *this * aRect.TopLeft();
-  quad[1] = *this * aRect.TopRight();
-  quad[2] = *this * aRect.BottomLeft();
-  quad[3] = *this * aRect.BottomRight();
+  quad[0] = TransformPoint(aRect.TopLeft());
+  quad[1] = TransformPoint(aRect.TopRight());
+  quad[2] = TransformPoint(aRect.BottomLeft());
+  quad[3] = TransformPoint(aRect.BottomRight());
 
   min_x = max_x = quad[0].x;
   min_y = max_y = quad[0].y;
 
   for (i = 1; i < 4; i++) {
     if (quad[i].x < min_x)
       min_x = quad[i].x;
     if (quad[i].x > max_x)
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -48,27 +48,27 @@ public:
 
   MOZ_ALWAYS_INLINE Matrix Copy() const
   {
     return Matrix(*this);
   }
 
   friend std::ostream& operator<<(std::ostream& aStream, const Matrix& aMatrix);
 
-  Point operator *(const Point &aPoint) const
+  Point TransformPoint(const Point &aPoint) const
   {
     Point retPoint;
 
     retPoint.x = aPoint.x * _11 + aPoint.y * _21 + _31;
     retPoint.y = aPoint.x * _12 + aPoint.y * _22 + _32;
 
     return retPoint;
   }
 
-  Size operator *(const Size &aSize) const
+  Size TransformSize(const Size &aSize) const
   {
     Size retSize;
 
     retSize.width = aSize.width * _11 + aSize.height * _21;
     retSize.height = aSize.width * _12 + aSize.height * _22;
 
     return retSize;
   }
@@ -587,17 +587,17 @@ public:
 
     // The transformed value of z is computed as:
     // z' = aPoint.x * _13 + aPoint.y * _23 + z * _33 + _43;
 
     // Solving for z when z' = 0 gives us:
     F z = -(aPoint.x * _13 + aPoint.y * _23 + _43) / _33;
 
     // Compute the transformed point
-    return *this * Point4DTyped<SourceUnits, F>(aPoint.x, aPoint.y, z, 1);
+    return this->TransformPoint(Point4DTyped<SourceUnits, F>(aPoint.x, aPoint.y, z, 1));
   }
 
   template<class F>
   RectTyped<TargetUnits, F>
   ProjectRectBounds(const RectTyped<SourceUnits, F>& aRect, const RectTyped<TargetUnits, F>& aClip) const
   {
     // This function must never return std::numeric_limits<Float>::max() or any
     // other arbitrary large value in place of inifinity.  This often occurs when
@@ -718,20 +718,20 @@ public:
                               const RectTyped<TargetUnits, F>& aClip,
                               PointTyped<TargetUnits, F>* aVerts) const
   {
     // Initialize a double-buffered array of points in homogenous space with
     // the input rectangle, aRect.
     Point4DTyped<UnknownUnits, F> points[2][kTransformAndClipRectMaxVerts];
     Point4DTyped<UnknownUnits, F>* dstPoint = points[0];
 
-    *dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.x, aRect.y, 0, 1);
-    *dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.XMost(), aRect.y, 0, 1);
-    *dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.XMost(), aRect.YMost(), 0, 1);
-    *dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.x, aRect.YMost(), 0, 1);
+    *dstPoint++ = TransformPoint(Point4DTyped<UnknownUnits, F>(aRect.x, aRect.y, 0, 1));
+    *dstPoint++ = TransformPoint(Point4DTyped<UnknownUnits, F>(aRect.XMost(), aRect.y, 0, 1));
+    *dstPoint++ = TransformPoint(Point4DTyped<UnknownUnits, F>(aRect.XMost(), aRect.YMost(), 0, 1));
+    *dstPoint++ = TransformPoint(Point4DTyped<UnknownUnits, F>(aRect.x, aRect.YMost(), 0, 1));
 
     // View frustum clipping planes are described as normals originating from
     // the 0,0,0,0 origin.
     Point4DTyped<UnknownUnits, F> planeNormals[4];
     planeNormals[0] = Point4DTyped<UnknownUnits, F>(1.0, 0.0, 0.0, -aClip.x);
     planeNormals[1] = Point4DTyped<UnknownUnits, F>(-1.0, 0.0, 0.0, aClip.XMost());
     planeNormals[2] = Point4DTyped<UnknownUnits, F>(0.0, 1.0, 0.0, -aClip.y);
     planeNormals[3] = Point4DTyped<UnknownUnits, F>(0.0, -1.0, 0.0, aClip.YMost());
@@ -819,66 +819,65 @@ public:
       Float y = aPoint.x * _21 + aPoint.y * _22 + aPoint.z * _23 + aPoint.w * _24;
       Float z = aPoint.x * _31 + aPoint.y * _32 + aPoint.z * _33 + aPoint.w * _34;
       Float w = aPoint.x * _41 + aPoint.y * _42 + aPoint.z * _43 + aPoint.w * _44;
 
       return TargetPoint4D(x, y, z, w);
   }
 
   template<class F>
-  Point4DTyped<TargetUnits, F> operator *(const Point4DTyped<SourceUnits, F>& aPoint) const
+  Point4DTyped<TargetUnits, F> TransformPoint(const Point4DTyped<SourceUnits, F>& aPoint) const
   {
     Point4DTyped<TargetUnits, F> retPoint;
 
     retPoint.x = aPoint.x * _11 + aPoint.y * _21 + aPoint.z * _31 + aPoint.w * _41;
     retPoint.y = aPoint.x * _12 + aPoint.y * _22 + aPoint.z * _32 + aPoint.w * _42;
     retPoint.z = aPoint.x * _13 + aPoint.y * _23 + aPoint.z * _33 + aPoint.w * _43;
     retPoint.w = aPoint.x * _14 + aPoint.y * _24 + aPoint.z * _34 + aPoint.w * _44;
 
     return retPoint;
   }
 
   template<class F>
-  Point3DTyped<TargetUnits, F> operator *(const Point3DTyped<SourceUnits, F>& aPoint) const
+  Point3DTyped<TargetUnits, F> TransformPoint(const Point3DTyped<SourceUnits, F>& aPoint) const
   {
     Point3DTyped<TargetUnits, F> result;
     result.x = aPoint.x * _11 + aPoint.y * _21 + aPoint.z * _31 + _41;
     result.y = aPoint.x * _12 + aPoint.y * _22 + aPoint.z * _32 + _42;
     result.z = aPoint.x * _13 + aPoint.y * _23 + aPoint.z * _33 + _43;
 
     result /= (aPoint.x * _14 + aPoint.y * _24 + aPoint.z * _34 + _44);
 
     return result;
   }
 
   template<class F>
-  PointTyped<TargetUnits, F> operator *(const PointTyped<SourceUnits, F> &aPoint) const
+  PointTyped<TargetUnits, F> TransformPoint(const PointTyped<SourceUnits, F> &aPoint) const
   {
     Point4DTyped<SourceUnits, F> temp(aPoint.x, aPoint.y, 0, 1);
-    Point4DTyped<TargetUnits, F> result = *this * temp;
-    return result.As2DPoint();
+    return TransformPoint(temp).As2DPoint();
   }
 
   template<class F>
   GFX2D_API RectTyped<TargetUnits, F> TransformBounds(const RectTyped<SourceUnits, F>& aRect) const
   {
     Point4DTyped<TargetUnits, F> verts[4];
-    verts[0] = *this * Point4DTyped<SourceUnits, F>(aRect.x, aRect.y, 0.0, 1.0);
-    verts[1] = *this * Point4DTyped<SourceUnits, F>(aRect.XMost(), aRect.y, 0.0, 1.0);
-    verts[2] = *this * Point4DTyped<SourceUnits, F>(aRect.XMost(), aRect.YMost(), 0.0, 1.0);
-    verts[3] = *this * Point4DTyped<SourceUnits, F>(aRect.x, aRect.YMost(), 0.0, 1.0);
+    verts[0] = TransformPoint(Point4DTyped<SourceUnits, F>(aRect.x, aRect.y, 0.0, 1.0));
+    verts[1] = TransformPoint(Point4DTyped<SourceUnits, F>(aRect.XMost(), aRect.y, 0.0, 1.0));
+    verts[2] = TransformPoint(Point4DTyped<SourceUnits, F>(aRect.XMost(), aRect.YMost(), 0.0, 1.0));
+    verts[3] = TransformPoint(Point4DTyped<SourceUnits, F>(aRect.x, aRect.YMost(), 0.0, 1.0));
 
     PointTyped<TargetUnits, F> quad[4];
     F min_x, max_x;
     F min_y, max_y;
 
-    quad[0] = *this * aRect.TopLeft();
-    quad[1] = *this * aRect.TopRight();
-    quad[2] = *this * aRect.BottomLeft();
-    quad[3] = *this * aRect.BottomRight();
+    quad[0] = TransformPoint(aRect.TopLeft());
+    quad[1] = TransformPoint(aRect.TopRight());
+    quad[2] = TransformPoint(aRect.BottomLeft());
+    quad[3] = TransformPoint(aRect.BottomRight());
 
     min_x = max_x = quad[0].x;
     min_y = max_y = quad[0].y;
 
     for (int i = 1; i < 4; i++) {
       if (quad[i].x < min_x) {
         min_x = quad[i].x;
       }
@@ -1502,19 +1501,19 @@ public:
     _33 += -1.0/aDepth * _43;
     _34 += -1.0/aDepth * _44;
   }
 
   Point3D GetNormalVector() const
   {
     // Define a plane in transformed space as the transformations
     // of 3 points on the z=0 screen plane.
-    Point3D a = *this * Point3D(0, 0, 0);
-    Point3D b = *this * Point3D(0, 1, 0);
-    Point3D c = *this * Point3D(1, 0, 0);
+    Point3D a = TransformPoint(Point3D(0, 0, 0));
+    Point3D b = TransformPoint(Point3D(0, 1, 0));
+    Point3D c = TransformPoint(Point3D(1, 0, 0));
 
     // Convert to two vectors on the surface of the plane.
     Point3D ab = b - a;
     Point3D ac = c - a;
 
     return ac.CrossProduct(ab);
   }
 
--- a/gfx/2d/PathCG.cpp
+++ b/gfx/2d/PathCG.cpp
@@ -249,17 +249,17 @@ PathCG::StreamToSink(PathSink *aSink) co
   CGPathApply(mPath, aSink, StreamPathToSinkApplierFunc);
 }
 
 bool
 PathCG::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
 {
   Matrix inverse = aTransform;
   inverse.Invert();
-  Point transformedPoint = inverse*aPoint;
+  Point transformedPoint = inverse.TransformPoint(aPoint);
   // We could probably drop the input transform and just transform the point at the caller?
   CGPoint point = {transformedPoint.x, transformedPoint.y};
 
   // The transform parameter of CGPathContainsPoint doesn't seem to work properly on OS X 10.5
   // so we transform aPoint ourselves.
   return CGPathContainsPoint(mPath, nullptr, point, mFillRule == FillRule::FILL_EVEN_ODD);
 }
 
@@ -289,17 +289,17 @@ ScratchContext()
 
 bool
 PathCG::StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
                             const Point &aPoint,
                             const Matrix &aTransform) const
 {
   Matrix inverse = aTransform;
   inverse.Invert();
-  Point transformedPoint = inverse*aPoint;
+  Point transformedPoint = inverse.TransformPoint(aPoint);
   // We could probably drop the input transform and just transform the point at the caller?
   CGPoint point = {transformedPoint.x, transformedPoint.y};
 
   CGContextRef cg = ScratchContext();
 
   CGContextSaveGState(cg);
 
   CGContextBeginPath(cg);
--- a/gfx/2d/PathCairo.cpp
+++ b/gfx/2d/PathCairo.cpp
@@ -171,41 +171,41 @@ PathCairo::CopyToBuilder(FillRule aFillR
 }
 
 already_AddRefed<PathBuilder>
 PathCairo::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
 {
   RefPtr<PathBuilderCairo> builder = new PathBuilderCairo(aFillRule);
 
   AppendPathToBuilder(builder, &aTransform);
-  builder->mCurrentPoint = aTransform * mCurrentPoint;
+  builder->mCurrentPoint = aTransform.TransformPoint(mCurrentPoint);
 
   return builder.forget();
 }
 
 bool
 PathCairo::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
 {
   Matrix inverse = aTransform;
   inverse.Invert();
-  Point transformed = inverse * aPoint;
+  Point transformed = inverse.TransformPoint(aPoint);
 
   EnsureContainingContext(aTransform);
 
   return cairo_in_fill(mContainingContext, transformed.x, transformed.y);
 }
 
 bool
 PathCairo::StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
                                const Point &aPoint,
                                const Matrix &aTransform) const
 {
   Matrix inverse = aTransform;
   inverse.Invert();
-  Point transformed = inverse * aPoint;
+  Point transformed = inverse.TransformPoint(aPoint);
 
   EnsureContainingContext(aTransform);
 
   SetCairoStrokeOptions(mContainingContext, aStrokeOptions);
 
   return cairo_in_stroke(mContainingContext, transformed.x, transformed.y);
 }
 
@@ -308,17 +308,17 @@ PathCairo::AppendPathToBuilder(PathBuild
   if (aTransform) {
     size_t i = 0;
     while (i < mPathData.size()) {
       uint32_t pointCount = mPathData[i].header.length - 1;
       aBuilder->mPathData.push_back(mPathData[i]);
       i++;
       for (uint32_t c = 0; c < pointCount; c++) {
         cairo_path_data_t data;
-        Point newPoint = *aTransform * Point(mPathData[i].point.x, mPathData[i].point.y);
+        Point newPoint = aTransform->TransformPoint(Point(mPathData[i].point.x, mPathData[i].point.y));
         data.point.x = newPoint.x;
         data.point.y = newPoint.y;
         aBuilder->mPathData.push_back(data);
         i++;
       }
     }
   } else {
     for (size_t i = 0; i < mPathData.size(); i++) {
--- a/gfx/2d/PathD2D.cpp
+++ b/gfx/2d/PathD2D.cpp
@@ -414,17 +414,17 @@ PathD2D::TransformedCopyToBuilder(const 
   }
   if (FAILED(hr)) {
     gfxWarning() << "Failed to simplify PathGeometry to tranformed copy. Code: " << hexa(hr) << " Active: " << mEndedActive;
     return nullptr;
   }
 
   RefPtr<PathBuilderD2D> pathBuilder = new PathBuilderD2D(sink, path, aFillRule, mBackendType);
   
-  pathBuilder->mCurrentPoint = aTransform * mEndPoint;
+  pathBuilder->mCurrentPoint = aTransform.TransformPoint(mEndPoint);
   
   if (mEndedActive) {
     pathBuilder->mFigureActive = true;
   }
 
   return pathBuilder.forget();
 }
 
--- a/gfx/2d/PathHelpers.h
+++ b/gfx/2d/PathHelpers.h
@@ -36,17 +36,19 @@ inline void PartialArcToBezier(T* aSink,
                                Float aKappaFactor = kKappaFactor)
 {
   Point cp1 =
     aStartOffset + Point(-aStartOffset.y, aStartOffset.x) * aKappaFactor;
 
   Point cp2 =
     aEndOffset + Point(aEndOffset.y, -aEndOffset.x) * aKappaFactor;
 
-  aSink->BezierTo(aTransform * cp1, aTransform * cp2, aTransform * aEndOffset);
+  aSink->BezierTo(aTransform.TransformPoint(cp1),
+                  aTransform.TransformPoint(cp2),
+                  aTransform.TransformPoint(aEndOffset));
 }
 
 /**
  * Draws an acute arc (<= 90 degrees) given exact start and end points.
  * Specialized version avoiding kappa calculation.
  */
 template <typename T>
 inline void AcuteArcToBezier(T* aSink,
@@ -105,17 +107,17 @@ void ArcToBezier(T* aSink, const Point &
 
   Float currentStartAngle = aStartAngle;
   Point currentStartOffset(cosf(aStartAngle), sinf(aStartAngle));
   Matrix transform = Matrix::Scaling(aRadius.width, aRadius.height);
   if (aRotation != 0.0f) {
     transform *= Matrix::Rotation(aRotation);
   }
   transform.PostTranslate(aOrigin);
-  aSink->LineTo(transform * currentStartOffset);
+  aSink->LineTo(transform.TransformPoint(currentStartOffset));
 
   while (arcSweepLeft > 0) {
     Float currentEndAngle =
       currentStartAngle + std::min(arcSweepLeft, Float(M_PI / 2.0f)) * sweepDirection;
     Point currentEndOffset(cosf(currentEndAngle), sinf(currentEndAngle));
 
     PartialArcToBezier(aSink, currentStartOffset, currentEndOffset, transform,
                        ComputeKappaFactor(currentEndAngle - currentStartAngle));
@@ -132,17 +134,17 @@ void ArcToBezier(T* aSink, const Point &
  * inlined which vastly simplifies it and avoids a bunch of transcedental function
  * calls which should make it faster. */
 template <typename T>
 void EllipseToBezier(T* aSink, const Point &aOrigin, const Size &aRadius)
 {
   Matrix transform(aRadius.width, 0, 0, aRadius.height, aOrigin.x, aOrigin.y);
   Point currentStartOffset(1, 0);
 
-  aSink->LineTo(transform * currentStartOffset);
+  aSink->LineTo(transform.TransformPoint(currentStartOffset));
 
   for (int i = 0; i < 4; i++) {
     // cos(x+pi/2) == -sin(x)
     // sin(x+pi/2) == cos(x)
     Point currentEndOffset(-currentStartOffset.y, currentStartOffset.x);
 
     PartialArcToBezier(aSink, currentStartOffset, currentEndOffset, transform);
 
@@ -358,19 +360,19 @@ inline bool UserToDevicePixelSnapped(Rec
   if (!aAllowScaleOr90DegreeRotate &&
       (!WITHIN_E(mat._11, 1.f) || !WITHIN_E(mat._22, 1.f) ||
        !WITHIN_E(mat._12, 0.f) || !WITHIN_E(mat._21, 0.f))) {
     // We have non-translation, but only translation is allowed.
     return false;
   }
 #undef WITHIN_E
 
-  Point p1 = mat * aRect.TopLeft();
-  Point p2 = mat * aRect.TopRight();
-  Point p3 = mat * aRect.BottomRight();
+  Point p1 = mat.TransformPoint(aRect.TopLeft());
+  Point p2 = mat.TransformPoint(aRect.TopRight());
+  Point p3 = mat.TransformPoint(aRect.BottomRight());
 
   // Check that the rectangle is axis-aligned. For an axis-aligned rectangle,
   // two opposite corners define the entire rectangle. So check if
   // the axis-aligned rectangle with opposite corners p1 and p3
   // define an axis-aligned rectangle whose other corners are p2 and p4.
   // We actually only need to check one of p2 and p4, since an affine
   // transform maps parallelograms to parallelograms.
   if (p2 == Point(p1.x, p3.y) || p2 == Point(p3.x, p1.y)) {
--- a/gfx/2d/PathRecording.cpp
+++ b/gfx/2d/PathRecording.cpp
@@ -98,23 +98,23 @@ PathRecording::TransformedCopyToBuilder(
 {
   RefPtr<PathBuilder> pathBuilder = mPath->TransformedCopyToBuilder(aTransform, aFillRule);
   RefPtr<PathBuilderRecording> recording = new PathBuilderRecording(pathBuilder, aFillRule);
   typedef std::vector<PathOp> pathOpVec;
   for (pathOpVec::const_iterator iter = mPathOps.begin(); iter != mPathOps.end(); iter++) {
     PathOp newPathOp;
     newPathOp.mType = iter->mType;
     if (sPointCount[newPathOp.mType] >= 1) {
-      newPathOp.mP1 = aTransform * iter->mP1;
+      newPathOp.mP1 = aTransform.TransformPoint(iter->mP1);
     }
     if (sPointCount[newPathOp.mType] >= 2) {
-      newPathOp.mP2 = aTransform * iter->mP2;
+      newPathOp.mP2 = aTransform.TransformPoint(iter->mP2);
     }
     if (sPointCount[newPathOp.mType] >= 3) {
-      newPathOp.mP3 = aTransform * iter->mP3;
+      newPathOp.mP3 = aTransform.TransformPoint(iter->mP3);
     }
     recording->mPathOps.push_back(newPathOp);
   }
   return recording.forget();
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/PathSkia.cpp
+++ b/gfx/2d/PathSkia.cpp
@@ -129,17 +129,17 @@ PathSkia::TransformedCopyToBuilder(const
 static bool
 SkPathContainsPoint(const SkPath& aPath, const Point& aPoint, const Matrix& aTransform)
 {
   Matrix inverse = aTransform;
   if (!inverse.Invert()) {
     return false;
   }
 
-  SkPoint point = PointToSkPoint(inverse * aPoint);
+  SkPoint point = PointToSkPoint(inverse.TransformPoint(aPoint));
   return aPath.contains(point.fX, point.fY);
 }
 
 bool
 PathSkia::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
 {
   if (!mPath.isFinite()) {
     return false;
--- a/gfx/layers/LayerSorter.cpp
+++ b/gfx/layers/LayerSorter.cpp
@@ -41,17 +41,17 @@ enum LayerSortOrder {
  * We want to solve:
  *
  * point = normal . (p0 - l0) / normal . l
  */
 static gfxFloat RecoverZDepth(const Matrix4x4& aTransform, const gfxPoint& aPoint)
 {
     const Point3D l(0, 0, 1);
     Point3D l0 = Point3D(aPoint.x, aPoint.y, 0);
-    Point3D p0 = aTransform * Point3D(0, 0, 0);
+    Point3D p0 = aTransform.TransformPoint(Point3D(0, 0, 0));
     Point3D normal = aTransform.GetNormalVector();
 
     gfxFloat n = normal.DotProduct(p0 - l0); 
     gfxFloat d = normal.DotProduct(l);
 
     if (!d) {
         return 0;
     }
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -682,17 +682,17 @@ Layer::SnapTransformTranslation(const Ma
     // don't snap it.
     // For a perspective transform, the content is transformed in
     // non-linear, so we don't snap it too.
     return aTransform;
   }
 
   // Snap for 3D Transforms
 
-  Point3D transformedOrigin = aTransform * Point3D();
+  Point3D transformedOrigin = aTransform.TransformPoint(Point3D());
 
   // Compute the transformed snap by rounding the values of
   // transformed origin.
   auto transformedSnapXY = IntPoint::Round(transformedOrigin.x, transformedOrigin.y);
   Matrix4x4 inverse = aTransform;
   inverse.Invert();
   // see Matrix4x4::ProjectPoint()
   Float transformedSnapZ =
@@ -701,17 +701,17 @@ Layer::SnapTransformTranslation(const Ma
                               inverse._43) / inverse._33);
   Point3D transformedSnap =
     Point3D(transformedSnapXY.x, transformedSnapXY.y, transformedSnapZ);
   if (transformedOrigin == transformedSnap) {
     return aTransform;
   }
 
   // Compute the snap from the transformed snap.
-  Point3D snap = inverse * transformedSnap;
+  Point3D snap = inverse.TransformPoint(transformedSnap);
   if (snap.z > 0.001 || snap.z < -0.001) {
     // Allow some level of accumulated computation error.
     MOZ_ASSERT(inverse._33 == 0.0);
     return aTransform;
   }
 
   // The difference between the origin and snap is the residual transform.
   if (aResidualTransform) {
@@ -744,19 +744,19 @@ Layer::SnapTransform(const Matrix4x4& aT
   }
 
   Matrix matrix2D;
   Matrix4x4 result;
   if (mManager->IsSnappingEffectiveTransforms() &&
       aTransform.Is2D(&matrix2D) &&
       gfxSize(1.0, 1.0) <= aSnapRect.Size() &&
       matrix2D.PreservesAxisAlignedRectangles()) {
-    auto transformedTopLeft = IntPoint::Round(matrix2D * ToPoint(aSnapRect.TopLeft()));
-    auto transformedTopRight = IntPoint::Round(matrix2D * ToPoint(aSnapRect.TopRight()));
-    auto transformedBottomRight = IntPoint::Round(matrix2D * ToPoint(aSnapRect.BottomRight()));
+    auto transformedTopLeft = IntPoint::Round(matrix2D.TransformPoint(ToPoint(aSnapRect.TopLeft())));
+    auto transformedTopRight = IntPoint::Round(matrix2D.TransformPoint(ToPoint(aSnapRect.TopRight())));
+    auto transformedBottomRight = IntPoint::Round(matrix2D.TransformPoint(ToPoint(aSnapRect.BottomRight())));
 
     Matrix snappedMatrix = gfxUtils::TransformRectToRect(aSnapRect,
       transformedTopLeft, transformedTopRight, transformedBottomRight);
 
     result = Matrix4x4::From2D(snappedMatrix);
     if (aResidualTransform && !snappedMatrix.IsSingular()) {
       // set aResidualTransform so that aResidual * snappedMatrix == matrix2D.
       // (i.e., appying snappedMatrix after aResidualTransform gives the
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1973,22 +1973,21 @@ public:
         mAllowResidualTranslation ? &residual : nullptr);
     // The residual can only be a translation because SnapTransformTranslation
     // only changes the transform if it's a translation
     NS_ASSERTION(residual.IsTranslation(),
                  "Residual transform can only be a translation");
     if (!gfx::ThebesPoint(residual.GetTranslation()).WithinEpsilonOf(mResidualTranslation, 1e-3f)) {
       mResidualTranslation = gfx::ThebesPoint(residual.GetTranslation());
       DebugOnly<mozilla::gfx::Point> transformedOrig =
-        idealTransform * mozilla::gfx::Point();
+        idealTransform.TransformPoint(mozilla::gfx::Point());
 #ifdef DEBUG
-      DebugOnly<mozilla::gfx::Point> transformed =
-        idealTransform * mozilla::gfx::Point(mResidualTranslation.x,
-                                             mResidualTranslation.y) -
-        *&transformedOrig;
+      DebugOnly<mozilla::gfx::Point> transformed = idealTransform.TransformPoint(
+        mozilla::gfx::Point(mResidualTranslation.x, mResidualTranslation.y)
+      ) - *&transformedOrig;
 #endif
       NS_ASSERTION(-0.5 <= (&transformed)->x && (&transformed)->x < 0.5 &&
                    -0.5 <= (&transformed)->y && (&transformed)->y < 0.5,
                    "Residual translation out of range");
       mValidRegion.SetEmpty();
     }
     ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
   }
--- a/gfx/layers/apz/test/gtest/TestHitTesting.cpp
+++ b/gfx/layers/apz/test/gtest/TestHitTesting.cpp
@@ -116,49 +116,49 @@ TEST_F(APZHitTestingTester, HitTesting1)
   uint32_t paintSequenceNumber = 0;
 
   // Now we have a root APZC that will match the page
   SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, paintSequenceNumber++);
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(root), hit.get());
   // expect hit point at LayerIntPoint(15, 15)
-  EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc * ScreenPoint(15, 15));
-  EXPECT_EQ(ScreenPoint(15, 15), transformToGecko * ParentLayerPoint(15, 15));
+  EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc.TransformPoint(ScreenPoint(15, 15)));
+  EXPECT_EQ(ScreenPoint(15, 15), transformToGecko.TransformPoint(ParentLayerPoint(15, 15)));
 
   // Now we have a sub APZC with a better fit
   SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, paintSequenceNumber++);
   EXPECT_NE(ApzcOf(root), ApzcOf(layers[3]));
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(ApzcOf(layers[3]), hit.get());
   // expect hit point at LayerIntPoint(25, 25)
-  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc * ScreenPoint(25, 25));
-  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko * ParentLayerPoint(25, 25));
+  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc.TransformPoint(ScreenPoint(25, 25)));
+  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko.TransformPoint(ParentLayerPoint(25, 25)));
 
   // At this point, layers[4] obscures layers[3] at the point (15, 15) so
   // hitting there should hit the root APZC
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(root), hit.get());
 
   // Now test hit testing when we have two scrollable layers
   SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 2);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, paintSequenceNumber++);
   hit = GetTargetAPZC(ScreenPoint(15, 15));
   EXPECT_EQ(ApzcOf(layers[4]), hit.get());
   // expect hit point at LayerIntPoint(15, 15)
-  EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc * ScreenPoint(15, 15));
-  EXPECT_EQ(ScreenPoint(15, 15), transformToGecko * ParentLayerPoint(15, 15));
+  EXPECT_EQ(ParentLayerPoint(15, 15), transformToApzc.TransformPoint(ScreenPoint(15, 15)));
+  EXPECT_EQ(ScreenPoint(15, 15), transformToGecko.TransformPoint(ParentLayerPoint(15, 15)));
 
   // Hit test ouside the reach of layer[3,4] but inside root
   hit = GetTargetAPZC(ScreenPoint(90, 90));
   EXPECT_EQ(ApzcOf(root), hit.get());
   // expect hit point at LayerIntPoint(90, 90)
-  EXPECT_EQ(ParentLayerPoint(90, 90), transformToApzc * ScreenPoint(90, 90));
-  EXPECT_EQ(ScreenPoint(90, 90), transformToGecko * ParentLayerPoint(90, 90));
+  EXPECT_EQ(ParentLayerPoint(90, 90), transformToApzc.TransformPoint(ScreenPoint(90, 90)));
+  EXPECT_EQ(ScreenPoint(90, 90), transformToGecko.TransformPoint(ParentLayerPoint(90, 90)));
 
   // Hit test ouside the reach of any layer
   hit = GetTargetAPZC(ScreenPoint(1000, 10));
   EXPECT_EQ(nullAPZC, hit.get());
   EXPECT_EQ(ScreenToParentLayerMatrix4x4(), transformToApzc);
   EXPECT_EQ(ParentLayerToScreenMatrix4x4(), transformToGecko);
   hit = GetTargetAPZC(ScreenPoint(-1000, 10));
   EXPECT_EQ(nullAPZC, hit.get());
@@ -183,103 +183,103 @@ TEST_F(APZHitTestingTester, HitTesting2)
 
   TestAsyncPanZoomController* apzcroot = ApzcOf(root);
   TestAsyncPanZoomController* apzc1 = ApzcOf(layers[1]);
   TestAsyncPanZoomController* apzc3 = ApzcOf(layers[3]);
 
   // Hit an area that's clearly on the root layer but not any of the child layers.
   RefPtr<AsyncPanZoomController> hit = GetTargetAPZC(ScreenPoint(75, 25));
   EXPECT_EQ(apzcroot, hit.get());
-  EXPECT_EQ(ParentLayerPoint(75, 25), transformToApzc * ScreenPoint(75, 25));
-  EXPECT_EQ(ScreenPoint(75, 25), transformToGecko * ParentLayerPoint(75, 25));
+  EXPECT_EQ(ParentLayerPoint(75, 25), transformToApzc.TransformPoint(ScreenPoint(75, 25)));
+  EXPECT_EQ(ScreenPoint(75, 25), transformToGecko.TransformPoint(ParentLayerPoint(75, 25)));
 
   // Hit an area on the root that would be on layers[3] if layers[2]
   // weren't transformed.
   // Note that if layers[2] were scrollable, then this would hit layers[2]
   // because its composition bounds would be at (10,60)-(50,100) (and the
   // scale-only transform that we set on layers[2] would be invalid because
   // it would place the layer into overscroll, as its composition bounds
   // start at x=10 but its content at x=20).
   hit = GetTargetAPZC(ScreenPoint(15, 75));
   EXPECT_EQ(apzcroot, hit.get());
-  EXPECT_EQ(ParentLayerPoint(15, 75), transformToApzc * ScreenPoint(15, 75));
-  EXPECT_EQ(ScreenPoint(15, 75), transformToGecko * ParentLayerPoint(15, 75));
+  EXPECT_EQ(ParentLayerPoint(15, 75), transformToApzc.TransformPoint(ScreenPoint(15, 75)));
+  EXPECT_EQ(ScreenPoint(15, 75), transformToGecko.TransformPoint(ParentLayerPoint(15, 75)));
 
   // Hit an area on layers[1].
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(apzc1, hit.get());
-  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc * ScreenPoint(25, 25));
-  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko * ParentLayerPoint(25, 25));
+  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc.TransformPoint(ScreenPoint(25, 25)));
+  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko.TransformPoint(ParentLayerPoint(25, 25)));
 
   // Hit an area on layers[3].
   hit = GetTargetAPZC(ScreenPoint(25, 75));
   EXPECT_EQ(apzc3, hit.get());
   // transformToApzc should unapply layers[2]'s transform
-  EXPECT_EQ(ParentLayerPoint(12.5, 75), transformToApzc * ScreenPoint(25, 75));
+  EXPECT_EQ(ParentLayerPoint(12.5, 75), transformToApzc.TransformPoint(ScreenPoint(25, 75)));
   // and transformToGecko should reapply it
-  EXPECT_EQ(ScreenPoint(25, 75), transformToGecko * ParentLayerPoint(12.5, 75));
+  EXPECT_EQ(ScreenPoint(25, 75), transformToGecko.TransformPoint(ParentLayerPoint(12.5, 75)));
 
   // Hit an area on layers[3] that would be on the root if layers[2]
   // weren't transformed.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzc3, hit.get());
   // transformToApzc should unapply layers[2]'s transform
-  EXPECT_EQ(ParentLayerPoint(37.5, 75), transformToApzc * ScreenPoint(75, 75));
+  EXPECT_EQ(ParentLayerPoint(37.5, 75), transformToApzc.TransformPoint(ScreenPoint(75, 75)));
   // and transformToGecko should reapply it
-  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko * ParentLayerPoint(37.5, 75));
+  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko.TransformPoint(ParentLayerPoint(37.5, 75)));
 
   // Pan the root layer upward by 50 pixels.
   // This causes layers[1] to scroll out of view, and an async transform
   // of -50 to be set on the root layer.
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
 
   // This first pan will move the APZC by 50 pixels, and dispatch a paint request.
   // Since this paint request is in the queue to Gecko, transformToGecko will
   // take it into account.
   ApzcPanNoFling(apzcroot, 100, 50);
 
   // Hit where layers[3] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
-  EXPECT_EQ(ParentLayerPoint(75, 75), transformToApzc * ScreenPoint(75, 75));
+  EXPECT_EQ(ParentLayerPoint(75, 75), transformToApzc.TransformPoint(ScreenPoint(75, 75)));
   // and transformToGecko unapplies it and then reapplies it, because by the
   // time the event being transformed reaches Gecko the new paint request will
   // have been handled.
-  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko * ParentLayerPoint(75, 75));
+  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko.TransformPoint(ParentLayerPoint(75, 75)));
 
   // Hit where layers[1] used to be and where layers[3] should now be.
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(apzc3, hit.get());
   // transformToApzc unapplies both layers[2]'s css transform and the root's
   // async transform
-  EXPECT_EQ(ParentLayerPoint(12.5, 75), transformToApzc * ScreenPoint(25, 25));
+  EXPECT_EQ(ParentLayerPoint(12.5, 75), transformToApzc.TransformPoint(ScreenPoint(25, 25)));
   // transformToGecko reapplies both the css transform and the async transform
   // because we have already issued a paint request with it.
-  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko * ParentLayerPoint(12.5, 75));
+  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko.TransformPoint(ParentLayerPoint(12.5, 75)));
 
   // This second pan will move the APZC by another 50 pixels.
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
   ApzcPanNoFling(apzcroot, 100, 50);
 
   // Hit where layers[3] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(75, 75));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
-  EXPECT_EQ(ParentLayerPoint(75, 75), transformToApzc * ScreenPoint(75, 75));
+  EXPECT_EQ(ParentLayerPoint(75, 75), transformToApzc.TransformPoint(ScreenPoint(75, 75)));
   // transformToGecko unapplies the full async transform of -100 pixels
-  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko * ParentLayerPoint(75, 75));
+  EXPECT_EQ(ScreenPoint(75, 75), transformToGecko.TransformPoint(ParentLayerPoint(75, 75)));
 
   // Hit where layers[1] used to be. It should now hit the root.
   hit = GetTargetAPZC(ScreenPoint(25, 25));
   EXPECT_EQ(apzcroot, hit.get());
   // transformToApzc doesn't unapply the root's own async transform
-  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc * ScreenPoint(25, 25));
+  EXPECT_EQ(ParentLayerPoint(25, 25), transformToApzc.TransformPoint(ScreenPoint(25, 25)));
   // transformToGecko unapplies the full async transform of -100 pixels
-  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko * ParentLayerPoint(25, 25));
+  EXPECT_EQ(ScreenPoint(25, 25), transformToGecko.TransformPoint(ParentLayerPoint(25, 25)));
 }
 
 TEST_F(APZHitTestingTester, ComplexMultiLayerTree) {
   CreateComplexMultiLayerTree();
   ScopedLayerTreeRegistration registration(manager, 0, root, mcc);
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
 
   /* The layer tree looks like this:
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -490,18 +490,18 @@ AsyncCompositionManager::AlignFixedAndSt
         LayerPoint offsetAnchor = anchor + GetLayerFixedMarginsOffset(layer, aFixedLayerMargins);
 
         // Additionally transform the anchor to compensate for the change
         // from the old cumulative transform to the new cumulative transform. We do
         // this by using the old transform to take the offset anchor back into
         // subtree root space, and then the inverse of the new cumulative transform
         // to bring it back to layer space.
         LayerPoint transformedAnchor = ViewAs<LayerPixel>(
-            newCumulativeTransform.Inverse() *
-            (oldCumulativeTransform * offsetAnchor.ToUnknownPoint()));
+            newCumulativeTransform.Inverse().TransformPoint(
+              (oldCumulativeTransform.TransformPoint(offsetAnchor.ToUnknownPoint()))));
 
         // We want to translate the layer by the difference between |transformedAnchor|
         // and |anchor|. To achieve this, we will add a translation to the layer's
         // transform. This translation will apply on top of the layer's local
         // transform, but |anchor| and |transformedAnchor| are in a coordinate space
         // where the local transform isn't applied yet, so apply it and then subtract
         // to get the desired translation.
         auto localTransformTyped = ViewAs<LayerToParentLayerMatrix4x4>(localTransform);
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -276,41 +276,35 @@ gfxMatrix
 gfxContext::CurrentMatrix() const
 {
   return ThebesMatrix(mTransform);
 }
 
 gfxPoint
 gfxContext::DeviceToUser(const gfxPoint& point) const
 {
-  Matrix matrix = mTransform;
-  matrix.Invert();
-  return ThebesPoint(matrix * ToPoint(point));
+  return ThebesPoint(mTransform.Inverse().TransformPoint(ToPoint(point)));
 }
 
 Size
 gfxContext::DeviceToUser(const Size& size) const
 {
-  Matrix matrix = mTransform;
-  matrix.Invert();
-  return matrix * size;
+  return mTransform.Inverse().TransformSize(size);
 }
 
 gfxRect
 gfxContext::DeviceToUser(const gfxRect& rect) const
 {
-  Matrix matrix = mTransform;
-  matrix.Invert();
-  return ThebesRect(matrix.TransformBounds(ToRect(rect)));
+  return ThebesRect(mTransform.Inverse().TransformBounds(ToRect(rect)));
 }
 
 gfxPoint
 gfxContext::UserToDevice(const gfxPoint& point) const
 {
-  return ThebesPoint(mTransform * ToPoint(point));
+  return ThebesPoint(mTransform.TransformPoint(ToPoint(point)));
 }
 
 Size
 gfxContext::UserToDevice(const Size& size) const
 {
   const Matrix &matrix = mTransform;
 
   Size newSize;
@@ -1153,20 +1147,20 @@ gfxContext::ChangeTransform(const Matrix
     Matrix toNewUS = mTransform * invMatrix;
 
     if (toNewUS.IsRectilinear()) {
       mRect = toNewUS.TransformBounds(mRect);
       mRect.NudgeToIntegers();
     } else {
       mPathBuilder = mDT->CreatePathBuilder(FillRule::FILL_WINDING);
 
-      mPathBuilder->MoveTo(toNewUS * mRect.TopLeft());
-      mPathBuilder->LineTo(toNewUS * mRect.TopRight());
-      mPathBuilder->LineTo(toNewUS * mRect.BottomRight());
-      mPathBuilder->LineTo(toNewUS * mRect.BottomLeft());
+      mPathBuilder->MoveTo(toNewUS.TransformPoint(mRect.TopLeft()));
+      mPathBuilder->LineTo(toNewUS.TransformPoint(mRect.TopRight()));
+      mPathBuilder->LineTo(toNewUS.TransformPoint(mRect.BottomRight()));
+      mPathBuilder->LineTo(toNewUS.TransformPoint(mRect.BottomLeft()));
       mPathBuilder->Close();
 
       mPathIsRect = false;
     }
 
     // No need to consider the transform changed now!
     mTransformChanged = false;
   } else if ((mPath || mPathBuilder) && !mTransformChanged) {
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1570,17 +1570,17 @@ public:
     }
 
     void OutputGlyph(uint32_t aGlyphID, const gfxPoint& aPt)
     {
         Glyph *glyph = AppendGlyph();
         glyph->mIndex = aGlyphID;
         glyph->mPosition.x = aPt.x;
         glyph->mPosition.y = aPt.y;
-        glyph->mPosition = mFontParams.matInv * glyph->mPosition;
+        glyph->mPosition = mFontParams.matInv.TransformPoint(glyph->mPosition);
         Flush(false); // this will flush only if the buffer is full
     }
 
     const TextRunDrawParams& mRunParams;
     const FontDrawParams& mFontParams;
 
 private:
 #define GLYPH_BUFFER_SIZE (2048/sizeof(Glyph))
@@ -1761,17 +1761,17 @@ private:
 // doesn't appear bolded, it appears as if a bad text shadow exists
 // when a non-identity transform exists.  Use an offset factor so that
 // the second draw occurs at a constant offset in device pixels.
 
 double
 gfxFont::CalcXScale(DrawTarget* aDrawTarget)
 {
     // determine magnitude of a 1px x offset in device space
-    Size t = aDrawTarget->GetTransform() * Size(1.0, 0.0);
+    Size t = aDrawTarget->GetTransform().TransformSize(Size(1.0, 0.0));
     if (t.width == 1.0 && t.height == 0.0) {
         // short-circuit the most common case to avoid sqrt() and division
         return 1.0;
     }
 
     double m = sqrt(t.width * t.width + t.height * t.height);
 
     NS_ASSERTION(m != 0.0, "degenerate transform while synthetic bolding");
@@ -1829,17 +1829,17 @@ gfxFont::DrawOneGlyph(uint32_t aGlyphID,
             return;
         }
     }
 
     if (fontParams.haveColorGlyphs &&
         RenderColorGlyph(runParams.dt, runParams.context,
                          fontParams.scaledFont, fontParams.renderingOptions,
                          fontParams.drawOptions,
-                         fontParams.matInv * gfx::Point(devPt.x, devPt.y),
+                         fontParams.matInv.TransformPoint(gfx::Point(devPt.x, devPt.y)),
                          aGlyphID)) {
         return;
     }
 
     aBuffer.OutputGlyph(aGlyphID, devPt);
 
     // Synthetic bolding (if required) by multi-striking.
     for (int32_t i = 0; i < fontParams.extraStrikes; ++i) {
--- a/layout/base/UnitTransforms.h
+++ b/layout/base/UnitTransforms.h
@@ -156,17 +156,17 @@ TypedMatrix ViewAs(const gfx::Matrix4x4&
 
 // Convenience functions for transforming an entity from one strongly-typed
 // coordinate system to another using the provided transformation matrix.
 template <typename TargetUnits, typename SourceUnits>
 static gfx::PointTyped<TargetUnits>
 TransformBy(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
             const gfx::PointTyped<SourceUnits>& aPoint)
 {
-  return aTransform * aPoint;
+  return aTransform.TransformPoint(aPoint);
 }
 template <typename TargetUnits, typename SourceUnits>
 static gfx::IntPointTyped<TargetUnits>
 TransformBy(const gfx::Matrix4x4Typed<SourceUnits, TargetUnits>& aTransform,
             const gfx::IntPointTyped<SourceUnits>& aPoint)
 {
   return RoundedToInt(TransformBy(aTransform, gfx::PointTyped<SourceUnits>(aPoint)));
 }
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -6257,17 +6257,17 @@ nsDisplayTransform::GetHitDepthAtPoint(n
 
   Matrix4x4 inverse = matrix;
   inverse.Invert();
   Point4D point = inverse.ProjectPoint(Point(NSAppUnitsToFloatPixels(aPoint.x, factor),
                                              NSAppUnitsToFloatPixels(aPoint.y, factor)));
 
   Point point2d = point.As2DPoint();
 
-  Point3D transformed = matrix * Point3D(point2d.x, point2d.y, 0);
+  Point3D transformed = matrix.TransformPoint(Point3D(point2d.x, point2d.y, 0));
   return transformed.z;
 }
 
 /* The bounding rectangle for the object is the overflow rectangle translated
  * by the reference point.
  */
 nsRect
 nsDisplayTransform::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2683,17 +2683,17 @@ nsLayoutUtils::TransformPoints(nsIFrame*
       aFromFrame->PresContext()->CSSToDevPixelScale();
   CSSToLayoutDeviceScale devPixelsPerCSSPixelToFrame =
       aToFrame->PresContext()->CSSToDevPixelScale();
   for (uint32_t i = 0; i < aPointCount; ++i) {
     LayoutDevicePoint devPixels = aPoints[i] * devPixelsPerCSSPixelFromFrame;
     // What should the behaviour be if some of the points aren't invertible
     // and others are? Just assume all points are for now.
     Point toDevPixels = downToDest.ProjectPoint(
-        (upToAncestor * Point(devPixels.x, devPixels.y))).As2DPoint();
+        (upToAncestor.TransformPoint(Point(devPixels.x, devPixels.y)))).As2DPoint();
     // Divide here so that when the devPixelsPerCSSPixels are the same, we get the correct
     // answer instead of some inaccuracy multiplying a number by its reciprocal.
     aPoints[i] = LayoutDevicePoint(toDevPixels.x, toDevPixels.y) /
         devPixelsPerCSSPixelToFrame;
   }
   return TRANSFORM_SUCCEEDED;
 }
 
@@ -2712,18 +2712,18 @@ nsLayoutUtils::TransformPoint(nsIFrame* 
   downToDest.Invert();
   Matrix4x4 upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor);
 
   float devPixelsPerAppUnitFromFrame =
     1.0f / aFromFrame->PresContext()->AppUnitsPerDevPixel();
   float devPixelsPerAppUnitToFrame =
     1.0f / aToFrame->PresContext()->AppUnitsPerDevPixel();
   Point4D toDevPixels = downToDest.ProjectPoint(
-      upToAncestor * Point(aPoint.x * devPixelsPerAppUnitFromFrame,
-                           aPoint.y * devPixelsPerAppUnitFromFrame));
+      upToAncestor.TransformPoint(Point(aPoint.x * devPixelsPerAppUnitFromFrame,
+                                        aPoint.y * devPixelsPerAppUnitFromFrame)));
   if (!toDevPixels.HasPositiveWCoord()) {
     // Not strictly true, but we failed to get a valid point in this
     // coordinate space.
     return NONINVERTIBLE_TRANSFORM;
   }
   aPoint.x = NSToCoordRound(toDevPixels.x / devPixelsPerAppUnitToFrame);
   aPoint.y = NSToCoordRound(toDevPixels.y / devPixelsPerAppUnitToFrame);
   return TRANSFORM_SUCCEEDED;
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -4222,17 +4222,17 @@ SVGTextFrame::GetEndPositionOfChar(nsICo
     advance = -advance;
   }
 
   // The end position is the start position plus the advance in the direction
   // of the glyph's rotation.
   Matrix m =
     Matrix::Rotation(mPositions[startIndex].mAngle) *
     Matrix::Translation(ToPoint(mPositions[startIndex].mPosition));
-  Point p = m * Point(advance / mFontSizeScaleFactor, 0);
+  Point p = m.TransformPoint(Point(advance / mFontSizeScaleFactor, 0));
 
   NS_ADDREF(*aResult = new DOMSVGPoint(p));
   return NS_OK;
 }
 
 /**
  * Implements the SVG DOM GetExtentOfChar method for the specified
  * text content element.
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -361,17 +361,17 @@ nsSVGPathGeometryFrame::GetFrameForPoint
     SVGContentUtils::AutoStrokeOptions stroke;
     SVGContentUtils::GetStrokeOptions(&stroke, content, StyleContext(), nullptr);
     gfxMatrix userToOuterSVG;
     if (nsSVGUtils::GetNonScalingStrokeTransform(this, &userToOuterSVG)) {
       // We need to transform the path back into the appropriate ancestor
       // coordinate system in order for non-scaled stroke to be correct.
       // Naturally we also need to transform the point into the same
       // coordinate system in order to hit-test against the path.
-      point = ToMatrix(userToOuterSVG) * point;
+      point = ToMatrix(userToOuterSVG).TransformPoint(point);
       RefPtr<PathBuilder> builder =
         path->TransformedCopyToBuilder(ToMatrix(userToOuterSVG), fillRule);
       path = builder->Finish();
     }
     isHit = path->StrokeContainsPoint(stroke, point, Matrix());
   }
 
   if (isHit && nsSVGUtils::HitTestClip(this, aPoint))
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -872,17 +872,17 @@ nsSVGUtils::HitTestRect(const gfx::Matri
                         float aX, float aY)
 {
   gfx::Rect rect(aRX, aRY, aRWidth, aRHeight);
   if (rect.IsEmpty() || aMatrix.IsSingular()) {
     return false;
   }
   gfx::Matrix toRectSpace = aMatrix;
   toRectSpace.Invert();
-  gfx::Point p = toRectSpace * gfx::Point(aX, aY);
+  gfx::Point p = toRectSpace.TransformPoint(gfx::Point(aX, aY));
   return rect.x <= p.x && p.x <= rect.XMost() &&
          rect.y <= p.y && p.y <= rect.YMost();
 }
 
 gfxRect
 nsSVGUtils::GetClipRectForFrame(nsIFrame *aFrame,
                                 float aX, float aY, float aWidth, float aHeight)
 {