RESOLVED FIXED 3676
MIR Image replacement technique (negative letter-spacing) does not always work
https://bugs.webkit.org/show_bug.cgi?id=3676
Summary MIR Image replacement technique (negative letter-spacing) does not always work
Niels Leenheer (HTML5test)
Reported 2005-06-23 05:08:29 PDT
If a letter-spacing is applied to text each character is written seperately. After each letter is written the width of that character is added to the x coordinate. Then the letter-spacing will be added and the next character is drawn at the new x coordinate. The difference between the old x and the new x is what I call deltax below. A positive letter-spacing means that deltax is larger than it would have been if the letter-spacing was not applied. Similarly, a negative letter-spacing means that deltax is smaller than it would have been if the letter-spacing was not applied. CURRENT BEHAVOIR: If you increase the negative letter-spacing it will eventually become larger than the width of the characters and at that point deltax will become negative and the text starts to flow backwards. If the width of the negative letter-spacing is larger than the width of a character the text will run backwards. This can be demonstrated by the following little snipped of HTML: <h1 style='padding-left: 10em; letter-spacing: -32px;'>The quick brown fox...</h1>" This is displayed as: ...xof nworb kciuq ehT DESIRED BEHAVOIR: If you increase the negative letter-spacing it will eventually become larger than the width of the characters and at that point deltax will become negative. If deltax is don't draw the character. This means that text that used to flow backwards now simply is not shown at all, as desired by the MIR image replacement technique.
Attachments
Testcase (888 bytes, text/html)
2005-06-23 05:11 PDT, Niels Leenheer (HTML5test)
no flags
Possible patch (756 bytes, patch)
2005-06-23 05:12 PDT, Niels Leenheer (HTML5test)
no flags
testcase for negative-letter-spacing (573 bytes, text/html)
2022-12-26 18:44 PST, Karl Dubost
no flags
rendering in safari, firefox, chrome (113.14 KB, image/png)
2022-12-26 18:46 PST, Karl Dubost
no flags
Test reduction (206 bytes, text/html)
2022-12-28 20:39 PST, zalan
no flags
Test case screenshot (13.23 KB, image/png)
2022-12-28 21:23 PST, zalan
no flags
Test case screenshot (2) (24.30 KB, image/png)
2022-12-28 21:24 PST, zalan
no flags
test case screenshot (original) (121.90 KB, image/png)
2022-12-28 21:25 PST, zalan
no flags
Patch (6.60 KB, patch)
2022-12-29 10:39 PST, zalan
no flags
Niels Leenheer (HTML5test)
Comment 1 2005-06-23 05:11:24 PDT
Created attachment 2580 [details] Testcase This testcase contains 10 lines. - Line 1 - 3 should contain the string "The quick brown fox jumps..." in various letter spacings. - Line 4 - 9 should be completely empty. - Line 10 should contain the string "The quick brown over the lazy dog".
Niels Leenheer (HTML5test)
Comment 2 2005-06-23 05:12:25 PDT
Created attachment 2581 [details] Possible patch This seems too simple, but it does solve the problem on various testcases and live websites. Any comments?
Ian 'Hixie' Hickson
Comment 3 2005-06-23 07:23:05 PDT
This is invalid. Negative letter spacing _should_ make the text go backwards. That fact that it doesn't in other browsers is a bug in those browsers.
Ian 'Hixie' Hickson
Comment 4 2005-06-23 07:32:13 PDT
Niels Leenheer (HTML5test)
Comment 5 2005-06-23 23:47:17 PDT
The CSS 2.1 spec says the following about negative letter-spacing: Values may be negative, but there may be implementation-specific limits. At the moment the two browsers that are used most, Internet Explorer and Firefox both have an implementation-specific limit that result in the text disappearing when a large negative value is used. Emulating the behavoir of those two browsers and adding an artificial limit to KHTML/Webcore is not contrary to the CSS 2.1 spec. On the other hand it will improve compatibility with websites that employ the MIR image replacement technique, which depends on the behavoir of IE and Firefox.
Dave Hyatt
Comment 6 2005-06-24 11:32:41 PDT
Agreed.
Ian 'Hixie' Hickson
Comment 7 2005-06-25 18:09:34 PDT
Doing what IE does here is stupid. It makes it impossible to achieve several dynamic effects. Opera already does the right thing here, as will Mozilla in due course. The implementation-specific limits clause is not supposed to mean you can fail to do the right thing if you want to, it's to allow small devices that can't handle negative numbers to do a "best effort" rendering. This bug is INVALID. If it is "fixed" it should be in quirks mode only, and important pages that it breaks should be listed.
Dave Hyatt
Comment 8 2005-06-25 19:18:11 PDT
Can someone from Gecko comment on whether they intend to fix the bug? If they don't, then I feel that we should change to match.
Robert O'Callahan
Comment 9 2006-04-16 17:49:52 PDT
I think it's a bug that we should fix in Gecko.
Brent Fulgham
Comment 10 2022-07-06 11:29:47 PDT
We do not have the same behavior as Chrome or Firefox for the final line of the test case (the string with multiple colors).
Radar WebKit Bug Importer
Comment 11 2022-07-06 11:30:02 PDT
Karl Dubost
Comment 12 2022-12-26 18:44:45 PST
Created attachment 464215 [details] testcase for negative-letter-spacing As Brent said, Only the last test case is now failing. Let's make it simpler and easier to understand what is happening.
Karl Dubost
Comment 13 2022-12-26 18:46:33 PST
Created attachment 464216 [details] rendering in safari, firefox, chrome Tested on macOS 13.3 --- Safari Technology Preview 160 18615.1.14.3 Firefox Nightly 110.0a1 11022.12.14 Google Chrome Canary 111.0.5499.0 5499.0
zalan
Comment 14 2022-12-28 20:39:53 PST
Created attachment 464239 [details] Test reduction Thank you Karl for the negative letter-spacing test case.
zalan
Comment 15 2022-12-28 21:23:41 PST
Created attachment 464241 [details] Test case screenshot This fixes both test cases. diff --git a/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp b/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp index a1d927521680..7d84517d22cd 100644 --- a/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp +++ b/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp @@ -403,7 +403,8 @@ void Line::appendInlineBoxEnd(const InlineItem& inlineItem, const RenderStyle& s // https://drafts.csswg.org/css-text-3/#letter-spacing-property See example 21. removeTrailingLetterSpacing(); m_contentLogicalWidth -= removeBorderAndPaddingEndForInlineBoxDecorationClone(inlineItem); - auto logicalLeft = lastRunLogicalRight(); + // Negative letter spacing should only shorten the content to the boundary of the previous run. + auto logicalLeft = style.letterSpacing() < 0 ? m_contentLogicalWidth : lastRunLogicalRight(); m_runs.append({ inlineItem, style, logicalLeft, logicalWidth }); // Do not let negative margin make the content shorter than it already is. m_contentLogicalWidth = std::max(m_contentLogicalWidth, logicalLeft + logicalWidth);
zalan
Comment 16 2022-12-28 21:24:11 PST
Created attachment 464242 [details] Test case screenshot (2)
zalan
Comment 17 2022-12-28 21:25:28 PST
Created attachment 464243 [details] test case screenshot (original)
zalan
Comment 18 2022-12-29 10:39:32 PST
Antti Koivisto
Comment 19 2022-12-29 11:18:35 PST
Antti Koivisto
Comment 20 2022-12-29 11:54:15 PST
Comment on attachment 2581 [details] Possible patch View in context: https://bugs.webkit.org/attachment.cgi?id=2581&action=review > font.cpp:107 > - if ( d == QPainter::RTL ) > + > + if ( d == QPainter::RTL ) { > + if (chw > 0) > + return; > + > x -= chw; > + } else if (chw < 0) > + return; I do like this patch too.
zalan
Comment 21 2022-12-29 12:03:52 PST
(In reply to Antti Koivisto from comment #20) > Comment on attachment 2581 [details] > Possible patch > > View in context: https://bugs.webkit.org/attachment.cgi?id=2581&action=review > > > font.cpp:107 > > - if ( d == QPainter::RTL ) > > + > > + if ( d == QPainter::RTL ) { > > + if (chw > 0) > > + return; > > + > > x -= chw; > > + } else if (chw < 0) > > + return; > > I do like this patch too. will check if it applies (need to install cvs first)
EWS
Comment 22 2022-12-29 12:40:50 PST
Committed 258356@main (4aee4f4a4f9d): <https://commits.webkit.org/258356@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 464249 [details].
Note You need to log in before you can comment on or make changes to this bug.