Bug 1377169 - Turn gfxRect into a typedef. r=jrmuizel
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 05 Jul 2017 11:22:00 -0400
changeset 418596 5115e2dea29a22fbaac7ad9db8723de762ec4ddd
parent 418595 aacccf77a70555632762651685be6bdfb3dac2e7
child 418597 4d0faee8c20033d1e4d0aacf694b6845ea295d21
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1377169
milestone56.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 1377169 - Turn gfxRect into a typedef. r=jrmuizel One thing to note here is that the Scale function on gfxRect has a different implementation than that in gfx::Rect which is replacing it. The former just scales the width/height directly whereas the latter scales the XMost/YMost and recomputes the width/height. MozReview-Commit-ID: 5FImdIaNfC3
dom/canvas/OffscreenCanvas.h
gfx/layers/LayerSorter.cpp
gfx/thebes/RoundedRect.h
gfx/thebes/gfxASurface.h
gfx/thebes/gfxBlur.h
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxDrawable.h
gfx/thebes/gfxGlyphExtents.h
gfx/thebes/gfxRect.cpp
gfx/thebes/gfxRect.h
gfx/thebes/moz.build
image/ImageRegion.h
image/OrientedImage.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsPresContext.h
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRenderingBorders.cpp
layout/style/StyleAnimationValue.h
layout/style/nsStyleTransformMatrix.h
layout/svg/SVGTextFrame.cpp
layout/svg/nsFilterInstance.cpp
layout/svg/nsSVGForeignObjectFrame.cpp
layout/svg/nsSVGGradientFrame.h
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGPaintServerFrame.h
layout/svg/nsSVGUtils.cpp
widget/FontRange.h
widget/cocoa/nsNativeThemeCocoa.mm
widget/windows/nsNativeThemeWin.cpp
--- a/dom/canvas/OffscreenCanvas.h
+++ b/dom/canvas/OffscreenCanvas.h
@@ -2,16 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_DOM_OFFSCREENCANVAS_H_
 #define MOZILLA_DOM_OFFSCREENCANVAS_H_
 
+#include "gfxTypes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/RefPtr.h"
 #include "CanvasRenderingContextHelper.h"
 #include "nsCycleCollectionParticipant.h"
 
 struct JSContext;
 
--- a/gfx/layers/LayerSorter.cpp
+++ b/gfx/layers/LayerSorter.cpp
@@ -11,16 +11,17 @@
 #include "DirectedGraph.h"              // for DirectedGraph
 #include "Layers.h"                     // for Layer
 #include "gfxEnv.h"                     // for gfxEnv
 #include "gfxLineSegment.h"             // for gfxLineSegment
 #include "gfxPoint.h"                   // for gfxPoint
 #include "gfxQuad.h"                    // for gfxQuad
 #include "gfxRect.h"                    // for gfxRect
 #include "gfxTypes.h"                   // for gfxFloat
