Backout ffcdd896a1fa (bug 787947) for reftest failures
authorEd Morley <emorley@mozilla.com>
Wed, 03 Oct 2012 13:43:19 +0100
changeset 115355 9b992222370b37a610d329067d02fe1b1773c96d
parent 115354 5cf45899da84fa911f0dd85f44ba1223a7671243
child 115356 1e5584c8e7d0d7aa6ae41d27a555856c5b82d070
push idunknown
push userunknown
push dateunknown
bugs787947
milestone18.0a1
backs outffcdd896a1fa7bb419077873da59d2d2ed9e3271
Backout ffcdd896a1fa (bug 787947) for reftest failures
layout/base/nsCSSRendering.cpp
layout/reftests/bugs/787947-1-ref.html
layout/reftests/bugs/787947-1.html
layout/reftests/bugs/reftest.list
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2278,17 +2278,16 @@ nsCSSRendering::PaintGradient(nsPresCont
   // destination, but after pixel-snapping tiles may not all be the same size.
   nsRect dirty;
   if (!dirty.IntersectRect(aDirtyRect, aFillArea))
     return;
 
   gfxRect areaToFill =
     nsLayoutUtils::RectToGfxRect(aFillArea, appUnitsPerPixel);
   gfxMatrix ctm = ctx->CurrentMatrix();
-  bool isCTMPreservingAxisAlignedRectangles = ctm.PreservesAxisAlignedRectangles();
 
   // 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 = pattern->mCoversTile ? xStart + aOneCellArea.width : dirty.XMost();
   nscoord yEnd = pattern->mCoversTile ? yStart + aOneCellArea.height : dirty.YMost();
 
   // x and y are the top-left corner of the tile to draw
@@ -2298,40 +2297,37 @@ nsCSSRendering::PaintGradient(nsPresCont
       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 =
         pattern->mCoversTile ? areaToFill : tileRect.Intersect(areaToFill);
       ctx->NewPath();
-      // Try snapping the fill rect. Snap its top-left and bottom-right
-      // independently to preserve the orientation.
-      gfxPoint snappedFillRectTopLeft = fillRect.TopLeft();
-      gfxPoint snappedFillRectBottomRight = fillRect.BottomRight();
-      if (isCTMPreservingAxisAlignedRectangles &&
-          ctx->UserToDevicePixelSnapped(snappedFillRectTopLeft, true) &&
-          ctx->UserToDevicePixelSnapped(snappedFillRectBottomRight, true)) {
-        if (snappedFillRectTopLeft.x == snappedFillRectBottomRight.x ||
-            snappedFillRectTopLeft.y == snappedFillRectBottomRight.y) {
-          // Nothing to draw; avoid scaling by zero and other weirdness that
-          // could put the context in an error state.
-          continue;
-        }
-        // Set the context's transform to the transform that maps fillRect to
-        // snappedFillRect. The part of the gradient that was going to
-        // exactly fill fillRect will fill snappedFillRect instead.
+      // If we can snap the gradient tile and fill rects, do so, but make sure
+      // that the gradient is scaled precisely to the tile rect.
+      gfxRect fillRectSnapped = fillRect;
+      // Don't snap the tileRect directly since that would lose information
+      // about the orientation of the current transform (i.e. vertical or
+      // horizontal flipping). Instead snap the corners independently so if
+      // the CTM has a flip, our Scale() below preserves the flip.
+      gfxPoint tileRectSnappedTopLeft = tileRect.TopLeft();
+      gfxPoint tileRectSnappedBottomRight = tileRect.BottomRight();
+      if (ctx->UserToDevicePixelSnapped(fillRectSnapped, true) &&
+          ctx->UserToDevicePixelSnapped(tileRectSnappedTopLeft, true) &&
+          ctx->UserToDevicePixelSnapped(tileRectSnappedBottomRight, true)) {
         ctx->IdentityMatrix();
-        ctx->Translate(snappedFillRectTopLeft);
-        ctx->Scale((snappedFillRectBottomRight.x - snappedFillRectTopLeft.x)/fillRect.width,
-                   (snappedFillRectBottomRight.y - snappedFillRectTopLeft.y)/fillRect.height);
-        ctx->Translate(-fillRect.TopLeft());
+        ctx->Rectangle(fillRectSnapped);
+        ctx->Translate(tileRectSnappedTopLeft);
+        ctx->Scale((tileRectSnappedBottomRight.x - tileRectSnappedTopLeft.x)/tileRect.width,
+                   (tileRectSnappedBottomRight.y - tileRectSnappedTopLeft.y)/tileRect.height);
+      } else {
+        ctx->Rectangle(fillRect);
+        ctx->Translate(tileRect.TopLeft());
       }
-      ctx->Rectangle(fillRect);
-      ctx->Translate(tileRect.TopLeft());
       ctx->SetPattern(pattern->mPattern);
       ctx->Fill();
       ctx->SetMatrix(ctm);
     }
   }
   // If we could not put the gradient in the gradient cache, make sure to
   // release its resources so we don't leak.
   if (!gradientRegistered) {
deleted file mode 100644
--- a/layout/reftests/bugs/787947-1-ref.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!DOCTYPE HTML>
-<div style="position:absolute; left:10px; top:10px; width:100px; height:100px; border:1px solid black; background-image:linear-gradient(white, black);"></div>
-<p style="position:absolute; left:10px; z-index:2">Hello
deleted file mode 100644
--- a/layout/reftests/bugs/787947-1.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!DOCTYPE HTML>
-<div style="position:absolute; left:10px; top:10px; width:100px; height:100px; border:1px solid black; background-image:linear-gradient(white, black); background-size:0.3px 100px;"></div>
-<p style="position:absolute; left:10px; z-index:2">Hello
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1714,9 +1714,8 @@ fuzzy-if(true,17,5859) == 759036-2.html 
 == 776265-1a.html 776265-1-ref.html
 == 776265-1b.html 776265-1-ref.html
 == 776265-1c.html 776265-1-ref.html
 == 776265-1d.html 776265-1-ref.html
 == 776265-2a.html 776265-2-ref.html
 == 776265-2b.html 776265-2-ref.html
 == 776265-2c.html 776265-2-ref.html
 == 776265-2d.html 776265-2-ref.html
-== 787947-1.html 787947-1-ref.html