Bug 1025553, part 6 - Remove gfxMatrix::Multiply(). r=Bas
authorJonathan Watt <jwatt@jwatt.org>
Fri, 11 Jul 2014 08:07:07 +0100
changeset 207341 fb2ab91ddd34477e3e00eabee861935e3d5c6b5f
parent 207340 2d724821fb523fa3e67692e1eaf1a74979f49866
child 207342 b336c6598bf14dc67ccc9c2d8989964adcbde5a8
push idunknown
push userunknown
push dateunknown
reviewersBas
bugs1025553
milestone33.0a1
Bug 1025553, part 6 - Remove gfxMatrix::Multiply(). r=Bas
gfx/thebes/gfxDrawable.cpp
gfx/thebes/gfxMatrix.cpp
gfx/thebes/gfxMatrix.h
gfx/thebes/gfxUtils.cpp
image/src/ClippedImage.cpp
image/src/RasterImage.cpp
image/src/imgFrame.cpp
layout/svg/SVGTextFrame.cpp
layout/svg/nsSVGGradientFrame.cpp
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGUtils.cpp
--- a/gfx/thebes/gfxDrawable.cpp
+++ b/gfx/thebes/gfxDrawable.cpp
@@ -52,17 +52,17 @@ DeviceToImageTransform(gfxContext* aCont
     nsRefPtr<gfxASurface> currentTarget =
         aContext->CurrentSurface(&deviceX, &deviceY);
     gfxMatrix currentMatrix = aContext->CurrentMatrix();
     gfxMatrix deviceToUser = currentMatrix;
     if (!deviceToUser.Invert()) {
         return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
     }
     deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
-    return gfxMatrix(deviceToUser).Multiply(aUserSpaceToImageSpace);
+    return deviceToUser * aUserSpaceToImageSpace;
 }
 
 static void
 PreparePatternForUntiledDrawing(gfxPattern* aPattern,
                                 const gfxMatrix& aDeviceToImage,
                                 gfxASurface *currentTarget,
                                 const GraphicsFilter aDefaultFilter)
 {
@@ -154,17 +154,17 @@ gfxSurfaceDrawable::Draw(gfxContext* aCo
           filter = GraphicsFilter::FILTER_FAST;
         }
         nsRefPtr<gfxASurface> currentTarget = aContext->CurrentSurface();
         gfxMatrix deviceSpaceToImageSpace =
             DeviceToImageTransform(aContext, aTransform);
         PreparePatternForUntiledDrawing(pattern, deviceSpaceToImageSpace,
                                         currentTarget, filter);
     }
-    pattern->SetMatrix(gfxMatrix(aTransform).Multiply(mTransform));
+    pattern->SetMatrix(aTransform * mTransform);
     aContext->NewPath();
     aContext->SetPattern(pattern);
     aContext->Rectangle(aFillRect);
     aContext->Fill();
     // clear the pattern so that the snapshot is released before the
     // drawable is destroyed
     aContext->SetDeviceColor(gfxRGBA(0.0, 0.0, 0.0, 0.0));
     return true;
@@ -292,15 +292,15 @@ gfxPatternDrawable::Draw(gfxContext* aCo
         // will happen through this Draw() method with aRepeat = false.
         nsRefPtr<gfxCallbackDrawable> callbackDrawable = MakeCallbackDrawable();
         return callbackDrawable->Draw(aContext, aFillRect, true, aFilter,
                                       aTransform);
     }
 
     aContext->NewPath();
     gfxMatrix oldMatrix = mPattern->GetMatrix();
-    mPattern->SetMatrix(gfxMatrix(aTransform).Multiply(oldMatrix));
+    mPattern->SetMatrix(aTransform * oldMatrix);
     aContext->SetPattern(mPattern);
     aContext->Rectangle(aFillRect);
     aContext->Fill();
     mPattern->SetMatrix(oldMatrix);
     return true;
 }
