Bug 1088498. Treat anchor offsets just less than 0.5 as 0.5 when rounding. r=seth
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 29 Oct 2014 15:08:40 +1300
changeset 212917 d67de20b86127757fe5441b510b87710e14401bc
parent 212916 669b21a7bfd018e2775d7fd6761d4a6aee1b9325
child 212918 048e11424dec07029ee0e26cf98aac3b52193f56
push id27736
push userryanvm@gmail.com
push dateWed, 29 Oct 2014 20:49:13 +0000
treeherdermozilla-central@80e18ff7c7b2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth
bugs1088498
milestone36.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 1088498. Treat anchor offsets just less than 0.5 as 0.5 when rounding. r=seth
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -5205,16 +5205,30 @@ TransformBetweenRects(const gfxRect& aFr
 static nsRect
 TileNearRect(const nsRect& aAnyTile, const nsRect& aTargetRect)
 {
   nsPoint distance = aTargetRect.TopLeft() - aAnyTile.TopLeft();
   return aAnyTile + nsPoint(distance.x / aAnyTile.width * aAnyTile.width,
                             distance.y / aAnyTile.height * aAnyTile.height);
 }
 
+static gfxFloat
+StableRound(gfxFloat aValue)
+{
+  // Values slightly less than 0.5 should round up like 0.5 would; we're
+  // assuming they were meant to be 0.5.
+  return floor(aValue + 0.5001);
+}
+
+static gfxPoint
+StableRound(const gfxPoint& aPoint)
+{
+  return gfxPoint(StableRound(aPoint.x), StableRound(aPoint.y));
+}
+
 /**
  * Given a set of input parameters, compute certain output parameters
  * for drawing an image with the image snapping algorithm.
  * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
  *
  *  @see nsLayoutUtils::DrawImage() for the descriptions of input parameters
  */
 static SnappedImageDrawingParameters
@@ -5311,21 +5325,21 @@ ComputeSnappedImageDrawingParameters(gfx
     // Compute the anchor point in both device space and image space.  This
     // code assumes that pixel-based devices have one pixel per device unit!
     gfxPoint anchorPoint(gfxFloat(anchor.x)/aAppUnitsPerDevPixel,
                          gfxFloat(anchor.y)/aAppUnitsPerDevPixel);
     gfxPoint imageSpaceAnchorPoint =
       MapToFloatImagePixels(imageSize, devPixelDest, anchorPoint);
 
     if (didSnap) {
-      imageSpaceAnchorPoint.Round();
+      imageSpaceAnchorPoint = StableRound(imageSpaceAnchorPoint);
       anchorPoint = imageSpaceAnchorPoint;
       anchorPoint = MapToFloatUserPixels(imageSize, devPixelDest, anchorPoint);
       anchorPoint = currentMatrix.Transform(anchorPoint);
-      anchorPoint.Round();
+      anchorPoint = StableRound(anchorPoint);
     }
 
     gfxRect anchoredDestRect(anchorPoint, scaledDest);
     gfxRect anchoredImageRect(imageSpaceAnchorPoint, imageSize);
     transform = TransformBetweenRects(anchoredImageRect, anchoredDestRect);
     invTransform = TransformBetweenRects(anchoredDestRect, anchoredImageRect);
   }