Bug 126601 - [CSS Shapes] First line gets incorrectly adjusted in shape-inside due to rounding in some polygons
Summary: [CSS Shapes] First line gets incorrectly adjusted in shape-inside due to roun...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Zoltan Horvath
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-07 14:32 PST by Zoltan Horvath
Modified: 2014-01-09 16:51 PST (History)
6 users (show)

See Also:


Attachments
proposed patch (4.03 KB, patch)
2014-01-07 14:46 PST, Zoltan Horvath
no flags Details | Formatted Diff | Diff
Patch (4.46 KB, patch)
2014-01-07 21:57 PST, Zoltan Horvath
no flags Details | Formatted Diff | Diff
Patch (17.16 KB, patch)
2014-01-09 10:40 PST, Zoltan Horvath
no flags Details | Formatted Diff | Diff
Patch (16.13 KB, patch)
2014-01-09 15:50 PST, Zoltan Horvath
no flags Details | Formatted Diff | Diff
Patch (16.12 KB, patch)
2014-01-09 15:51 PST, Zoltan Horvath
bjonesbe: review+
Details | Formatted Diff | Diff
Patch (16.09 KB, patch)
2014-01-09 16:16 PST, Zoltan Horvath
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Zoltan Horvath 2014-01-07 14:32:25 PST
First line gets incorrectly adjusted due to rounding in some polygons.
Comment 1 Zoltan Horvath 2014-01-07 14:46:28 PST
Created attachment 220552 [details]
proposed patch
Comment 2 Zoltan Horvath 2014-01-07 15:25:45 PST
A little explanation: 

float firstPositiveWidth ends up used in 

shape.firstIncludedIntervalLogicalTop(m_shapeLineTop, LayoutSize(minSegmentWidth, m_lineHeight), newLineTop) (ShapeInsideInfo.cpp:99)

where minSegmentWidth becomes a LayoutUnit, which clamps floats to ints in LayoutUnit.h:11, so we our segment width becomes smaller than its actual width, which leads to the layout error. Ceiling the float in firstPositiveWidth solves the problem.

A following patch could be to clarify floats/ints in/call sites of firstPositiveWidth, but I'd do that separately.
Comment 3 Bem Jones-Bey 2014-01-07 15:51:47 PST
Comment on attachment 220552 [details]
proposed patch

View in context: https://bugs.webkit.org/attachment.cgi?id=220552&action=review

> Source/WebCore/rendering/line/BreakingContextInlineHeaders.h:467
> +            return ceilf(wordMeasurements[i].width);

Have you tested this with subpixel rendering both on and off?
Comment 4 Bem Jones-Bey 2014-01-07 15:55:44 PST
Comment on attachment 220552 [details]
proposed patch

View in context: https://bugs.webkit.org/attachment.cgi?id=220552&action=review

> LayoutTests/fast/shapes/shape-inside/shape-inside-polygon-rounded-first-fit.html:14
> +<div class="shape-inside">The</div>

I am worried that this test will be flaky on different platforms with different fonts. At the very least, I think you should specify a font size and font face if you can't put this together with something like Ahem.
Comment 5 Zoltan Horvath 2014-01-07 21:57:37 PST
Created attachment 220594 [details]
Patch

