From 9faa73de5f87fcbf61461adff0f2d7444d9f57cc Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Sat, 17 Oct 2015 10:18:00 -0700 Subject: [PATCH] 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 | 26 +++++++++--- layout/base/nsLayoutUtils.cpp | 14 +++++++ layout/base/nsLayoutUtils.h | 11 ++++++ layout/mathml/nsMathMLFrame.cpp | 7 ++-- layout/reftests/mathml/radicalbar-1.html | 48 +++++++++++++++++++++++ layout/reftests/mathml/radicalbar-1a.html | 48 +++++++++++++++++++++++ layout/reftests/mathml/radicalbar-1b.html | 48 +++++++++++++++++++++++ layout/reftests/mathml/radicalbar-1c.html | 48 +++++++++++++++++++++++ layout/reftests/mathml/radicalbar-1d.html | 48 +++++++++++++++++++++++ layout/reftests/mathml/radicalbar-2.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-2a.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-2b.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-2c.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-2d.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-3.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-3a.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-3b.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-3c.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/radicalbar-3d.html | 47 ++++++++++++++++++++++ layout/reftests/mathml/reftest.list | 15 +++++++ 20 files changed, 775 insertions(+), 8 deletions(-) create mode 100644 layout/reftests/mathml/radicalbar-1.html create mode 100644 layout/reftests/mathml/radicalbar-1a.html create mode 100644 layout/reftests/mathml/radicalbar-1b.html create mode 100644 layout/reftests/mathml/radicalbar-1c.html create mode 100644 layout/reftests/mathml/radicalbar-1d.html create mode 100644 layout/reftests/mathml/radicalbar-2.html create mode 100644 layout/reftests/mathml/radicalbar-2a.html create mode 100644 layout/reftests/mathml/radicalbar-2b.html create mode 100644 layout/reftests/mathml/radicalbar-2c.html create mode 100644 layout/reftests/mathml/radicalbar-2d.html create mode 100644 layout/reftests/mathml/radicalbar-3.html create mode 100644 layout/reftests/mathml/radicalbar-3a.html create mode 100644 layout/reftests/mathml/radicalbar-3b.html create mode 100644 layout/reftests/mathml/radicalbar-3c.html create mode 100644 layout/reftests/mathml/radicalbar-3d.html diff --git a/gfx/2d/PathHelpers.h b/gfx/2d/PathHelpers.h index 4dbc0aac8fbe..7a4fac98975d 100644 --- a/gfx/2d/PathHelpers.h +++ b/gfx/2d/PathHelpers.h @@ -352,9 +352,14 @@ extern UserDataKey sDisablePixelSnapping; * 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; @@ -383,8 +388,18 @@ inline bool UserToDevicePixelSnapped(Rect& aRect, const DrawTarget& aDrawTarget, // 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(), @@ -400,10 +415,11 @@ inline bool UserToDevicePixelSnapped(Rect& aRect, const DrawTarget& aDrawTarget, * 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(); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 429bd91b0b0b..6bd0eeb4fd18 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -8094,6 +8094,20 @@ Rect NSRectToSnappedRect(const nsRect& aRect, double 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, diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index b1492ad142e9..49644080dd50 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2853,6 +2853,17 @@ gfx::Rect NSRectToRect(const nsRect& aRect, double aAppUnitsPerPixel); 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, diff --git a/layout/mathml/nsMathMLFrame.cpp b/layout/mathml/nsMathMLFrame.cpp index f44593702ab9..da595ebefa3b 100644 --- a/layout/mathml/nsMathMLFrame.cpp +++ b/layout/mathml/nsMathMLFrame.cpp @@ -363,9 +363,10 @@ void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder, { // 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); diff --git a/layout/reftests/mathml/radicalbar-1.html b/layout/reftests/mathml/radicalbar-1.html new file mode 100644 index 000000000000..7ee38149dd20 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-1.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/mathml/radicalbar-1a.html b/layout/reftests/mathml/radicalbar-1a.html new file mode 100644 index 000000000000..3b43eb90922d --- /dev/null +++ b/layout/reftests/mathml/radicalbar-1a.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/mathml/radicalbar-1b.html b/layout/reftests/mathml/radicalbar-1b.html new file mode 100644 index 000000000000..3d49caa38dde --- /dev/null +++ b/layout/reftests/mathml/radicalbar-1b.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/mathml/radicalbar-1c.html b/layout/reftests/mathml/radicalbar-1c.html new file mode 100644 index 000000000000..3ebff2420370 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-1c.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/mathml/radicalbar-1d.html b/layout/reftests/mathml/radicalbar-1d.html new file mode 100644 index 000000000000..70c8ed936092 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-1d.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/mathml/radicalbar-2.html b/layout/reftests/mathml/radicalbar-2.html new file mode 100644 index 000000000000..140d0e037ba2 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-2.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-2a.html b/layout/reftests/mathml/radicalbar-2a.html new file mode 100644 index 000000000000..ff31625f0678 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-2a.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-2b.html b/layout/reftests/mathml/radicalbar-2b.html new file mode 100644 index 000000000000..8d2736fc60b4 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-2b.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-2c.html b/layout/reftests/mathml/radicalbar-2c.html new file mode 100644 index 000000000000..1e9f01777490 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-2c.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-2d.html b/layout/reftests/mathml/radicalbar-2d.html new file mode 100644 index 000000000000..b92ed920f067 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-2d.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-3.html b/layout/reftests/mathml/radicalbar-3.html new file mode 100644 index 000000000000..929ff534da64 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-3.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-3a.html b/layout/reftests/mathml/radicalbar-3a.html new file mode 100644 index 000000000000..5708e38a79a7 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-3a.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-3b.html b/layout/reftests/mathml/radicalbar-3b.html new file mode 100644 index 000000000000..8343654acb35 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-3b.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-3c.html b/layout/reftests/mathml/radicalbar-3c.html new file mode 100644 index 000000000000..c5f5e5a65eb5 --- /dev/null +++ b/layout/reftests/mathml/radicalbar-3c.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/radicalbar-3d.html b/layout/reftests/mathml/radicalbar-3d.html new file mode 100644 index 000000000000..99e7790fb04e --- /dev/null +++ b/layout/reftests/mathml/radicalbar-3d.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + +
+ + diff --git a/layout/reftests/mathml/reftest.list b/layout/reftests/mathml/reftest.list index de7b5fb220e4..6ef5e2d404a3 100644 --- a/layout/reftests/mathml/reftest.list +++ b/layout/reftests/mathml/reftest.list @@ -366,3 +366,18 @@ fails-if(winWidget) == mfrac-D-2.html mfrac-D-2-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-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-3.html about:blank +!= radicalbar-3a.html about:blank +!= radicalbar-3b.html about:blank +!= radicalbar-3c.html about:blank +!= radicalbar-3d.html about:blank