Expose RectToGfxRect on nsLayoutUtils. (Bug 459144, patch 10) r=roc a2.0=blocking:beta6+
authorL. David Baron <dbaron@dbaron.org>
Tue, 07 Sep 2010 15:20:35 -0700
changeset 52135 6a28138050f5ab3fdf4f17a8758d80afa2e88d47
parent 52134 433efb14d970b425841ad356ab9da36c37bb7183
child 52136 ebabfab36a6f83c956130b245937c99c419413a0
push id15552
push userdbaron@mozilla.com
push dateTue, 07 Sep 2010 22:22:17 +0000
treeherdermozilla-central@ebabfab36a6f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs459144
milestone2.0b6pre
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
Expose RectToGfxRect on nsLayoutUtils. (Bug 459144, patch 10) r=roc a2.0=blocking:beta6+
layout/base/nsCSSRendering.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -452,26 +452,16 @@ MakeBevelColor(mozilla::css::Side whichS
     break;
   }
   return theColor;
 }
 
 //----------------------------------------------------------------------
 // Thebes Border Rendering Code Start
 
-// helper function to convert a nsRect to a gfxRect
-static gfxRect
-RectToGfxRect(const nsRect& rect, nscoord twipsPerPixel)
-{
-  return gfxRect(gfxFloat(rect.x) / twipsPerPixel,
-                 gfxFloat(rect.y) / twipsPerPixel,
-                 gfxFloat(rect.width) / twipsPerPixel,
-                 gfxFloat(rect.height) / twipsPerPixel);
-}
-
 /*
  * Compute the float-pixel radii that should be used for drawing
  * this border/outline, given the various input bits.
  */
 /* static */ void
 nsCSSRendering::ComputePixelRadii(const nscoord *aAppUnitsRadii,
                                   nscoord aAppUnitsPerPixel,
                                   gfxCornerSizes *oBorderRadii)
@@ -592,17 +582,17 @@ nsCSSRendering::PaintBorderWithStyleBord
   SF(" outerRect: %d %d %d %d\n", outerRect.x, outerRect.y, outerRect.width, outerRect.height);
 
   // we can assume that we're already clipped to aDirtyRect -- I think? (!?)
 
   // Get our conversion values
   nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
 
   // convert outer and inner rects
-  gfxRect oRect(RectToGfxRect(outerRect, twipsPerPixel));
+  gfxRect oRect(nsLayoutUtils::RectToGfxRect(outerRect, twipsPerPixel));
 
   // convert the border widths
   gfxFloat borderWidths[4] = { gfxFloat(border.top / twipsPerPixel),
                                gfxFloat(border.right / twipsPerPixel),
                                gfxFloat(border.bottom / twipsPerPixel),
                                gfxFloat(border.left / twipsPerPixel) };
 
   // convert the radii
