bug 622507 - allow a possible subpixel discrepancy at bottom/right of popup rect because we snap the top/left to a pixel boundary when positioning. r+a=roc, test-only
authorJonathan Kew <jfkthame@gmail.com>
Mon, 21 Feb 2011 08:52:21 +0000
changeset 62894 2ce0aeb5929caa71342cc26c55cb37aec0bae7f0
parent 62893 3db6693e136e2ae28e17b5e8f19d15b46305a128
child 62895 338a48d9f6033fa5a3e7ed38ed9210e048472462
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
bugs622507
milestone2.0b12pre
bug 622507 - allow a possible subpixel discrepancy at bottom/right of popup rect because we snap the top/left to a pixel boundary when positioning. r+a=roc, test-only
toolkit/content/tests/widgets/popup_shared.js
--- a/toolkit/content/tests/widgets/popup_shared.js
+++ b/toolkit/content/tests/widgets/popup_shared.js
@@ -308,16 +308,28 @@ function convertPosition(anchor, align)
   if (anchor == "topright" && align == "bottomright") return "before_end";
   if (anchor == "bottomleft" && align == "bottomright") return "start_after";
   if (anchor == "bottomleft" && align == "topleft") return "after_start";
   if (anchor == "bottomright" && align == "bottomleft") return "end_after";
   if (anchor == "bottomright" && align == "topright") return "after_end";
   return "";
 }
 
+/*
+ * When checking position of the bottom or right edge of the popup's rect,
+ * use this instead of strict equality check of rounded values,
+ * because we snap the top/left edges to pixel boundaries,
+ * which can shift the bottom/right up to 0.5px from its "ideal" location,
+ * and could cause it to round differently. (See bug 622507.)
+ */
+function isWithinHalfPixel(a, b)
+{
+  return Math.abs(a - b) <= 0.5;
+}
+
 function compareEdge(anchor, popup, edge, offsetX, offsetY, testname)
 {
   testname += " " + edge;
 
   checkOpen(anchor.id, testname);
 
   var anchorrect = anchor.getBoundingClientRect();
   var popuprect = popup.getBoundingClientRect();
@@ -363,27 +375,27 @@ function compareEdge(anchor, popup, edge
   if (edge == "overlap") {
     ok(Math.round(anchorrect.left) + offsetY == Math.round(popuprect.left) &&
        Math.round(anchorrect.top) + offsetY == Math.round(popuprect.top),
        testname + " position");
     return;
   }
 
   if (edge.indexOf("before") == 0)
-    check1 = (Math.round(anchorrect.top) + offsetY == Math.round(popuprect.bottom));
+    check1 = isWithinHalfPixel(anchorrect.top + offsetY, popuprect.bottom);
   else if (edge.indexOf("after") == 0)
     check1 = (Math.round(anchorrect.bottom) + offsetY == Math.round(popuprect.top));
   else if (edge.indexOf("start") == 0)
-    check1 = (Math.round(anchorrect.left) + offsetX == Math.round(popuprect.right));
+    check1 = isWithinHalfPixel(anchorrect.left + offsetX, popuprect.right);
   else if (edge.indexOf("end") == 0)
     check1 = (Math.round(anchorrect.right) + offsetX == Math.round(popuprect.left));
 
   if (0 < edge.indexOf("before"))
     check2 = (Math.round(anchorrect.top) + offsetY == Math.round(popuprect.top));
   else if (0 < edge.indexOf("after"))
-    check2 = (Math.round(anchorrect.bottom) + offsetY == Math.round(popuprect.bottom));
+    check2 = isWithinHalfPixel(anchorrect.bottom + offsetY, popuprect.bottom);
   else if (0 < edge.indexOf("start"))
     check2 = (Math.round(anchorrect.left) + offsetX == Math.round(popuprect.left));
   else if (0 < edge.indexOf("end"))
-    check2 = (Math.round(anchorrect.right) + offsetX == Math.round(popuprect.right));
+    check2 = isWithinHalfPixel(anchorrect.right + offsetX, popuprect.right);
 
   ok(check1 && check2, testname + " position");
 }