(In reply to comment #3)
> (From update of attachment 220552 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=220552&action=review
> 
> > Source/WebCore/rendering/line/BreakingContextInlineHeaders.h:467
> > +            return ceilf(wordMeasurements[i].width);
> 
> Have you tested this with subpixel rendering both on and off?

I haven't tested. As far as I know subpixel layout is enabled only on ELF and GTK. We don't have any tests which would fail due to this rounding (most of the tests uses fixed font width, or shapes without the requirement of first line adjusting, thus the new rounding won't change anything), otherwise it would have failed already.

(In reply to comment #4)
> (From update of attachment 220552 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=220552&action=review
> 
> > LayoutTests/fast/shapes/shape-inside/shape-inside-polygon-rounded-first-fit.html:14
> > +<div class="shape-inside">The</div>
> 
> I am worried that this test will be flaky on different platforms with different fonts. At the very least, I think you should specify a font size and font face if you can't put this together with something like Ahem.

Unfortunately, we can't use Ahem, since it has fixed width, thus it won't result a floating width. I specified the font in the test to make it clear.

I also added a short explanation about the problem to the changelog.
Comment 6 Bem Jones-Bey 2014-01-08 10:14:21 PST
(In reply to comment #5)
> Created an attachment (id=220594) [details]
> Patch
> 
> (In reply to comment #3)
> > (From update of attachment 220552 [details] [details])
> > View in context: https://bugs.webkit.org/attachment.cgi?id=220552&action=review
> > 
> > > Source/WebCore/rendering/line/BreakingContextInlineHeaders.h:467
> > > +            return ceilf(wordMeasurements[i].width);
> > 
> > Have you tested this with subpixel rendering both on and off?
> 
> I haven't tested. As far as I know subpixel layout is enabled only on ELF and GTK. We don't have any tests which would fail due to this rounding (most of the tests uses fixed font width, or shapes without the requirement of first line adjusting, thus the new rounding won't change anything), otherwise it would have failed already.

It is only enabled on ELF/Gtk for now, they are working on enabling it for Mac right now. Note that there is no rounding due to LayoutUnit when subpixel layout is turned on, which is why I am concerned that your fix may not be valid and your test may even fail when run on Gtk/EFL.

> 
> (In reply to comment #4)
> > (From update of attachment 220552 [details] [details])
> > View in context: https://bugs.webkit.org/attachment.cgi?id=220552&action=review
> > 
> > > LayoutTests/fast/shapes/shape-inside/shape-inside-polygon-rounded-first-fit.html:14
> > > +<div class="shape-inside">The</div>
> > 
> > I am worried that this test will be flaky on different platforms with different fonts. At the very least, I think you should specify a font size and font face if you can't put this together with something like Ahem.
> 
> Unfortunately, we can't use Ahem, since it has fixed width, thus it won't result a floating width. I specified the font in the test to make it clear.

Have you tried to specify a floating point width for your Ahem characters? Or does that not work?
Comment 7 Zoltan Horvath 2014-01-08 10:17:02 PST
(In reply to comment #6)
> It is only enabled on ELF/Gtk for now, they are working on enabling it for Mac right now. Note that there is no rounding due to LayoutUnit when subpixel layout is turned on, which is why I am concerned that your fix may not be valid and your test may even fail when run on Gtk/EFL.

Good point.

> > (In reply to comment #4)
> Have you tried to specify a floating point width for your Ahem characters? Or does that not work?

I tried. I didn't work. :(
Comment 8 Bem Jones-Bey 2014-01-08 10:37:33 PST
(In reply to comment #7) 
> > > (In reply to comment #4)
> > Have you tried to specify a floating point width for your Ahem characters? Or does that not work?
> 
> I tried. I didn't work. :(

Well, even if you don't use Ahem, it would probably help if you did specify a font that you know has the metrics you want, as right now you are at the mercy of whatever default font is used by the test. I don't remember off the top of my head, but isn't there a list of fonts that one can rely on other than Ahem as being installed for the tests?
Comment 9 Bear Travis 2014-01-08 10:54:00 PST
Comment on attachment 220594 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=220594&action=review

> LayoutTests/fast/shapes/shape-inside/shape-inside-polygon-rounded-first-fit-expected.html:7
> +    height: 75px;

I am also concerned about the fragility of this test. If you need a font with characters with a specific height / width ratio, I can build one for you and you can embed it in the test as a data uri.
Will the test pass with subpixel layout enabled as well?

> Source/WebCore/rendering/line/BreakingContextInlineHeaders.h:467
> +            return ceilf(wordMeasurements[i].width);

I don't think this should be adjusted here, but rather when the float -> LayoutUnit conversion takes place (in ShapeInsideInfo::adjustLogicalLineTop). Alternatively you could change adjustLogicalLineTop to take a LayoutUnit.

I think the correct behavior (including subpixel layout concerns) is to round up to the nearest value LayoutUnit can express. Without subpixel layout, this is in steps of 1 pixel. With subpixel layout, it's in steps of 1/64 of a pixel. You can use LayoutUnit::fromFloatCeil to get this value.
Comment 10 Hans Muller 2014-01-08 15:34:04 PST
(In reply to comment #2)
> A little explanation: 
> 
> float firstPositiveWidth ends up used in 
> 
> shape.firstIncludedIntervalLogicalTop(m_shapeLineTop, LayoutSize(minSegmentWidth, m_lineHeight), newLineTop) (ShapeInsideInfo.cpp:99)
> 
> where minSegmentWidth becomes a LayoutUnit, which clamps floats to ints in LayoutUnit.h:11, so we our segment width becomes smaller than its actual width, which leads to the layout error. Ceiling the float in firstPositiveWidth solves the problem.

Per our discussion on IRC: I think this problem would be better solved by making the firstIncludedIntervalLogicalTop() minLogicalIntervalSize parameter a float for all of the Shape subclasses.  The fact that it's implicitly converted to a LayoutUnit and then back to a float is just asking for trouble and appears to be unnecessary.  The minLogicalIntervalSize parameter's LayoutUnit type may just be a historical artifact.
Comment 11 Zoltan Horvath 2014-01-09 10:40:33 PST
Created attachment 220750 [details]
Patch
Comment 12 Bem Jones-Bey 2014-01-09 13:49:40 PST
Comment on attachment 220750 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=220750&action=review

> LayoutTests/fast/shapes/shape-inside/shape-inside-polygon-rounded-first-fit.html:13
> +    background-color: green;
> +    color: green;

Since the color of the text is green, and it's very tiny compared to the square, it can be hard to tell if this test fails with manual inspection. It would be nice if you could make the failure mode show some red, for example, by placing a green div on top of the div with the shape-inside so that you can make the text red. (and then put "You should not see any red" in the description)

> Source/WebCore/rendering/shapes/Shape.h:81
> +    virtual bool firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const float minLogicalWidth, const LayoutUnit logicalHeight, LayoutUnit& result) const = 0;

Why not have this take a FloatSize?
Comment 13 Zoltan Horvath 2014-01-09 15:50:33 PST
Created attachment 220779 [details]
Patch

(In reply to comment #12)
> (From update of attachment 220750 [details])
> Since the color of the text is green, and it's very tiny compared to the square, it can be hard to tell if this test fails with manual inspection. It would be nice if you could make the failure mode show some red, for example, by placing a green div on top of the div with the shape-inside so that you can make the text red. (and then put "You should not see any red" in the description)

I increased the size of the content, so it's much bigger now. I also painted to red and added green overlay. There is no way to miss it now, if it fails. I also updated the test description.

> > Source/WebCore/rendering/shapes/Shape.h:81
> > +    virtual bool firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const float minLogicalWidth, const LayoutUnit logicalHeight, LayoutUnit& result) const = 0;
> 
> Why not have this take a FloatSize?

I modified to use FloatSize.

Thanks for looking into.
Comment 14 Zoltan Horvath 2014-01-09 15:51:38 PST
Created attachment 220780 [details]
Patch
Comment 15 Bem Jones-Bey 2014-01-09 16:09:55 PST
Comment on attachment 220780 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=220780&action=review

r=me, even if you don't feel like updating for the nit on the test.

> LayoutTests/fast/shapes/shape-inside/shape-inside-polygon-rounded-first-fit.html:15
> +    background-color: green;

Nit: I'd delete this line.
Comment 16 Zoltan Horvath 2014-01-09 16:16:22 PST
Created attachment 220785 [details]
Patch
Comment 17 WebKit Commit Bot 2014-01-09 16:51:38 PST
Comment on attachment 220785 [details]
Patch

Clearing flags on attachment: 220785

Committed r161604: <http://trac.webkit.org/changeset/161604>
Comment 18 WebKit Commit Bot 2014-01-09 16:51:40 PST
All reviewed patches have been landed.  Closing bug.