WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
98062
[chromium] Subpixel text positioning causes incorrect inline-block layout.
https://bugs.webkit.org/show_bug.cgi?id=98062
Summary
[chromium] Subpixel text positioning causes incorrect inline-block layout.
Robert Flack
Reported
2012-10-01 13:43:44 PDT
When the attached page is viewed with subpixel text positioning enabled it causes the page to have a horizontal scrollbar and a scrollWidth 1 greater than the offsetWidth even though all the content fits on the page. Interestingly the span's scrollWidth is also 1 greater than its offsetWidth.
Attachments
Test case showing the subpixel text positioning size problem
(230 bytes, text/html)
2012-10-01 13:50 PDT
,
Robert Flack
no flags
Details
Patch
(1.49 KB, patch)
2012-10-26 14:56 PDT
,
Terry Anderson
tdanderson
: review-
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Levi Weintraub
Comment 1
2012-10-01 13:45:00 PDT
Super interesting. Can you give attaching the test page another try?
Robert Flack
Comment 2
2012-10-01 13:50:22 PDT
Created
attachment 166534
[details]
Test case showing the subpixel text positioning size problem
Levi Weintraub
Comment 3
2012-10-01 13:56:43 PDT
What version of Chrome are you repro-ing with? Emil and I tried to repro with 22, 23, and 24 on Windows, Mac, and Linux to no avail.
Levi Weintraub
Comment 4
2012-10-01 13:57:18 PDT
Sorry, I missed the "subpixel text positioning" part. Sorry!
vollick
Comment 5
2012-10-03 08:22:10 PDT
This bug is possibly related to
http://codereview.chromium.org/10996037/
. We were doing some dodgy RectF to Rect conversions in chrome -- we were just flooring the position and size when we should have been taking either the enclosing or enclosed rect -- so I got rid of these conversions. There are a couple of spots where I'd chosen ToEnclosingRect rather than the old conversion, and this might have been the wrong choice and may be causing some rects to be one pixel larger than they ought to be.
Terry Anderson
Comment 6
2012-10-26 14:56:28 PDT
Created
attachment 171021
[details]
Patch
Terry Anderson
Comment 7
2012-10-26 14:57:13 PDT
(In reply to
comment #6
)
> Created an attachment (id=171021) [details] > Patch
This issue only reproduces in some cases. In the attached test case, if you replace the span with <span>x</span> the problem does not reproduce, but with <span>xx</span> it does. The horizontal scrollbar appears because in ScrollView::updateScrollbars(), the contents width is reported as being 1 larger than the visible width. I looked at the value of layoutOverflowRect().width() in RenderView::unscaledDocumentRect() after changing the text of the test case. Here is some data: (text on test page, layoutOverflowRect().width(), horizontal scrollbar present?) 'x', 575.296875, no 'xx', 575.609375, yes 'xxx', 575.906250, yes 'xxxx', 575.218750, no 'Hello, world!', 575.765625, yes This seemed to indicate that rounding (rather than always taking the floor) may be responsible for the one pixel difference. This patch indeed fixes the bug but is likely not a landable solution. An alternate solution could be to ensure that overflow is not falsely reported (perhaps using knownToHaveNoOverflow() ?). If |m_overflow| in RenderBox is never set, then layoutOverflowRect().width() will always be 575.000000.
Terry Anderson
Comment 8
2012-10-28 16:35:08 PDT
Levi or Emil, are you able to provide any guidance about the best way to proceed here?
Levi Weintraub
Comment 9
2012-10-30 04:03:49 PDT
(In reply to
comment #7
)
> I looked at the value of layoutOverflowRect().width() in RenderView::unscaledDocumentRect() after changing the text of the test case. Here is some data: > > (text on test page, layoutOverflowRect().width(), horizontal scrollbar present?) > 'x', 575.296875, no > 'xx', 575.609375, yes > 'xxx', 575.906250, yes > 'xxxx', 575.218750, no > 'Hello, world!', 575.765625, yes > > This seemed to indicate that rounding (rather than always taking the floor) may be responsible for the one pixel difference. This patch indeed fixes the bug but is likely not a landable solution. > > An alternate solution could be to ensure that overflow is not falsely reported (perhaps using knownToHaveNoOverflow() ?). If |m_overflow| in RenderBox is never set, then layoutOverflowRect().width() will always be 575.000000.
Rounding is, of course, necessary for sub-pixel layout to work properly. Are you saying that we're only setting m_overflow in the fail case? We should be treating all values as LayoutUnits when determining if we overflow. What's the delta between the client rect and the value we're using to determine that we have overflow when it occurs? If you turn off sub-pixel layout (in Platform.h, not FractionalLayoutUnit.h), does the problem go away? Do we not set m_overflow in that case? This is a step towards the problem, but it's not quite enough to understand the root cause yet.
Terry Anderson
Comment 10
2012-11-01 15:41:47 PDT
(In reply to
comment #9
)
> (In reply to
comment #7
) > > I looked at the value of layoutOverflowRect().width() in RenderView::unscaledDocumentRect() after changing the text of the test case. Here is some data: > > > > (text on test page, layoutOverflowRect().width(), horizontal scrollbar present?) > > 'x', 575.296875, no > > 'xx', 575.609375, yes > > 'xxx', 575.906250, yes > > 'xxxx', 575.218750, no > > 'Hello, world!', 575.765625, yes > > > > This seemed to indicate that rounding (rather than always taking the floor) may be responsible for the one pixel difference. This patch indeed fixes the bug but is likely not a landable solution. > > > > An alternate solution could be to ensure that overflow is not falsely reported (perhaps using knownToHaveNoOverflow() ?). If |m_overflow| in RenderBox is never set, then layoutOverflowRect().width() will always be 575.000000. > > Rounding is, of course, necessary for sub-pixel layout to work properly. Are you saying that we're only setting m_overflow in the fail case? We should be treating all values as LayoutUnits when determining if we overflow. What's the delta between the client rect and the value we're using to determine that we have overflow when it occurs? If you turn off sub-pixel layout (in Platform.h, not FractionalLayoutUnit.h), does the problem go away? Do we not set m_overflow in that case? > > This is a step towards the problem, but it's not quite enough to understand the root cause yet.
On further investigation, |m_overflow| (in RenderBox and InlineFlowBox) is getting set in both the pass case ('x') and the fail case ('xx'). When determining if we have overflow in the pass case, the overflow rect width is 0.296875 larger than the client rect. When determining if we have overflow in the fail case, the overflow rect width is 0.609375 larger than the client rect. Despite having |m_overflow| set, the pass case does not invoke a horizontal scrollbar because the 0.296875 disappears as a result of rounding when setting the integer contents size. If I disable sub-pixel layout as you suggested, the problem does indeed go away and |m_overflow| is never set in either RenderBox or InlineFlowBox.
Levi Weintraub
Comment 11
2012-11-02 07:10:49 PDT
(In reply to
comment #10
)
> If I disable sub-pixel layout as you suggested, the problem does indeed go away and |m_overflow| is never set in either RenderBox or InlineFlowBox.
Aha! That's most definitely a bug we can look into :)
Terry Anderson
Comment 12
2012-11-08 09:59:50 PST
Fixed with
http://trac.webkit.org/changeset/133903
Emil A Eklund
Comment 13
2012-11-08 10:01:46 PST
Awesome, thanks for verifying Terry!
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug