Bug 1101020 - Add the ability to fall back to not snapping, if snapping results in a zero area rect r=roc
☠☠ backed out by f0d877062026 ☠ ☠
authorJames Kitchener <jkitch.bug@internode.on.net>
Wed, 07 Oct 2015 11:18:08 +0530
changeset 287682 18d4a0ca8cc176be185ba4b22c1fd790aadd1f43
parent 287681 7fb566dcac63340200371b1f9f37454f69d2c37b
child 287683 67b7e1825a7fc500b68d6e17d3d4e1914db68697
push id8654
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:48:40 +0000
treeherdermozilla-aurora@bc4551debe17 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1101020
milestone44.0a1
Bug 1101020 - Add the ability to fall back to not snapping, if snapping results in a zero area rect r=roc
gfx/2d/PathHelpers.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/mathml/nsMathMLFrame.cpp
layout/reftests/mathml/radicalbar-1.html
layout/reftests/mathml/radicalbar-1a.html
layout/reftests/mathml/radicalbar-1b.html
layout/reftests/mathml/radicalbar-1c.html
layout/reftests/mathml/radicalbar-1d.html
layout/reftests/mathml/radicalbar-1e.html
layout/reftests/mathml/radicalbar-2.html
layout/reftests/mathml/radicalbar-2a.html
layout/reftests/mathml/radicalbar-2b.html
layout/reftests/mathml/radicalbar-2c.html
layout/reftests/mathml/radicalbar-2d.html
layout/reftests/mathml/radicalbar-2e.html
layout/reftests/mathml/radicalbar-3.html
layout/reftests/mathml/radicalbar-3a.html
layout/reftests/mathml/radicalbar-3b.html
layout/reftests/mathml/radicalbar-3c.html
layout/reftests/mathml/radicalbar-3d.html
layout/reftests/mathml/radicalbar-3e.html
layout/reftests/mathml/reftest.list
--- a/gfx/2d/PathHelpers.h
+++ b/gfx/2d/PathHelpers.h
@@ -347,19 +347,24 @@ extern UserDataKey sDisablePixelSnapping
  * This function returns true if aRect is modified, otherwise it returns false.
  *
  * Note that the snapping is such that filling the rect using a DrawTarget
  * which has the identity matrix as its transform will result in crisp edges.
  * (That is, aRect will have integer values, aligning its edges between pixel
  * boundaries.)  If on the other hand you stroking the rect with an odd valued
  * stroke width then the edges of the stroke will be antialiased (assuming an
  * AntialiasMode that does antialiasing).
+ *
+ * Empty snaps are those which result in a rectangle of 0 area.  If they are
+ * disallowed, an axis is left unsnapped if the rounding process results in a
+ * length of 0.
  */
 inline bool UserToDevicePixelSnapped(Rect& aRect, const DrawTarget& aDrawTarget,
-                                     bool aAllowScaleOr90DegreeRotate = false)
+                                     bool aAllowScaleOr90DegreeRotate = false,
+                                     bool aAllowEmptySnaps = true)
 {
   if (aDrawTarget.GetUserData(&sDisablePixelSnapping)) {
     return false;
   }
 
   Matrix mat = aDrawTarget.GetTransform();
 
   const Float epsilon = 0.0000001f;
@@ -378,37 +383,48 @@ inline bool UserToDevicePixelSnapped(Rec
 
   // Check that the rectangle is axis-aligned. For an axis-aligned rectangle,
   // two opposite corners define the entire rectangle. So check if
   // the axis-aligned rectangle with opposite corners p1 and p3
   // define an axis-aligned rectangle whose other corners are p2 and p4.
   // We actually only need to check one of p2 and p4, since an affine
   // transform maps parallelograms to parallelograms.
   if (p2 == Point(p1.x, p3.y) || p2 == Point(p3.x, p1.y)) {
-      p1.Round();
-      p3.Round();
+      Point p1r = p1;
+      Point p3r = p3;
+      p1r.Round();
+      p3r.Round();
+      if (aAllowEmptySnaps || p1r.x != p3r.x) {
+          p1.x = p1r.x;
+          p3.x = p3r.x;
+      }
+      if (aAllowEmptySnaps || p1r.y != p3r.y) {
+          p1.y = p1r.y;
+          p3.y = p3r.y;
+      }
 
       aRect.MoveTo(Point(std::min(p1.x, p3.x), std::min(p1.y, p3.y)));
       aRect.SizeTo(Size(std::max(p1.x, p3.x) - aRect.X(),
                         std::max(p1.y, p3.y) - aRect.Y()));
       return true;
   }
 
   return false;
 }
 
 /**
  * This function has the same behavior as UserToDevicePixelSnapped except that
  * aRect is not transformed to device space.
  */
 inline bool MaybeSnapToDevicePixels(Rect& aRect, const DrawTarget& aDrawTarget,
-                                    bool aAllowScaleOr90DegreeRotate = false)
+                                    bool aAllowScaleOr90DegreeRotate = false,
+                                    bool aAllowEmptySnaps = true)
 {
   if (UserToDevicePixelSnapped(aRect, aDrawTarget,
-                               aAllowScaleOr90DegreeRotate)) {
+                               aAllowScaleOr90DegreeRotate, aAllowEmptySnaps)) {
     // Since UserToDevicePixelSnapped returned true we know there is no
     // rotation/skew in 'mat', so we can just use TransformBounds() here.
     Matrix mat = aDrawTarget.GetTransform();
     mat.Invert();
     aRect = mat.TransformBounds(aRect);
     return true;
   }
   return false;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -8096,16 +8096,30 @@ Rect NSRectToSnappedRect(const nsRect& a
   // division using a larger type and avoiding rounding error.
   Rect rect(Float(aRect.x / aAppUnitsPerPixel),
             Float(aRect.y / aAppUnitsPerPixel),
             Float(aRect.width / aAppUnitsPerPixel),
             Float(aRect.height / aAppUnitsPerPixel));
   MaybeSnapToDevicePixels(rect, aSnapDT, true);
   return rect;
 }
+// Similar to a snapped rect, except an axis is left unsnapped if the snapping
+// process results in a length of 0.
+Rect NSRectToNonEmptySnappedRect(const nsRect& aRect, double aAppUnitsPerPixel,
+                                 const gfx::DrawTarget& aSnapDT)
+{
+  // Note that by making aAppUnitsPerPixel a double we're doing floating-point
+  // division using a larger type and avoiding rounding error.
+  Rect rect(Float(aRect.x / aAppUnitsPerPixel),
+            Float(aRect.y / aAppUnitsPerPixel),
+            Float(aRect.width / aAppUnitsPerPixel),
+            Float(aRect.height / aAppUnitsPerPixel));
+  MaybeSnapToDevicePixels(rect, aSnapDT, true, false);
+  return rect;
+}
 
 void StrokeLineWithSnapping(const nsPoint& aP1, const nsPoint& aP2,
                             int32_t aAppUnitsPerDevPixel,
                             DrawTarget& aDrawTarget,
                             const Pattern& aPattern,
                             const StrokeOptions& aStrokeOptions,
                             const DrawOptions& aDrawOptions)
 {
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2855,16 +2855,27 @@ gfx::Rect NSRectToRect(const nsRect& aRe
  * The passed DrawTarget is used to additionally snap the returned Rect to
  * device pixels, if appropriate (as decided and carried out by Moz2D's
  * MaybeSnapToDevicePixels helper, which this function calls to do any
  * snapping).
  */
 gfx::Rect NSRectToSnappedRect(const nsRect& aRect, double aAppUnitsPerPixel,
                               const gfx::DrawTarget& aSnapDT);
 
+/**
+* Converts, where possible, an nsRect in app units to a Moz2D Rect in pixels
+* (whether those are device pixels or CSS px depends on what the caller
+*  chooses to pass as aAppUnitsPerPixel).
+*
+* If snapping results in a rectangle with zero width or height, the affected
+* coordinates are left unsnapped
+*/
+gfx::Rect NSRectToNonEmptySnappedRect(const nsRect& aRect, double aAppUnitsPerPixel,
+                                      const gfx::DrawTarget& aSnapDT);
+
 void StrokeLineWithSnapping(const nsPoint& aP1, const nsPoint& aP2,
                             int32_t aAppUnitsPerDevPixel,
                             gfx::DrawTarget& aDrawTarget,
                             const gfx::Pattern& aPattern,
                             const gfx::StrokeOptions& aStrokeOptions = gfx::StrokeOptions(),
                             const gfx::DrawOptions& aDrawOptions = gfx::DrawOptions());
 
   namespace layout {
--- a/layout/mathml/nsMathMLFrame.cpp
+++ b/layout/mathml/nsMathMLFrame.cpp
@@ -358,19 +358,20 @@ private:
   nsRect    mRect;
 };
 
 void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder,
                                nsRenderingContext* aCtx)
 {
   // paint the bar with the current text color
   DrawTarget* drawTarget = aCtx->GetDrawTarget();
-  Rect rect = NSRectToSnappedRect(mRect + ToReferenceFrame(),
-                                  mFrame->PresContext()->AppUnitsPerDevPixel(),
-                                  *drawTarget);
+  Rect rect =
+    NSRectToNonEmptySnappedRect(mRect + ToReferenceFrame(),
+                                mFrame->PresContext()->AppUnitsPerDevPixel(),
+                                *drawTarget);
   ColorPattern color(ToDeviceColor(
                        mFrame->GetVisitedDependentColor(eCSSProperty_color)));
   drawTarget->FillRect(rect, color);
 }
 
 void
 nsMathMLFrame::DisplayBar(nsDisplayListBuilder* aBuilder,
                           nsIFrame* aFrame, const nsRect& aRect,
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-1.html
@@ -0,0 +1,48 @@
+<!doctype html>
+  <html>
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="visible">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-1a.html
@@ -0,0 +1,48 @@
+<!doctype html>
+  <html reftest-zoom=".5">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="visible">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-1b.html
@@ -0,0 +1,48 @@
+<!doctype html>
+  <html reftest-zoom=".4">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="visible">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-1c.html
@@ -0,0 +1,48 @@
+<!doctype html>
+  <html reftest-zoom=".3">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="visible">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-1d.html
@@ -0,0 +1,48 @@
+<!doctype html>
+  <html reftest-zoom=".2">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="visible">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-1e.html
@@ -0,0 +1,48 @@
+<!doctype html>
+  <html reftest-zoom=".1">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="visible">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-2.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html>
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="visible">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-2a.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.5">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="visible">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-2b.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.4">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="visible">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-2c.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.3">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="visible">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-2d.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.2">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="visible">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-2e.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.1">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="hidden">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="visible">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-3.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html>
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="visible">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-3a.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.5">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="visible">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-3b.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.4">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="visible">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-3c.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.3">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="visible">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-3d.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.2">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="visible">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/radicalbar-3e.html
@@ -0,0 +1,47 @@
+<!doctype html>
+  <html reftest-zoom="0.1">
+  <head>
+    <!-- Default to invisible text -->
+    <style type="text/css" media="screen, print">
+      .hidden {
+        color: white;
+      }
+      .visible {
+        color: black;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- Nest successive radicals and test that the horizontal bar of one of them is drawn.
+         Because the comparison is for inequality with about:blank, at most one can be visible -->
+    <math>
+      <mrow>
+        <msqrt class="hidden">
+          <mspace width="1em" height="1em" />
+          <msqrt class="hidden">
+            <mspace width="1em" height="1em" />
+            <msqrt class="hidden">
+              <mspace width="1em" height="1em" />
+              <msqrt class="hidden">
+                <mspace width="1em" height="1em" />
+                <msqrt class="visible">
+                  <mspace width="1em" height="1em" />
+                  <msqrt class="hidden">
+                    <mspace width="1em" height="1em" />
+                    <msqrt class="hidden">
+                      <mspace width="20em" height="1em" />
+                    </msqrt>
+                  </msqrt>
+                </msqrt>
+              </msqrt>
+            </msqrt>
+          </msqrt>
+        </msqrt>
+      </mrow>
+    </math>
+
+    <!-- Block out all but the horizontal bar of the visible radical -->
+    <div style="position: absolute; top: 5px; left: 0px;
+                width: 20em; height: 10em; background: white;"></div>
+  </body>
+</html>
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -361,8 +361,26 @@ fails-if(winWidget) == mfrac-C-2.html mf
 fuzzy-if(OSX,1,100) == mfrac-D-1.html mfrac-D-1-ref.html
 fails-if(winWidget) == mfrac-D-2.html mfrac-D-2-ref.html
 == mfrac-D-3.html mfrac-D-3-ref.html
 == mfrac-D-4.html mfrac-D-4-ref.html
 == mfrac-E-1.html mfrac-E-1-ref.html
 test-pref(dom.webcomponents.enabled,true) == shadow-dom-1.html shadow-dom-1-ref.html
 pref(font.size.inflation.emPerLine,25) == font-inflation-1.html font-inflation-1-ref.html
 test-pref(font.minimum-size.x-math,40) == default-font.html default-font-ref.html
+!= radicalbar-1.html about:blank
+!= radicalbar-1a.html about:blank
+!= radicalbar-1b.html about:blank
+!= radicalbar-1c.html about:blank
+!= radicalbar-1d.html about:blank
+!= radicalbar-1e.html about:blank
+!= radicalbar-2.html about:blank
+!= radicalbar-2a.html about:blank
+!= radicalbar-2b.html about:blank
+!= radicalbar-2c.html about:blank
+!= radicalbar-2d.html about:blank
+!= radicalbar-2e.html about:blank
+!= radicalbar-3.html about:blank
+!= radicalbar-3a.html about:blank
+!= radicalbar-3b.html about:blank
+!= radicalbar-3c.html about:blank
+!= radicalbar-3d.html about:blank
+!= radicalbar-3e.html about:blank