+#include "gfxUtils.h"                   // for TransformToQuad
 #include "mozilla/gfx/BasePoint3D.h"    // for BasePoint3D
 #include "mozilla/Sprintf.h"            // for SprintfLiteral
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsTArray, etc
 #include "limits.h"
 #include "mozilla/Assertions.h"
 
 namespace mozilla {
@@ -84,18 +85,18 @@ static LayerSortOrder CompareDepth(Layer
              aTwo->GetParent() && aTwo->GetParent()->Extend3DContext());
   // Effective transform of leaves may had been projected to 2D.
   Matrix4x4 ourTransform =
     aOne->GetLocalTransform() * aOne->GetParent()->GetEffectiveTransform();
   Matrix4x4 otherTransform =
     aTwo->GetLocalTransform() * aTwo->GetParent()->GetEffectiveTransform();
 
   // Transform both rectangles and project into 2d space.
-  gfxQuad ourTransformedRect = ourRect.TransformToQuad(ourTransform);
-  gfxQuad otherTransformedRect = otherRect.TransformToQuad(otherTransform);
+  gfxQuad ourTransformedRect = gfxUtils::TransformToQuad(ourRect, ourTransform);
+  gfxQuad otherTransformedRect = gfxUtils::TransformToQuad(otherRect, otherTransform);
 
   gfxRect ourBounds = ourTransformedRect.GetBounds();
   gfxRect otherBounds = otherTransformedRect.GetBounds();
 
   if (!ourBounds.Intersects(otherBounds)) {
     return Undefined;
   }
 
--- a/gfx/thebes/RoundedRect.h
+++ b/gfx/thebes/RoundedRect.h
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ROUNDED_RECT_H
 #define ROUNDED_RECT_H
 
 #include "gfxRect.h"
+#include "gfxTypes.h"
 #include "mozilla/gfx/PathHelpers.h"
 
 namespace mozilla {
 /* A rounded rectangle abstraction.
  *
  * This can represent a rectangle with a different pair of radii on each corner.
  *
  * Note: CoreGraphics and Direct2D only support rounded rectangle with the same
--- a/gfx/thebes/gfxASurface.h
+++ b/gfx/thebes/gfxASurface.h
@@ -5,25 +5,25 @@
 
 #ifndef GFX_ASURFACE_H
 #define GFX_ASURFACE_H
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/UniquePtr.h"
 
 #include "gfxPoint.h"
+#include "gfxRect.h"
 #include "gfxTypes.h"
 #include "nscore.h"
 #include "nsSize.h"
 #include "mozilla/gfx/Rect.h"
 
 #include "nsStringFwd.h"
 
 class gfxImageSurface;
-struct gfxRect;
 
 template <typename T>
 struct already_AddRefed;
 
 /**
  * A surface is something you can draw on. Instantiate a subclass of this
  * abstract class, and use gfxContext to draw on this surface.
  */
--- a/gfx/thebes/gfxBlur.h
+++ b/gfx/thebes/gfxBlur.h
@@ -2,23 +2,23 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_BLUR_H
 #define GFX_BLUR_H
 
 #include "gfxTypes.h"
+#include "gfxRect.h"
 #include "nsSize.h"
 #include "gfxPoint.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/gfx/Blur.h"
 
 class gfxContext;
-struct gfxRect;
 
 namespace mozilla {
   namespace gfx {
     struct Color;
     struct RectCornerRadii;
     class SourceSurface;
     class DrawTarget;
   } // namespace gfx
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -227,18 +227,17 @@ gfxContext::Rectangle(const gfxRect& rec
   Rect rec = ToRect(rect);
 
   if (snapToPixels) {
     gfxRect newRect(rect);
     if (UserToDevicePixelSnapped(newRect, true)) {
       gfxMatrix mat = ThebesMatrix(mTransform);
       if (mat.Invert()) {
         // We need the user space rect.
-        newRect.TransformBoundsBy(mat);
-        rec = ToRect(newRect);
+        rec = ToRect(mat.TransformBounds(newRect));
       } else {
         rec = Rect();
       }
     }
   }
 
   if (!mPathBuilder && !mPathIsRect) {
     mPathIsRect = true;
--- a/gfx/thebes/gfxDrawable.h
+++ b/gfx/thebes/gfxDrawable.h
@@ -3,18 +3,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_DRAWABLE_H
 #define GFX_DRAWABLE_H
 
 #include "gfxRect.h"
 #include "gfxMatrix.h"
+#include "gfxTypes.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Types.h"
+#include "nsISupportsImpl.h"
 
 class gfxContext;
 class gfxPattern;
 
 /**
  * gfxDrawable
  * An Interface representing something that has an intrinsic size and can draw
  * itself repeatedly.
--- a/gfx/thebes/gfxGlyphExtents.h
+++ b/gfx/thebes/gfxGlyphExtents.h
@@ -2,23 +2,23 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_GLYPHEXTENTS_H
 #define GFX_GLYPHEXTENTS_H
 
 #include "gfxFont.h"
+#include "gfxRect.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 #include "mozilla/MemoryReporting.h"
 
 class gfxContext;
-struct gfxRect;
 
 namespace mozilla {
 namespace gfx {
 class DrawTarget;
 } // namespace gfx
 } // namespace mozilla
 
 /**
deleted file mode 100644
--- a/gfx/thebes/gfxRect.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "gfxRect.h"
-
-#include "nsMathUtils.h"
-
-#include "mozilla/gfx/Matrix.h"
-
-#include "gfxQuad.h"
-
-gfxQuad
-gfxRect::TransformToQuad(const mozilla::gfx::Matrix4x4 &aMatrix) const
-{
-  gfxPoint points[4];
-
-  points[0] = aMatrix.TransformPoint(TopLeft());
-  points[1] = aMatrix.TransformPoint(TopRight());
-  points[2] = aMatrix.TransformPoint(BottomRight());
-  points[3] = aMatrix.TransformPoint(BottomLeft());
-
-  // Could this ever result in lines that intersect? I don't think so.
-  return gfxQuad(points[0], points[1], points[2], points[3]);
-}
-
-void
-gfxRect::TransformBy(const mozilla::gfx::MatrixDouble& aMatrix)
-{
-  *this = gfxRect(aMatrix.TransformPoint(TopLeft()),
-                  aMatrix.TransformSize(Size()));
-}
-
-void
-gfxRect::TransformBoundsBy(const mozilla::gfx::MatrixDouble& aMatrix)
-{
-  RectDouble tmp(x, y, width, height);
-  tmp = aMatrix.TransformBounds(tmp);
-  x = tmp.x;
-  y = tmp.y;
-  width = tmp.width;
-  height = tmp.height;
-}
-
-static bool
-WithinEpsilonOfInteger(gfxFloat aX, gfxFloat aEpsilon)
-{
-    return fabs(NS_round(aX) - aX) <= fabs(aEpsilon);
-}
-
-bool
-gfxRect::WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const
-{
-    NS_ASSERTION(-0.5 < aEpsilon && aEpsilon < 0.5, "Nonsense epsilon value");
-    return (WithinEpsilonOfInteger(x, aEpsilon) &&
-            WithinEpsilonOfInteger(y, aEpsilon) &&
-            WithinEpsilonOfInteger(width, aEpsilon) &&
-            WithinEpsilonOfInteger(height, aEpsilon));
-}
-
-/* Clamp r to CAIRO_COORD_MIN .. CAIRO_COORD_MAX
- * these are to be device coordinates.
- *
- * Cairo is currently using 24.8 fixed point,
- * so -2^24 .. 2^24-1 is our valid
- */
-
-#define CAIRO_COORD_MAX (16777215.0)
-#define CAIRO_COORD_MIN (-16777216.0)
-
-void
-gfxRect::Condition()
-{
-    // if either x or y is way out of bounds;
-    // note that we don't handle negative w/h here
-    if (x > CAIRO_COORD_MAX) {
-        x = CAIRO_COORD_MAX;
-        width = 0.0;
-    } 
-
-    if (y > CAIRO_COORD_MAX) {
-        y = CAIRO_COORD_MAX;
-        height = 0.0;
-    }
-
-    if (x < CAIRO_COORD_MIN) {
-        width += x - CAIRO_COORD_MIN;
-        if (width < 0.0)
-            width = 0.0;
-        x = CAIRO_COORD_MIN;
-    }
-
-    if (y < CAIRO_COORD_MIN) {
-        height += y - CAIRO_COORD_MIN;
-        if (height < 0.0)
-            height = 0.0;
-        y = CAIRO_COORD_MIN;
-    }
-
-    if (x + width > CAIRO_COORD_MAX) {
-        width = CAIRO_COORD_MAX - x;
-    }
-
-    if (y + height > CAIRO_COORD_MAX) {
-        height = CAIRO_COORD_MAX - y;
-    }
-}
-
--- a/gfx/thebes/gfxRect.h
+++ b/gfx/thebes/gfxRect.h
@@ -1,114 +1,14 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_RECT_H
 #define GFX_RECT_H
 
-#include "gfxTypes.h"
-#include "gfxPoint.h"
-#include "nsDebug.h"
-#include "nsRect.h"
-#include "mozilla/gfx/BaseMargin.h"
-#include "mozilla/gfx/BaseRect.h"
-#include "mozilla/gfx/MatrixFwd.h"
 #include "mozilla/gfx/Rect.h"
-#include "mozilla/Assertions.h"
-
-struct gfxQuad;
 
 typedef mozilla::gfx::MarginDouble gfxMargin;
-
-struct gfxRect :
-    public mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> {
-    typedef mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super;
-
-    gfxRect() : Super() {}
-    gfxRect(const gfxPoint& aPos, const gfxSize& aSize) :
-        Super(aPos, aSize) {}
-    gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) :
-        Super(aX, aY, aWidth, aHeight) {}
-
-    /**
-     * Return true if all components of this rect are within
-     * aEpsilon of integer coordinates, defined as
-     *   |round(coord) - coord| <= |aEpsilon|
-     * for x,y,width,height.
-     */
-    bool WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const;
-
-    gfxPoint AtCorner(mozilla::Corner corner) const {
-        switch (corner) {
-            case mozilla::eCornerTopLeft: return TopLeft();
-            case mozilla::eCornerTopRight: return TopRight();
-            case mozilla::eCornerBottomRight: return BottomRight();
-            case mozilla::eCornerBottomLeft: return BottomLeft();
-        }
-        return gfxPoint(0.0, 0.0);
-    }
-
-    gfxPoint CCWCorner(mozilla::Side side) const {
-        switch (side) {
-            case mozilla::eSideTop: return TopLeft();
-            case mozilla::eSideRight: return TopRight();
-            case mozilla::eSideBottom: return BottomRight();
-            case mozilla::eSideLeft: return BottomLeft();
-        }
-        MOZ_CRASH("Incomplete switch");
-    }
-
-    gfxPoint CWCorner(mozilla::Side side) const {
-        switch (side) {
-            case mozilla::eSideTop: return TopRight();
-            case mozilla::eSideRight: return BottomRight();
-            case mozilla::eSideBottom: return BottomLeft();
-            case mozilla::eSideLeft: return TopLeft();
-        }
-        MOZ_CRASH("Incomplete switch");
-    }
-
-    /* Conditions this border to Cairo's max coordinate space.
-     * The caller can check IsEmpty() after Condition() -- if it's TRUE,
-     * the caller can possibly avoid doing any extra rendering.
-     */
-    void Condition();
-
-    void Scale(gfxFloat k) {
-        NS_ASSERTION(k >= 0.0, "Invalid (negative) scale factor");
-        x *= k;
-        y *= k;
-        width *= k;
-        height *= k;
-    }
-
-    void Scale(gfxFloat sx, gfxFloat sy) {
-        NS_ASSERTION(sx >= 0.0, "Invalid (negative) scale factor");
-        NS_ASSERTION(sy >= 0.0, "Invalid (negative) scale factor");
-        x *= sx;
-        y *= sy;
-        width *= sx;
-        height *= sy;
-    }
-
-    void ScaleInverse(gfxFloat k) {
-        NS_ASSERTION(k > 0.0, "Invalid (negative) scale factor");
-        x /= k;
-        y /= k;
-        width /= k;
-        height /= k;
-    }
-
-    /*
-     * Transform this rectangle with aMatrix, resulting in a gfxQuad.
-     */
-    gfxQuad TransformToQuad(const mozilla::gfx::Matrix4x4 &aMatrix) const;
-
-    // Some temporary functions that we need until gfxRect gets turned into a
-    // typedef for RectDouble. It would be simpler to put these in Matrix.h
-    // but that code shouldn't #include gfxRect.h so we put it here instead.
-    void TransformBy(const mozilla::gfx::MatrixDouble& aMatrix);
-    void TransformBoundsBy(const mozilla::gfx::MatrixDouble& aMatrix);
-};
+typedef mozilla::gfx::RectDouble gfxRect;
 
 #endif /* GFX_RECT_H */
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -195,17 +195,16 @@ UNIFIED_SOURCES += [
     'gfxGlyphExtents.cpp',
     'gfxGradientCache.cpp',
     'gfxGraphiteShaper.cpp',
     'gfxHarfBuzzShaper.cpp',
     'gfxImageSurface.cpp',
     'gfxMathTable.cpp',
     'gfxPattern.cpp',
     'gfxPlatformFontList.cpp',
-    'gfxRect.cpp',
     'gfxScriptItemizer.cpp',
     'gfxSkipChars.cpp',
     'gfxSVGGlyphs.cpp',
     'gfxTextRun.cpp',
     'gfxUserFontSet.cpp',
     'gfxUtils.cpp',
     'nsUnicodeRange.cpp',
     'SoftwareVsyncSource.cpp',
--- a/image/ImageRegion.h
+++ b/image/ImageRegion.h
@@ -105,27 +105,27 @@ public:
     mRect.Scale(sx, sy);
     if (mIsRestricted) {
       mRestriction.Scale(sx, sy);
     }
   }
 
   void TransformBy(const gfxMatrix& aMatrix)
   {
-    mRect.TransformBy(aMatrix);
+    mRect = aMatrix.TransformRect(mRect);
     if (mIsRestricted) {
-      mRestriction.TransformBy(aMatrix);
+      mRestriction = aMatrix.TransformRect(mRestriction);
     }
   }
 
   void TransformBoundsBy(const gfxMatrix& aMatrix)
   {
-    mRect.TransformBoundsBy(aMatrix);
+    mRect = aMatrix.TransformBounds(mRect);
     if (mIsRestricted) {
-      mRestriction.TransformBoundsBy(aMatrix);
+      mRestriction = aMatrix.TransformBounds(mRestriction);
     }
   }
 
   ImageRegion operator-(const gfxPoint& aPt) const
   {
     if (mIsRestricted) {
       return CreateWithSamplingRestriction(mRect - aPt, mRestriction - aPt);
     }
--- a/image/OrientedImage.cpp
+++ b/image/OrientedImage.cpp
@@ -359,17 +359,17 @@ OrientedImage::GetImageSpaceInvalidation
   rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&innerSize.height);
   if (NS_FAILED(rv)) {
     // Fall back to identity if the width and height aren't available.
     return rect;
   }
 
   // Transform the invalidation rect into the correct orientation.
   gfxMatrix matrix(OrientationMatrix(innerSize));
-  gfxRect invalidRect(rect.x, rect.y, rect.width, rect.height);
-  invalidRect.TransformBoundsBy(matrix);
+  gfxRect invalidRect(matrix.TransformBounds(gfxRect(rect.x, rect.y,
+                                                     rect.width, rect.height)));
 
   return IntRect::RoundOut(invalidRect.x, invalidRect.y,
                            invalidRect.width, invalidRect.height);
 }
 
 } // namespace image
 } // namespace mozilla
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6582,29 +6582,25 @@ ComputeSnappedImageDrawingParameters(gfx
   // filtering will occur, and restricting the fill rect to the dirty rect
   // would change the values computed for edge pixels, which we can't allow.
   // Also, if 'didSnap' is false then rounding out 'devPixelDirty' might not
   // produce pixel-aligned coordinates, which would also break the values
   // computed for edge pixels.
   if (didSnap && !invTransform.HasNonIntegerTranslation()) {
     // This form of Transform is safe to call since non-axis-aligned
     // transforms wouldn't be snapped.
-    devPixelDirty.TransformBy(currentMatrix);
+    devPixelDirty = currentMatrix.TransformRect(devPixelDirty);
     devPixelDirty.RoundOut();
     fill = fill.Intersect(devPixelDirty);
   }
   if (fill.IsEmpty())
     return SnappedImageDrawingParameters();
 
-  gfxRect imageSpaceFill = fill;
-  if (didSnap) {
-    imageSpaceFill.TransformBy(invTransform);
-  } else {
-    imageSpaceFill.TransformBoundsBy(invTransform);
-  }
+  gfxRect imageSpaceFill(didSnap ? invTransform.TransformRect(fill)
+                                 : invTransform.TransformBounds(fill));
 
   // If we didn't snap, we need to post-multiply the matrix on the context to
   // get the final matrix we'll draw with, because we didn't take it into
   // account when computing the matrices above.
   if (!didSnap) {
     transform = transform * currentMatrix;
   }
 
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -24,17 +24,17 @@
 #include "nsITimer.h"
 #include "nsCRT.h"
 #include "nsIWidgetListener.h"
 #include "nsLanguageAtomService.h"
 #include "nsGkAtoms.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsChangeHint.h"
 #include <algorithm>
-// This also pulls in gfxTypes.h, which we cannot include directly.
+#include "gfxTypes.h"
 #include "gfxRect.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/AppUnits.h"
 #include "prclist.h"
 #include "nsThreadUtils.h"
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2329,17 +2329,17 @@ SetupImageLayerClip(nsCSSRendering::Imag
   // Do not do this if we have a caller-provided clip rect --
   // as above with bgArea, arguably a bug, but table painting seems
   // to depend on it.
 
   if (aClipState.mHasAdditionalBGClipArea) {
     gfxRect bgAreaGfx = nsLayoutUtils::RectToGfxRect(
       aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
     bgAreaGfx.Round();
-    bgAreaGfx.Condition();
+    gfxUtils::ConditionRect(bgAreaGfx);
 
     aAutoSR->EnsureSaved(aCtx);
     aCtx->NewPath();
     aCtx->Rectangle(bgAreaGfx, true);
     aCtx->Clip();
   }
 
   if (aClipState.mHasRoundedCorners) {
@@ -2403,17 +2403,17 @@ DrawBackgroundColor(nsCSSRendering::Imag
   aCtx->NewPath();
   aCtx->Rectangle(dirty, true);
   aCtx->Clip();
 
   if (aClipState.mHasAdditionalBGClipArea) {
     gfxRect bgAdditionalAreaGfx = nsLayoutUtils::RectToGfxRect(
       aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
     bgAdditionalAreaGfx.Round();
-    bgAdditionalAreaGfx.Condition();
+    gfxUtils::ConditionRect(bgAdditionalAreaGfx);
     aCtx->NewPath();
     aCtx->Rectangle(bgAdditionalAreaGfx, true);
     aCtx->Clip();
   }
 
   RefPtr<Path> roundedRect =
     MakePathForRoundedRect(*drawTarget, bgAreaGfx, aClipState.mClippedRadii);
   aCtx->SetPath(roundedRect);
@@ -4282,25 +4282,24 @@ nsContextBoxBlur::Init(const nsRect& aRe
   // Convert from app units to device pixels
   gfxRect rect = nsLayoutUtils::RectToGfxRect(aRect, aAppUnitsPerDevPixel);
 
   gfxRect dirtyRect =
     nsLayoutUtils::RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel);
   dirtyRect.RoundOut();
 
   gfxMatrix transform = aDestinationCtx->CurrentMatrix();
-  rect.TransformBoundsBy(transform);
+  rect = transform.TransformBounds(rect);
 
   mPreTransformed = !transform.IsIdentity();
 
   // Create the temporary surface for blurring
-  dirtyRect.TransformBoundsBy(transform);
+  dirtyRect = transform.TransformBounds(dirtyRect);
   if (aSkipRect) {
-    gfxRect skipRect = *aSkipRect;
-    skipRect.TransformBoundsBy(transform);
+    gfxRect skipRect = transform.TransformBounds(*aSkipRect);
     mContext = mAlphaBoxBlur.Init(aDestinationCtx, rect, spreadRadius,
                                   blurRadius, &dirtyRect, &skipRect);
   } else {
     mContext = mAlphaBoxBlur.Init(aDestinationCtx, rect, spreadRadius,
                                   blurRadius, &dirtyRect, nullptr);
   }
 
   if (mContext) {
@@ -4393,21 +4392,19 @@ nsContextBoxBlur::BlurRectangle(gfxConte
   }
 
   gfxPoint blurStdDev = ComputeBlurStdDev(aBlurRadius, aAppUnitsPerDevPixel, scaleX, scaleY);
 
   gfxRect dirtyRect =
     nsLayoutUtils::RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel);
   dirtyRect.RoundOut();
 
-  gfxRect shadowThebesRect = ThebesRect(shadowGfxRect);
-  shadowThebesRect.TransformBoundsBy(transform);
-  dirtyRect.TransformBoundsBy(transform);
-  gfxRect skipRect = aSkipRect;
-  skipRect.TransformBoundsBy(transform);
+  gfxRect shadowThebesRect = transform.TransformBounds(ThebesRect(shadowGfxRect));
+  dirtyRect = transform.TransformBounds(dirtyRect);
+  gfxRect skipRect = transform.TransformBounds(aSkipRect);
 
   if (aCornerRadii) {
     aCornerRadii->Scale(scaleX, scaleY);
   }
 
   gfxAlphaBoxBlur::BlurRectangle(aDestinationCtx,
                                  shadowThebesRect,
                                  aCornerRadii,
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3338,23 +3338,23 @@ nsCSSBorderRenderer::DrawBorders()
   PrintAsString(" mOuterRect: "); PrintAsString(mOuterRect); PrintAsStringNewline();
   PrintAsString(" mInnerRect: "); PrintAsString(mInnerRect); PrintAsStringNewline();
   PrintAsFormatString(" mBorderColors: 0x%08x 0x%08x 0x%08x 0x%08x\n", mBorderColors[0], mBorderColors[1], mBorderColors[2], mBorderColors[3]);
 
   // if conditioning the outside rect failed, then bail -- the outside
   // rect is supposed to enclose the entire border
   {
     gfxRect outerRect = ThebesRect(mOuterRect);
-    outerRect.Condition();
+    gfxUtils::ConditionRect(outerRect);
     if (outerRect.IsEmpty())
       return;
     mOuterRect = ToRect(outerRect);
 
     gfxRect innerRect = ThebesRect(mInnerRect);
-    innerRect.Condition();
+    gfxUtils::ConditionRect(innerRect);
     mInnerRect = ToRect(innerRect);
   }
 
   int dashedSides = 0;
 
   NS_FOR_CSS_SIDES(i) {
     uint8_t style = mBorderStyles[i];
     if (style == NS_STYLE_BORDER_STYLE_DASHED ||
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Utilities for animation of computed style values */
 
 #ifndef mozilla_StyleAnimationValue_h_
 #define mozilla_StyleAnimationValue_h_
 
+#include "gfxPoint.h"
 #include "mozilla/gfx/MatrixFwd.h"
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/UniquePtr.h"
 #include "nsStringFwd.h"
 #include "nsStringBuffer.h"
 #include "nsCoord.h"
 #include "nsColor.h"
 #include "nsCSSProps.h"
--- a/layout/style/nsStyleTransformMatrix.h
+++ b/layout/style/nsStyleTransformMatrix.h
@@ -5,19 +5,21 @@
 
 /*
  * A class representing three matrices that can be used for style transforms.
  */
 
 #ifndef nsStyleTransformMatrix_h_
 #define nsStyleTransformMatrix_h_
 
+#include "gfxPoint.h"
 #include "mozilla/gfx/Matrix.h"
 #include "mozilla/EnumeratedArray.h"
 #include "nsCSSValue.h"
+#include "nsSize.h"
 
 #include <limits>
 
 class nsIFrame;
 class nsStyleContext;
 class nsPresContext;
 struct gfxQuaternion;
 struct nsRect;
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -994,37 +994,33 @@ SVGBBox
 TextRenderedRun::GetFrameUserSpaceRect(nsPresContext* aContext,
                                        uint32_t aFlags) const
 {
   SVGBBox r = GetRunUserSpaceRect(aContext, aFlags);
   if (r.IsEmpty()) {
     return r;
   }
   gfxMatrix m = GetTransformFromRunUserSpaceToFrameUserSpace(aContext);
-  gfxRect thebesRect = r.ToThebesRect();
-  thebesRect.TransformBoundsBy(m);
-  return thebesRect;
+  return m.TransformBounds(r.ToThebesRect());
 }
 
 SVGBBox
 TextRenderedRun::GetUserSpaceRect(nsPresContext* aContext,
                                   uint32_t aFlags,
                                   const gfxMatrix* aAdditionalTransform) const
 {
   SVGBBox r = GetRunUserSpaceRect(aContext, aFlags);
   if (r.IsEmpty()) {
     return r;
   }
   gfxMatrix m = GetTransformFromRunUserSpaceToUserSpace(aContext);
   if (aAdditionalTransform) {
     m *= *aAdditionalTransform;
   }
-  gfxRect thebesRect = r.ToThebesRect();
-  thebesRect.TransformBoundsBy(m);
-  return thebesRect;
+  return m.TransformBounds(r.ToThebesRect());
 }
 
 void
 TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge,
                               nscoord& aVisIEndEdge) const
 {
   uint32_t contentLength = mFrame->GetContentLength();
   if (mTextFrameContentOffset == 0 &&
@@ -3623,18 +3619,18 @@ SVGTextFrame::PaintSVG(gfxContext& aCont
                      aDirtyRect->width, aDirtyRect->height);
 
     gfxFloat appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
     gfxRect frameRect(mRect.x / appUnitsPerDevPixel,
                       mRect.y / appUnitsPerDevPixel,
                       mRect.width / appUnitsPerDevPixel,
                       mRect.height / appUnitsPerDevPixel);
 
-    frameRect.TransformBoundsBy(GetCanvasTM());
-    nsRect canvasRect = nsLayoutUtils::RoundGfxRectToAppRect(frameRect, 1);
+    nsRect canvasRect = nsLayoutUtils::RoundGfxRectToAppRect(
+        GetCanvasTM().TransformBounds(frameRect), 1);
     if (!canvasRect.Intersects(dirtyRect)) {
       return;
     }
   }
 
   // SVG frames' PaintSVG methods paint in CSS px, but normally frames paint in
   // dev pixels. Here we multiply a CSS-px-to-dev-pixel factor onto aTransform
   // so our non-SVG nsTextFrame children paint correctly.
@@ -4296,18 +4292,17 @@ SVGTextFrame::GetExtentOfChar(nsIContent
   } else {
     glyphRect =
       gfxRect(x, -presContext->AppUnitsToGfxUnits(ascent) * cssPxPerDevPx,
               advance,
               presContext->AppUnitsToGfxUnits(ascent + descent) * cssPxPerDevPx);
   }
 
   // Transform the glyph's rect into user space.
-  glyphRect.TransformBoundsBy(m);
-  gfxRect r = glyphRect;
+  gfxRect r = m.TransformBounds(glyphRect);
 
   NS_ADDREF(*aResult = new dom::SVGRect(aContent, r.x, r.y, r.width, r.height));
   return NS_OK;
 }
 
 /**
  * Implements the SVG DOM GetRotationOfChar method for the specified
  * text content element.
@@ -5565,18 +5560,17 @@ SVGTextFrame::TransformFrameRectFromText
                      TextRenderedRun::eIncludeStroke;
 
     if (rectInFrameUserSpace.IntersectRect(rectInFrameUserSpace,
         run.GetFrameUserSpaceRect(presContext, flags).ToThebesRect())) {
       // Transform it up to user space of the <text>, also taking into
       // account the font size scale.
       gfxMatrix m = run.GetTransformFromRunUserSpaceToUserSpace(presContext);
       m.PreScale(mFontSizeScaleFactor, mFontSizeScaleFactor);
-      gfxRect rectInUserSpace = rectInFrameUserSpace;
-      rectInUserSpace.TransformBy(m);
+      gfxRect rectInUserSpace = m.TransformRect(rectInFrameUserSpace);
 
       // Union it into the result.
       result.UnionRect(result, rectInUserSpace);
     }
   }
 
   // Subtract the mRect offset from the result, as our user space for
   // this frame is relative to the top-left of mRect.
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -553,35 +553,35 @@ nsFilterInstance::FrameSpaceToFilterSpac
 {
   nsIntRect rect = OutputFilterSpaceBounds();
   if (aRect) {
     if (aRect->IsEmpty()) {
       return nsIntRect();
     }
     gfxRect rectInCSSPx =
       nsLayoutUtils::RectToGfxRect(*aRect, nsPresContext::AppUnitsPerCSSPixel());
-    gfxRect rectInFilterSpace = rectInCSSPx;
-    rectInFilterSpace.TransformBoundsBy(mFrameSpaceInCSSPxToFilterSpaceTransform);
+    gfxRect rectInFilterSpace =
+      mFrameSpaceInCSSPxToFilterSpaceTransform.TransformBounds(rectInCSSPx);
     rectInFilterSpace.RoundOut();
     nsIntRect intRect;
     if (gfxUtils::GfxRectToIntRect(rectInFilterSpace, &intRect)) {
       rect = intRect;
     }
   }
   return rect;
 }
 
 nsRect
 nsFilterInstance::FilterSpaceToFrameSpace(const nsIntRect& aRect) const
 {
   if (aRect.IsEmpty()) {
     return nsRect();
   }
   gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
-  r.TransformBoundsBy(mFilterSpaceToFrameSpaceInCSSPxTransform);
+  r = mFilterSpaceToFrameSpaceInCSSPxTransform.TransformBounds(r);
   // nsLayoutUtils::RoundGfxRectToAppRect rounds out.
   return nsLayoutUtils::RoundGfxRectToAppRect(r, nsPresContext::AppUnitsPerCSSPixel());
 }
 
 nsIntRegion
 nsFilterInstance::FrameSpaceToFilterSpace(const nsRegion* aRegion) const
 {
   if (!aRegion) {
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -229,17 +229,17 @@ nsSVGForeignObjectFrame::PaintSVG(gfxCon
                  "Display lists handle dirty rect intersection test");
     // Transform the dirty rect into app units in our userspace.
     gfxMatrix invmatrix = aTransform;
     DebugOnly<bool> ok = invmatrix.Invert();
     NS_ASSERTION(ok, "inverse of non-singular matrix should be non-singular");
 
     gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y,
                                      aDirtyRect->width, aDirtyRect->height);
-    transDirtyRect.TransformBoundsBy(invmatrix);
+    transDirtyRect = invmatrix.TransformBounds(transDirtyRect);
 
     kidDirtyRect.IntersectRect(kidDirtyRect,
       nsLayoutUtils::RoundGfxRectToAppRect(transDirtyRect,
                        PresContext()->AppUnitsPerCSSPixel()));
 
     // XXX after bug 614732 is fixed, we will compare mRect with aDirtyRect,
     // not with kidDirtyRect. I.e.
     // int32_t appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
--- a/layout/svg/nsSVGGradientFrame.h
+++ b/layout/svg/nsSVGGradientFrame.h
@@ -3,30 +3,29 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGGRADIENTFRAME_H__
 #define __NS_SVGGRADIENTFRAME_H__
 
 #include "mozilla/Attributes.h"
 #include "gfxMatrix.h"
+#include "gfxRect.h"
 #include "nsCOMPtr.h"
 #include "nsFrame.h"
 #include "nsLiteralString.h"
 #include "nsSVGPaintServerFrame.h"
 
 class gfxPattern;
 class nsIAtom;
 class nsIContent;
 class nsIFrame;
 class nsIPresShell;
 class nsStyleContext;
 
-struct gfxRect;
-
 namespace mozilla {
 class nsSVGAnimatedTransformList;
 
 namespace dom {
 class SVGLinearGradientElement;
 class SVGRadialGradientElement;
 } // namespace dom
 } // namespace mozilla
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -1213,17 +1213,17 @@ nsSVGIntegrationUtils::DrawableFromPaint
     // aFrame is either a pattern or a gradient. These fill the whole target
     // frame by default, so aPaintServerSize is the whole target background fill
     // area.
     nsSVGPaintServerFrame* server =
       static_cast<nsSVGPaintServerFrame*>(aFrame);
 
     gfxRect overrideBounds(0, 0,
                            aPaintServerSize.width, aPaintServerSize.height);
-    overrideBounds.ScaleInverse(aFrame->PresContext()->AppUnitsPerDevPixel());
+    overrideBounds.Scale(1.0 / aFrame->PresContext()->AppUnitsPerDevPixel());
     imgDrawingParams imgParams(aFlags);
     RefPtr<gfxPattern> pattern =
       server->GetPaintServerPattern(aTarget, aDrawTarget,
                                     aContextMatrix, &nsStyleSVG::mFill, 1.0,
                                     imgParams, &overrideBounds);
 
     if (!pattern)
       return nullptr;
--- a/layout/svg/nsSVGPaintServerFrame.h
+++ b/layout/svg/nsSVGPaintServerFrame.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGPAINTSERVERFRAME_H__
 #define __NS_SVGPAINTSERVERFRAME_H__
 
+#include "gfxRect.h"
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsFrame.h"
 #include "nsIFrame.h"
 #include "nsQueryFrame.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGUtils.h"
 
@@ -19,18 +20,16 @@ namespace gfx {
 class DrawTarget;
 } // namespace gfx
 } // namespace mozilla
 
 class gfxContext;
 class gfxPattern;
 class nsStyleContext;
 
-struct gfxRect;
-
 /**
  * RAII class used to temporarily set and remove the
  * NS_FRAME_DRAWING_AS_PAINTSERVER frame state bit while a frame is being
  * drawn as a paint server.
  */
 class MOZ_RAII AutoSetRestorePaintServerState
 {
 public:
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -466,19 +466,18 @@ public:
 
     // aDirtyRect is in user-space pixels, we need to convert to
     // outer-SVG-frame-relative device pixels.
     if (aDirtyRect) {
       gfxMatrix userToDeviceSpace = aTransform;
       if (userToDeviceSpace.IsSingular()) {
         return;
       }
-      gfxRect dirtyBounds =
-        gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height);
-      dirtyBounds.TransformBoundsBy(userToDeviceSpace);
+      gfxRect dirtyBounds = userToDeviceSpace.TransformBounds(
+        gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height));
       dirtyBounds.RoundOut();
       if (gfxUtils::GfxRectToIntRect(dirtyBounds, &tmpDirtyRect)) {
         dirtyRect = &tmpDirtyRect;
       }
     }
 
     svgFrame->PaintSVG(aContext, nsSVGUtils::GetCSSPxToDevPxMatrix(aTarget),
                        aImgParams, dirtyRect);
@@ -839,19 +838,19 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
       // aDirtyRect is in outer-<svg> device pixels, but the filter code needs
       // it in frame space.
       gfxMatrix userToDeviceSpace = aTransform;
       if (userToDeviceSpace.IsSingular()) {
         return;
       }
       gfxMatrix deviceToUserSpace = userToDeviceSpace;
       deviceToUserSpace.Invert();
-      gfxRect dirtyBounds = gfxRect(aDirtyRect->x, aDirtyRect->y,
-                                    aDirtyRect->width, aDirtyRect->height);
-      dirtyBounds.TransformBoundsBy(deviceToUserSpace);
+      gfxRect dirtyBounds = deviceToUserSpace.TransformBounds(
+                              gfxRect(aDirtyRect->x, aDirtyRect->y,
+                                      aDirtyRect->width, aDirtyRect->height));
       tmpDirtyRegion =
         nsLayoutUtils::RoundGfxRectToAppRect(
           dirtyBounds, aFrame->PresContext()->AppUnitsPerCSSPixel()) -
         aFrame->GetPosition();
       dirtyRegion = &tmpDirtyRegion;
     }
 
     SVGPaintCallback paintCallback;
@@ -964,18 +963,18 @@ nsSVGUtils::HitTestChildren(nsSVGDisplay
 
 nsRect
 nsSVGUtils::TransformFrameRectToOuterSVG(const nsRect& aRect,
                                          const gfxMatrix& aMatrix,
                                          nsPresContext* aPresContext)
 {
   gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
   r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel());
-  r.TransformBoundsBy(aMatrix);
-  return nsLayoutUtils::RoundGfxRectToAppRect(r, aPresContext->AppUnitsPerDevPixel());
+  return nsLayoutUtils::RoundGfxRectToAppRect(
+    aMatrix.TransformBounds(r), aPresContext->AppUnitsPerDevPixel());
 }
 
 IntSize
 nsSVGUtils::ConvertToSurfaceSize(const gfxSize& aSize,
                                  bool *aResultOverflows)
 {
   IntSize surfaceSize(ClampToInt(ceil(aSize.width)), ClampToInt(ceil(aSize.height)));
 
@@ -1149,17 +1148,17 @@ nsSVGUtils::GetBBox(nsIFrame* aFrame, ui
     y = fillBBox.y;
     width = fillBBox.width;
     height = fillBBox.height;
     bool hasClip = aFrame->StyleDisplay()->IsScrollableOverflow();
     if (hasClip) {
       clipRect =
         nsSVGUtils::GetClipRectForFrame(aFrame, x, y, width, height);
       if (aFrame->IsSVGForeignObjectFrame() || aFrame->IsSVGUseFrame()) {
-        clipRect.TransformBoundsBy(matrix);
+        clipRect = matrix.TransformBounds(clipRect);
       }
     }
     nsSVGEffects::EffectProperties effectProperties =
       nsSVGEffects::GetEffectProperties(aFrame);
     if (effectProperties.HasInvalidClipPath()) {
       bbox = gfxRect(0, 0, 0, 0);
     } else {
       nsSVGClipPathFrame *clipPathFrame =
@@ -1883,20 +1882,18 @@ nsSVGUtils::GetSVGGlyphExtents(Element* 
   return true;
 }
 
 nsRect
 nsSVGUtils::ToCanvasBounds(const gfxRect &aUserspaceRect,
                            const gfxMatrix &aToCanvas,
                            const nsPresContext *presContext)
 {
-  gfxRect userspaceRect = aUserspaceRect;
-  userspaceRect.TransformBoundsBy(aToCanvas);
   return nsLayoutUtils::RoundGfxRectToAppRect(
-                          userspaceRect,
+                          aToCanvas.TransformBounds(aUserspaceRect),
                           presContext->AppUnitsPerDevPixel());
 }
 
 gfxMatrix
 nsSVGUtils::GetCSSPxToDevPxMatrix(nsIFrame* aNonSVGFrame)
 {
   int32_t appUnitsPerDevPixel = aNonSVGFrame->PresContext()->AppUnitsPerDevPixel();
   float devPxPerCSSPx =
--- a/widget/FontRange.h
+++ b/widget/FontRange.h
@@ -2,16 +2,18 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_FontRange_h_
 #define mozilla_FontRange_h_
 
+#include "gfxTypes.h" // for gfxFloat
+
 namespace mozilla {
 
 struct FontRange
 {
   FontRange()
     : mStartOffset(0)
     , mFontSize(0)
   {
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2289,17 +2289,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
 
   DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
 
   // setup to draw into the correct port
   int32_t p2a = aFrame->PresContext()->AppUnitsPerDevPixel();
 
   gfx::Rect nativeDirtyRect = NSRectToRect(aDirtyRect, p2a);
   gfxRect nativeWidgetRect(aRect.x, aRect.y, aRect.width, aRect.height);
-  nativeWidgetRect.ScaleInverse(gfxFloat(p2a));
+  nativeWidgetRect.Scale(1.0 / gfxFloat(p2a));
   float nativeWidgetHeight = round(nativeWidgetRect.Height());
   nativeWidgetRect.Round();
   if (nativeWidgetRect.IsEmpty())
     return NS_OK; // Don't attempt to draw invisible widgets.
 
   AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
 
   bool hidpi = IsHiDPIContext(aFrame->PresContext()->DeviceContext());
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -1449,18 +1449,18 @@ nsNativeThemeWin::DrawWidgetBackground(g
   }
 
   gfxFloat p2a = gfxFloat(aFrame->PresContext()->AppUnitsPerDevPixel());
   RECT widgetRect;
   RECT clipRect;
   gfxRect tr(aRect.x, aRect.y, aRect.width, aRect.height),
           dr(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
 
-  tr.ScaleInverse(p2a * themeScale);
-  dr.ScaleInverse(p2a * themeScale);
+  tr.Scale(1.0 / (p2a * themeScale));
+  dr.Scale(1.0 / (p2a * themeScale));
 
   gfxWindowsNativeDrawing nativeDrawing(ctx, dr, GetWidgetNativeDrawingFlags(aWidgetType));
 
 RENDER_AGAIN:
 
   HDC hdc = nativeDrawing.BeginNativeDrawing();
   if (!hdc)
     return NS_ERROR_FAILURE;
@@ -3445,18 +3445,18 @@ nsresult nsNativeThemeWin::ClassicDrawWi
     return NS_OK;
   }
 
   gfxFloat p2a = gfxFloat(aFrame->PresContext()->AppUnitsPerDevPixel());
   RECT widgetRect;
   gfxRect tr(aRect.x, aRect.y, aRect.width, aRect.height),
           dr(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
 
-  tr.ScaleInverse(p2a);
-  dr.ScaleInverse(p2a);
+  tr.Scale(1.0 / p2a);
+  dr.Scale(1.0 / p2a);
 
   RefPtr<gfxContext> ctx = aContext;
 
   gfxWindowsNativeDrawing nativeDrawing(ctx, dr, GetWidgetNativeDrawingFlags(aWidgetType));
 
 RENDER_AGAIN:
 
   HDC hdc = nativeDrawing.BeginNativeDrawing();