--- a/gfx/thebes/gfxMatrix.cpp
+++ b/gfx/thebes/gfxMatrix.cpp
@@ -40,17 +40,17 @@ gfxMatrix::Translate(const gfxPoint& pt)
 const gfxMatrix&
 gfxMatrix::Rotate(gfxFloat radians)
 {
     cairo_matrix_rotate(CAIRO_MATRIX(this), radians);
     return *this;
 }
 
 const gfxMatrix&
-gfxMatrix::Multiply(const gfxMatrix& m)
+gfxMatrix::operator *= (const gfxMatrix& m)
 {
     cairo_matrix_multiply(CAIRO_MATRIX(this), CAIRO_MATRIX(this), CONST_CAIRO_MATRIX(&m));
     return *this;
 }
 
 const gfxMatrix&
 gfxMatrix::PreMultiply(const gfxMatrix& m)
 {
--- a/gfx/thebes/gfxMatrix.h
+++ b/gfx/thebes/gfxMatrix.h
@@ -48,25 +48,23 @@ public:
     gfxMatrix(gfxFloat a, gfxFloat b, gfxFloat c, gfxFloat d, gfxFloat tx, gfxFloat ty) :
         _11(a),  _12(b),
         _21(c),  _22(d),
         _31(tx), _32(ty) { }
 
     /**
      * Post-multiplies m onto the matrix.
      */
-    const gfxMatrix& operator *= (const gfxMatrix& m) {
-        return Multiply(m);
-    }
+    const gfxMatrix& operator *= (const gfxMatrix& m);
 
     /**
      * Multiplies *this with m and returns the result.
      */
     gfxMatrix operator * (const gfxMatrix& m) const {
-        return gfxMatrix(*this).Multiply(m);
+        return gfxMatrix(*this) *= m;
     }
 
     /* Returns true if the other matrix is fuzzy-equal to this matrix.
      * Note that this isn't a cheap comparison!
      */
     bool operator==(const gfxMatrix& other) const
     {
       return FuzzyEqual(_11, other._11) && FuzzyEqual(_12, other._12) &&
@@ -123,25 +121,16 @@ public:
     /**
      * Rotates this matrix. The rotation is pre-multiplied onto this matrix,
      * i.e. the translation takes place after the other transformations.
      *
      * @param radians Angle in radians.
      */
     const gfxMatrix& Rotate(gfxFloat radians);
 
-     /**
-      * Multiplies the current matrix with m.
-      * This is a post-multiplication, i.e. the transformations of m are
-      * applied _after_ the existing transformations.
-      *
-      * XXX is that difference (compared to Rotate etc) a good thing?
-      */
-    const gfxMatrix& Multiply(const gfxMatrix& m);
-
     /**
      * Multiplies the current matrix with m.
      * This is a pre-multiplication, i.e. the transformations of m are
      * applied _before_ the existing transformations.
      */
     const gfxMatrix& PreMultiply(const gfxMatrix& m);
 
     static gfxMatrix Translation(gfxFloat aX, gfxFloat aY)
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -496,17 +496,17 @@ DeviceToImageTransform(gfxContext* aCont
     nsRefPtr<gfxASurface> currentTarget =
         aContext->CurrentSurface(&deviceX, &deviceY);
     gfxMatrix currentMatrix = aContext->CurrentMatrix();
     gfxMatrix deviceToUser = currentMatrix;
     if (!deviceToUser.Invert()) {
         return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
     }
     deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
-    return gfxMatrix(deviceToUser).Multiply(aUserSpaceToImageSpace);
+    return deviceToUser * aUserSpaceToImageSpace;
 }
 
 /* These heuristics are based on Source/WebCore/platform/graphics/skia/ImageSkia.cpp:computeResamplingMode() */
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
 static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter,
                                              int aImgWidth, int aImgHeight,
                                              float aSourceWidth, float aSourceHeight)
 {
--- a/image/src/ClippedImage.cpp
+++ b/image/src/ClippedImage.cpp
@@ -383,29 +383,28 @@ ClippedImage::DrawSingleTile(gfxContext*
   if (NS_SUCCEEDED(InnerImage()->GetWidth(&imgWidth)) &&
       NS_SUCCEEDED(InnerImage()->GetHeight(&imgHeight))) {
     viewportSize = nsIntSize(imgWidth, imgHeight);
   } else {
     MOZ_ASSERT(false, "If ShouldClip() led us to draw then we should never get here");
   }
 
   // Add a translation to the transform to reflect the clipping region.
-  gfxMatrix transform(aUserSpaceToImageSpace);
-  transform.Multiply(gfxMatrix().Translate(gfxPoint(mClip.x, mClip.y)));
+  gfxMatrix transform =
+    aUserSpaceToImageSpace * gfxMatrix::Translation(mClip.x, mClip.y);
 
   // "Clamp the source rectangle" to the clipping region's width and height.
   // Really, this means modifying the transform to get the results we want.
   gfxRect sourceRect = transform.Transform(aFill);
   if (sourceRect.width > mClip.width || sourceRect.height > mClip.height) {
-    gfxMatrix clampSource;
-    clampSource.Translate(gfxPoint(sourceRect.x, sourceRect.y));
+    gfxMatrix clampSource = gfxMatrix::Translation(sourceRect.TopLeft());
     clampSource.Scale(ClampFactor(sourceRect.width, mClip.width),
                       ClampFactor(sourceRect.height, mClip.height));
-    clampSource.Translate(gfxPoint(-sourceRect.x, -sourceRect.y));
-    transform.Multiply(clampSource);
+    clampSource.Translate(-sourceRect.TopLeft());
+    transform *= clampSource;
   }
 
   return InnerImage()->Draw(aContext, aFilter, transform, aFill, aSubimage,
                             viewportSize, aSVGContext, aWhichFrame, aFlags);
 }
 
 NS_IMETHODIMP
 ClippedImage::RequestDiscard()
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -2618,18 +2618,17 @@ RasterImage::DrawWithPreDownscaleIfNeede
     // for each RasterImage.
     bool needScaleReq;
     if (mScaleResult.status == SCALE_DONE && mScaleResult.scale == scale) {
       // Grab and hold the surface to make sure the OS didn't destroy it
       surf = mScaleResult.frame->GetSurface();
       needScaleReq = !surf;
       if (surf) {
         frame = mScaleResult.frame;
-        userSpaceToImageSpace.Multiply(gfxMatrix().Scale(scale.width,
-                                                         scale.height));
+        userSpaceToImageSpace *= gfxMatrix::Scaling(scale.width, scale.height);
 
         // Since we're switching to a scaled image, we need to transform the
         // area of the subimage to draw accordingly, since imgFrame::Draw()
         // doesn't know about scaled frames.
         subimage.ScaleRoundOut(scale.width, scale.height);
       }
     } else {
       needScaleReq = !(mScaleResult.status == SCALE_PENDING &&
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -360,17 +360,17 @@ imgFrame::SurfaceForDrawing(bool        
   // padding and/or a partial decode just by twiddling parameters.
   // First, update our user-space fill rect.
   aSourceRect = aSourceRect.Intersect(available);
   gfxMatrix imageSpaceToUserSpace = aUserSpaceToImageSpace;
   imageSpaceToUserSpace.Invert();
   aFill = imageSpaceToUserSpace.Transform(aSourceRect);
 
   aSubimage = aSubimage.Intersect(available) - gfxPoint(aPadding.left, aPadding.top);
-  aUserSpaceToImageSpace.Multiply(gfxMatrix().Translate(-gfxPoint(aPadding.left, aPadding.top)));
+  aUserSpaceToImageSpace *= gfxMatrix::Translation(-aPadding.left, -aPadding.top);
   aSourceRect = aSourceRect - gfxPoint(aPadding.left, aPadding.top);
   aImageRect = gfxRect(0, 0, mSize.width, mSize.height);
 
   gfxIntSize availableSize(mDecoded.width, mDecoded.height);
   return SurfaceWithFormat(new gfxSurfaceDrawable(aSurface, availableSize),
                            mFormat);
 }
 
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -970,17 +970,17 @@ TextRenderedRun::GetUserSpaceRect(nsPres
                                   const gfxMatrix* aAdditionalTransform) const
 {
   SVGBBox r = GetRunUserSpaceRect(aContext, aFlags);
   if (r.IsEmpty()) {
     return r;
   }
   gfxMatrix m = GetTransformFromRunUserSpaceToUserSpace(aContext);
   if (aAdditionalTransform) {
-    m.Multiply(*aAdditionalTransform);
+    m *= *aAdditionalTransform;
   }
   return m.TransformBounds(r.ToThebesRect());
 }
 
 void
 TextRenderedRun::GetClipEdges(nscoord& aLeftEdge, nscoord& aRightEdge) const
 {
   uint32_t contentLength = mFrame->GetContentLength();
@@ -3589,18 +3589,17 @@ SVGTextFrame::PaintSVG(nsRenderingContex
   }
 
   gfxMatrix canvasTM = GetCanvasTM(FOR_PAINTING, aTransformRoot);
   if (canvasTM.IsSingular()) {
     NS_WARNING("Can't render text element!");
     return NS_ERROR_FAILURE;
   }
 
-  gfxMatrix matrixForPaintServers(canvasTM);
-  matrixForPaintServers.Multiply(initialMatrix);
+  gfxMatrix matrixForPaintServers = canvasTM * initialMatrix;
 
   // Check if we need to draw anything.
   if (aDirtyRect) {
     NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                  (mState & NS_FRAME_IS_NONDISPLAY),
                  "Display lists handle dirty rect intersection test");
     nsRect dirtyRect(aDirtyRect->x, aDirtyRect->y,
                      aDirtyRect->width, aDirtyRect->height);
@@ -3653,18 +3652,18 @@ SVGTextFrame::PaintSVG(nsRenderingContex
     nsAutoPtr<gfxTextContextPaint> contextPaint;
     DrawMode drawMode =
       SetupCairoState(gfx, frame, outerContextPaint,
                       getter_Transfers(contextPaint));
 
     // Set up the transform for painting the text frame for the substring
     // indicated by the run.
     gfxMatrix runTransform =
-      run.GetTransformFromUserSpaceForPainting(presContext, item);
-    runTransform.Multiply(currentMatrix);
+      run.GetTransformFromUserSpaceForPainting(presContext, item) *
+      currentMatrix;
     gfx->SetMatrix(runTransform);
 
     if (drawMode != DrawMode(0)) {
       nsRect frameRect = frame->GetVisualOverflowRect();
       bool paintSVGGlyphs;
       if (ShouldRenderAsPath(aContext, frame, paintSVGGlyphs)) {
         SVGTextDrawPathCallbacks callbacks(aContext, frame,
                                            matrixForPaintServers,
@@ -3713,18 +3712,18 @@ SVGTextFrame::GetFrameForPoint(const nsP
   TextRenderedRunIterator it(this);
   nsIFrame* hit = nullptr;
   for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) {
     uint16_t hitTestFlags = nsSVGUtils::GetGeometryHitTestFlags(run.mFrame);
     if (!(hitTestFlags & (SVG_HIT_TEST_FILL | SVG_HIT_TEST_STROKE))) {
       continue;
     }
 
-    gfxMatrix m = GetCanvasTM(FOR_HIT_TESTING);
-    m.PreMultiply(run.GetTransformFromRunUserSpaceToUserSpace(presContext));
+    gfxMatrix m = run.GetTransformFromRunUserSpaceToUserSpace(presContext) *
+                    GetCanvasTM(FOR_HIT_TESTING);
     if (!m.Invert()) {
       return nullptr;
     }
 
     gfxPoint pointInRunUserSpace = m.Transform(pointInOuterSVGUserUnits);
     gfxRect frameRect =
       run.GetRunUserSpaceRect(presContext, TextRenderedRun::eIncludeFill |
                                            TextRenderedRun::eIncludeStroke).ToThebesRect();
@@ -5446,19 +5445,18 @@ SVGTextFrame::TransformFrameRectToTextCh
                              aChildFrame);
   for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) {
     // Convert the incoming rect into frame user space.
     gfxMatrix userSpaceToRunUserSpace =
       run.GetTransformFromRunUserSpaceToUserSpace(presContext);
     if (!userSpaceToRunUserSpace.Invert()) {
       return result;
     }
-    gfxMatrix m;
-    m.PreMultiply(userSpaceToRunUserSpace);
-    m.PreMultiply(run.GetTransformFromRunUserSpaceToFrameUserSpace(presContext));
+    gfxMatrix m = run.GetTransformFromRunUserSpaceToFrameUserSpace(presContext) *
+                    userSpaceToRunUserSpace;
     gfxRect incomingRectInFrameUserSpace =
       m.TransformBounds(incomingRectInUserSpace);
 
     // Intersect it with this run's rectangle.
     uint32_t flags = TextRenderedRun::eIncludeFill |
                      TextRenderedRun::eIncludeStroke;
     SVGBBox runRectInFrameUserSpace = run.GetFrameUserSpaceRect(presContext, flags);
     if (runRectInFrameUserSpace.IsEmpty()) {
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -263,17 +263,17 @@ nsSVGGradientFrame::GetPaintServerPatter
   }
 
   // revert the vector effect transform so that the gradient appears unchanged
   if (aFillOrStroke == &nsStyleSVG::mStroke) {
     gfxMatrix nonScalingStrokeTM = nsSVGUtils::GetStrokeTransform(aSource);
     if (!nonScalingStrokeTM.Invert()) {
       return nullptr;
     }
-    patternMatrix.Multiply(nonScalingStrokeTM);
+    patternMatrix *= nonScalingStrokeTM;
   }
 
   if (!patternMatrix.Invert()) {
     return nullptr;
   }
 
   nsRefPtr<gfxPattern> gradient = CreateGradient();
   if (!gradient || gradient->CairoStatus())
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -706,18 +706,18 @@ nsSVGIntegrationUtils::DrawableFromPaint
 
     // pattern is now set up to fill aPaintServerSize. But we want it to
     // fill aRenderSize, so we need to add a scaling transform.
     // We couldn't just have set overrideBounds to aRenderSize - it would have
     // worked for gradients, but for patterns it would result in a different
     // pattern size.
     gfxFloat scaleX = overrideBounds.Width() / aRenderSize.width;
     gfxFloat scaleY = overrideBounds.Height() / aRenderSize.height;
-    gfxMatrix scaleMatrix = gfxMatrix().Scale(scaleX, scaleY);
-    pattern->SetMatrix(scaleMatrix.Multiply(pattern->GetMatrix()));
+    gfxMatrix scaleMatrix = gfxMatrix::Scaling(scaleX, scaleY);
+    pattern->SetMatrix(scaleMatrix * pattern->GetMatrix());
     nsRefPtr<gfxDrawable> drawable =
       new gfxPatternDrawable(pattern, aRenderSize);
     return drawable.forget();
   }
 
   // We don't want to paint into a surface as long as we don't need to, so we
   // set up a drawing callback.
   nsRefPtr<gfxDrawingCallback> cb =
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1120,18 +1120,17 @@ static gfxRect
 PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
                               nsIFrame* aFrame,
                               double aStyleExpansionFactor,
                               const gfxMatrix& aMatrix)
 {
   double style_expansion =
     aStyleExpansionFactor * nsSVGUtils::GetStrokeWidth(aFrame);
 
-  gfxMatrix matrix = aMatrix;
-  matrix.Multiply(nsSVGUtils::GetStrokeTransform(aFrame));
+  gfxMatrix matrix = aMatrix * nsSVGUtils::GetStrokeTransform(aFrame);
 
   double dx = style_expansion * (fabs(matrix._11) + fabs(matrix._21));
   double dy = style_expansion * (fabs(matrix._22) + fabs(matrix._12));
 
   gfxRect strokeExtents = aPathExtents;
   strokeExtents.Inflate(dx, dy);
   return strokeExtents;
 }