@@ -744,17 +734,17 @@ nsCSSRendering::PaintOutline(nsPresConte
   // get the radius for our outline
   nsIFrame::ComputeBorderRadii(ourOutline->mOutlineRadius, aBorderArea.Size(),
                                outerRect.Size(), 0, twipsRadii);
 
   // Get our conversion values
   nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
 
   // get the outer rectangles
-  gfxRect oRect(RectToGfxRect(outerRect, twipsPerPixel));
+  gfxRect oRect(nsLayoutUtils::RectToGfxRect(outerRect, twipsPerPixel));
 
   // convert the radii
   nsMargin outlineMargin(width, width, width, width);
   gfxCornerSizes outlineRadii;
   ComputePixelRadii(twipsRadii, twipsPerPixel, &outlineRadii);
 
   PRUint8 outlineStyle = ourOutline->GetOutlineStyle();
   PRUint8 outlineStyles[4] = { outlineStyle,
@@ -802,17 +792,17 @@ void
 nsCSSRendering::PaintFocus(nsPresContext* aPresContext,
                            nsIRenderingContext& aRenderingContext,
                            const nsRect& aFocusRect,
                            nscolor aColor)
 {
   nscoord oneCSSPixel = nsPresContext::CSSPixelsToAppUnits(1);
   nscoord oneDevPixel = aPresContext->DevPixelsToAppUnits(1);
 
-  gfxRect focusRect(RectToGfxRect(aFocusRect, oneDevPixel));
+  gfxRect focusRect(nsLayoutUtils::RectToGfxRect(aFocusRect, oneDevPixel));
 
   gfxCornerSizes focusRadii;
   {
     nscoord twipsRadii[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
     ComputePixelRadii(twipsRadii, oneDevPixel, &focusRadii);
   }
   gfxFloat focusWidths[4] = { gfxFloat(oneCSSPixel / oneDevPixel),
                               gfxFloat(oneCSSPixel / oneDevPixel),
@@ -1117,33 +1107,33 @@ nsCSSRendering::PaintBoxShadowOuter(nsPr
     hasBorderRadius = aForFrame->GetBorderRadii(twipsRadii);
     if (hasBorderRadius) {
       ComputePixelRadii(twipsRadii, twipsPerPixel, &borderRadii);
     }
   }
 
   nsRect frameRect =
     nativeTheme ? aForFrame->GetOverflowRectRelativeToSelf() + aFrameArea.TopLeft() : aFrameArea;
-  gfxRect frameGfxRect = RectToGfxRect(frameRect, twipsPerPixel);
+  gfxRect frameGfxRect(nsLayoutUtils::RectToGfxRect(frameRect, twipsPerPixel));
   frameGfxRect.Round();
 
   // We don't show anything that intersects with the frame we're blurring on. So tell the
   // blurrer not to do unnecessary work there.
   gfxRect skipGfxRect = frameGfxRect;
   PRBool useSkipGfxRect = PR_TRUE;
   if (nativeTheme) {
     // Optimize non-leaf native-themed frames by skipping computing pixels
     // in the padding-box. We assume the padding-box is going to be painted
     // opaquely for non-leaf frames.
     // XXX this may not be a safe assumption; we should make this go away
     // by optimizing box-shadow drawing more for the cases where we don't have a skip-rect.
     useSkipGfxRect = !aForFrame->IsLeaf();
     nsRect paddingRect =
       aForFrame->GetPaddingRect() - aForFrame->GetPosition() + aFrameArea.TopLeft();
-    skipGfxRect = RectToGfxRect(paddingRect, twipsPerPixel);
+    skipGfxRect = nsLayoutUtils::RectToGfxRect(paddingRect, twipsPerPixel);
   } else if (hasBorderRadius) {
     skipGfxRect.Inset(
         PR_MAX(borderRadii[C_TL].height, borderRadii[C_TR].height), 0,
         PR_MAX(borderRadii[C_BL].height, borderRadii[C_BR].height), 0);
   }
 
   for (PRUint32 i = shadows->Length(); i > 0; --i) {
     nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1);
@@ -1161,18 +1151,20 @@ nsCSSRendering::PaintBoxShadowOuter(nsPr
     }
 
     // shadowRect won't include the blur, so make an extra rect here that includes the blur
     // for use in the even-odd rule below.
     nsRect shadowRectPlusBlur = shadowRect;
     nscoord blurRadius = shadowItem->mRadius;
     shadowRectPlusBlur.Inflate(blurRadius, blurRadius);
 
-    gfxRect shadowGfxRect = RectToGfxRect(shadowRect, twipsPerPixel);
-    gfxRect shadowGfxRectPlusBlur = RectToGfxRect(shadowRectPlusBlur, twipsPerPixel);
+    gfxRect shadowGfxRect =
+      nsLayoutUtils::RectToGfxRect(shadowRect, twipsPerPixel);
+    gfxRect shadowGfxRectPlusBlur =
+      nsLayoutUtils::RectToGfxRect(shadowRectPlusBlur, twipsPerPixel);
     shadowGfxRect.Round();
     shadowGfxRectPlusBlur.RoundOut();
 
     gfxContext* renderContext = aRenderingContext.ThebesContext();
     nsRefPtr<gfxContext> shadowContext;
     nsContextBoxBlur blurringArea;
 
     // When getting the widget shape from the native theme, we're going
@@ -1361,17 +1353,17 @@ nsCSSRendering::PaintBoxShadowInner(nsPr
       nsCSSBorderRenderer::ComputeInnerRadii(innerRadii, borderSizes,
                                              &clipRectRadii);
     }
 
     // Set the "skip rect" to the area within the frame that we don't paint in,
     // including after blurring. We also use this for clipping later on.
     nsRect skipRect = shadowClipRect;
     skipRect.Deflate(blurRadius, blurRadius);
-    gfxRect skipGfxRect = RectToGfxRect(skipRect, twipsPerPixel);
+    gfxRect skipGfxRect = nsLayoutUtils::RectToGfxRect(skipRect, twipsPerPixel);
     if (hasBorderRadius) {
       skipGfxRect.Inset(PR_MAX(clipRectRadii[C_TL].height, clipRectRadii[C_TR].height), 0,
                         PR_MAX(clipRectRadii[C_BL].height, clipRectRadii[C_BR].height), 0);
     }
 
     gfxContext* renderContext = aRenderingContext.ThebesContext();
     nsRefPtr<gfxContext> shadowContext;
     nsContextBoxBlur blurringArea;
@@ -1389,32 +1381,35 @@ nsCSSRendering::PaintBoxShadowInner(nsPr
       shadowColor = aForFrame->GetStyleColor()->mColor;
 
     renderContext->Save();
     renderContext->SetColor(gfxRGBA(shadowColor));
 
     // Clip the context to the area of the frame's padding rect, so no part of the
     // shadow is painted outside. Also cut out anything beyond where the inset shadow
     // will be.
-    gfxRect shadowGfxRect = RectToGfxRect(paddingRect, twipsPerPixel);
+    gfxRect shadowGfxRect =
+      nsLayoutUtils::RectToGfxRect(paddingRect, twipsPerPixel);
     shadowGfxRect.Round();
     renderContext->NewPath();
     if (hasBorderRadius)
       renderContext->RoundedRectangle(shadowGfxRect, innerRadii, PR_FALSE);
     else
       renderContext->Rectangle(shadowGfxRect);
     renderContext->Rectangle(skipGfxRect);
     renderContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD);
     renderContext->Clip();
 
     // Fill the temporary surface minus the area within the frame that we should
     // not paint in, and blur and apply it
-    gfxRect shadowPaintGfxRect = RectToGfxRect(shadowPaintRect, twipsPerPixel);
+    gfxRect shadowPaintGfxRect =
+      nsLayoutUtils::RectToGfxRect(shadowPaintRect, twipsPerPixel);
     shadowPaintGfxRect.RoundOut();
-    gfxRect shadowClipGfxRect = RectToGfxRect(shadowClipRect, twipsPerPixel);
+    gfxRect shadowClipGfxRect =
+      nsLayoutUtils::RectToGfxRect(shadowClipRect, twipsPerPixel);
     shadowClipGfxRect.Round();
     shadowContext->NewPath();
     shadowContext->Rectangle(shadowPaintGfxRect);
     if (hasBorderRadius)
       shadowContext->RoundedRectangle(shadowClipGfxRect, clipRectRadii, PR_FALSE);
     else
       shadowContext->Rectangle(shadowClipGfxRect);
     shadowContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD);
@@ -1516,17 +1511,17 @@ static inline void
 SetupDirtyRects(const nsRect& aBGClipArea, const nsRect& aCallerDirtyRect,
                 nscoord aAppUnitsPerPixel,
                 /* OUT: */
                 nsRect* aDirtyRect, gfxRect* aDirtyRectGfx)
 {
   aDirtyRect->IntersectRect(aBGClipArea, aCallerDirtyRect);
 
   // Compute the Thebes equivalent of the dirtyRect.
-  *aDirtyRectGfx = RectToGfxRect(*aDirtyRect, aAppUnitsPerPixel);
+  *aDirtyRectGfx = nsLayoutUtils::RectToGfxRect(*aDirtyRect, aAppUnitsPerPixel);
   NS_WARN_IF_FALSE(aDirtyRect->IsEmpty() || !aDirtyRectGfx->IsEmpty(),
                    "converted dirty rect should not be empty");
   NS_ABORT_IF_FALSE(!aDirtyRect->IsEmpty() || aDirtyRectGfx->IsEmpty(),
                     "second should be empty if first is");
 }
 
 static void
 SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
@@ -1576,17 +1571,18 @@ SetupBackgroundClip(gfxContext *aCtx, PR
   // If we have rounded corners, clip all subsequent drawing to the
   // rounded rectangle defined by bgArea and bgRadii (we don't know
   // whether the rounded corners intrude on the dirtyRect or not).
   // 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 (aHaveRoundedCorners) {
-    gfxRect bgAreaGfx(RectToGfxRect(*aBGClipArea, aAppUnitsPerPixel));
+    gfxRect bgAreaGfx =
+      nsLayoutUtils::RectToGfxRect(*aBGClipArea, aAppUnitsPerPixel);
     bgAreaGfx.Round();
     bgAreaGfx.Condition();
 
     if (bgAreaGfx.IsEmpty()) {
       // I think it's become possible to hit this since
       // http://hg.mozilla.org/mozilla-central/rev/50e934e4979b landed.
       NS_WARNING("converted background area should not be empty");
       // Make our caller not do anything.
@@ -1851,17 +1847,18 @@ nsCSSRendering::PaintGradient(nsPresCont
                               const nsRect& aOneCellArea,
                               const nsRect& aFillArea)
 {
   if (aOneCellArea.IsEmpty())
     return;
 
   gfxContext *ctx = aRenderingContext.ThebesContext();
   nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-  gfxRect oneCellArea = RectToGfxRect(aOneCellArea, appUnitsPerPixel);
+  gfxRect oneCellArea =
+    nsLayoutUtils::RectToGfxRect(aOneCellArea, appUnitsPerPixel);
 
   // Compute "gradient line" start and end relative to oneCellArea
   gfxPoint lineStart, lineEnd;
   double radiusX = 0, radiusY = 0; // for radial gradients only
   if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
     ComputeLinearGradientLine(aPresContext, aGradient, oneCellArea.size,
                               &lineStart, &lineEnd);
   } else {
@@ -2080,30 +2077,31 @@ nsCSSRendering::PaintGradient(nsPresCont
   // Paint gradient tiles. This isn't terribly efficient, but doing it this
   // way is simple and sure to get pixel-snapping right. We could speed things
   // up by drawing tiles into temporary surfaces and copying those to the
   // destination, but after pixel-snapping tiles may not all be the same size.
   nsRect dirty;
   if (!dirty.IntersectRect(aDirtyRect, aFillArea))
     return;
 
-  gfxRect areaToFill = RectToGfxRect(aFillArea, appUnitsPerPixel);
+  gfxRect areaToFill =
+    nsLayoutUtils::RectToGfxRect(aFillArea, appUnitsPerPixel);
   gfxMatrix ctm = ctx->CurrentMatrix();
 
   // xStart/yStart are the top-left corner of the top-left tile.
   nscoord xStart = FindTileStart(dirty.x, aOneCellArea.x, aOneCellArea.width);
   nscoord yStart = FindTileStart(dirty.y, aOneCellArea.y, aOneCellArea.height);
   nscoord xEnd = dirty.XMost();
   nscoord yEnd = dirty.YMost();
   // x and y are the top-left corner of the tile to draw
   for (nscoord y = yStart; y < yEnd; y += aOneCellArea.height) {
     for (nscoord x = xStart; x < xEnd; x += aOneCellArea.width) {
       // The coordinates of the tile
-      gfxRect tileRect =
-        RectToGfxRect(nsRect(x, y, aOneCellArea.width, aOneCellArea.height),
+      gfxRect tileRect = nsLayoutUtils::RectToGfxRect(
+                      nsRect(x, y, aOneCellArea.width, aOneCellArea.height),
                       appUnitsPerPixel);
       // The actual area to fill with this tile is the intersection of this
       // tile with the overall area we're supposed to be filling
       gfxRect fillRect = tileRect.Intersect(areaToFill);
       ctx->NewPath();
       ctx->Translate(tileRect.pos);
       ctx->SetPattern(gradientPattern);
       ctx->Rectangle(fillRect - tileRect.pos, PR_TRUE);
@@ -3837,19 +3835,20 @@ nsContextBoxBlur::Init(const nsRect& aRe
 
   // If not blurring, draw directly onto the destination device
   if (blurRadius <= 0 && spreadRadius <= 0 && !(aFlags & FORCE_MASK)) {
     mContext = aDestinationCtx;
     return mContext;
   }
 
   // Convert from app units to device pixels
-  gfxRect rect = RectToGfxRect(aRect, aAppUnitsPerDevPixel);
-
-  gfxRect dirtyRect = RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel);
+  gfxRect rect = nsLayoutUtils::RectToGfxRect(aRect, aAppUnitsPerDevPixel);
+
+  gfxRect dirtyRect =
+    nsLayoutUtils::RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel);
   dirtyRect.RoundOut();
 
   // Create the temporary surface for blurring
   mContext = blur.Init(rect, gfxIntSize(spreadRadius, spreadRadius),
                        gfxIntSize(blurRadius, blurRadius),
                        &dirtyRect, aSkipRect);
   return mContext;
 }
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2866,20 +2866,18 @@ MapToFloatImagePixels(const gfxSize& aSi
 static gfxPoint
 MapToFloatUserPixels(const gfxSize& aSize,
                      const gfxRect& aDest, const gfxPoint& aPt)
 {
   return gfxPoint(aPt.x*aDest.size.width/aSize.width + aDest.pos.x,
                   aPt.y*aDest.size.height/aSize.height + aDest.pos.y);
 }
 
-// helper function to convert a nsRect to a gfxRect
-// borrowed from nsCSSRendering.cpp
-static gfxRect
-RectToGfxRect(const nsRect& aRect, PRInt32 aAppUnitsPerDevPixel)
+/* static */ gfxRect
+nsLayoutUtils::RectToGfxRect(const nsRect& aRect, PRInt32 aAppUnitsPerDevPixel)
 {
   return gfxRect(gfxFloat(aRect.x) / aAppUnitsPerDevPixel,
                  gfxFloat(aRect.y) / aAppUnitsPerDevPixel,
                  gfxFloat(aRect.width) / aAppUnitsPerDevPixel,
                  gfxFloat(aRect.height) / aAppUnitsPerDevPixel);
 }
 
 struct SnappedImageDrawingParameters {
@@ -2929,19 +2927,22 @@ ComputeSnappedImageDrawingParameters(gfx
                                      const nsPoint   aAnchor,
                                      const nsRect    aDirty,
                                      const nsIntSize aImageSize)
 
 {
   if (aDest.IsEmpty() || aFill.IsEmpty())
     return SnappedImageDrawingParameters();
 
-  gfxRect devPixelDest = RectToGfxRect(aDest, aAppUnitsPerDevPixel);
-  gfxRect devPixelFill = RectToGfxRect(aFill, aAppUnitsPerDevPixel);
-  gfxRect devPixelDirty = RectToGfxRect(aDirty, aAppUnitsPerDevPixel);
+  gfxRect devPixelDest =
+    nsLayoutUtils::RectToGfxRect(aDest, aAppUnitsPerDevPixel);
+  gfxRect devPixelFill =
+    nsLayoutUtils::RectToGfxRect(aFill, aAppUnitsPerDevPixel);
+  gfxRect devPixelDirty =
+    nsLayoutUtils::RectToGfxRect(aDirty, aAppUnitsPerDevPixel);
 
   PRBool ignoreScale = PR_FALSE;
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
   ignoreScale = PR_TRUE;
 #endif
   gfxRect fill = devPixelFill;
   PRBool didSnap = aCtx->UserToDevicePixelSnapped(fill, ignoreScale);
 
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -938,16 +938,22 @@ public:
                             gfxPattern::GraphicsFilter aGraphicsFilter,
                             const nsRect&        aDest,
                             const nsRect&        aFill,
                             const nsPoint&       aAnchor,
                             const nsRect&        aDirty,
                             PRUint32             aImageFlags);
 
   /**
+   * Convert an nsRect to a gfxRect.
+   */
+  static gfxRect RectToGfxRect(const nsRect& aRect,
+                               PRInt32 aAppUnitsPerDevPixel);
+
+  /**
    * Draw a drawable using the pixel snapping algorithm.
    * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
    *   @param aRenderingContext Where to draw the image, set up with an
    *                            appropriate scale and transform for drawing in
    *                            app units.
    *   @param aDrawable         The drawable we want to draw.
    *   @param aFilter           The graphics filter we should draw with.
    *   @param aDest             Where one copy of the image should mapped to.