RESOLVED FIXED 205990
A partially selected RTL text is placed at a wrong vertical position if it has a vertical initial advance
https://bugs.webkit.org/show_bug.cgi?id=205990
Summary A partially selected RTL text is placed at a wrong vertical position if it ha...
Fujii Hironori
Reported 2020-01-08 22:29:16 PST
[HarfBuzz] A partially selected RTL text is placed at a wrong vertical position if it has a vertical initial advance GTK port, trunk@254184 1. Go to https://ar.wikipedia.org/wiki/%D8%B3%D9%88%D8%B1%D8%A9_%D8%A7%D9%84%D8%A5%D8%AE%D9%84%D8%A7%D8%B5 2. Select a text which has Arabic diacritics by drugging mouse cursor slowly You can observe glyphs are dancing vertically. This issue still happens even after r254190 fixing other initial advance bug (Bug 118221).
Attachments
test case (192 bytes, text/html)
2020-01-08 22:30 PST, Fujii Hironori
no flags
[screenshot] GTK port (31.04 KB, image/png)
2020-01-08 22:32 PST, Fujii Hironori
no flags
[Screenshot] WinCairo port (12.77 KB, image/png)
2020-01-08 23:56 PST, Fujii Hironori
no flags
WIP Patch (11.62 KB, patch)
2020-01-09 02:18 PST, Fujii Hironori
no flags
WIP Patch (13.79 KB, patch)
2020-01-09 02:48 PST, Fujii Hironori
no flags
WIP Patch (13.80 KB, patch)
2020-01-09 03:01 PST, Fujii Hironori
no flags
WIP Patch (1.12 KB, patch)
2020-01-09 03:12 PST, Fujii Hironori
no flags
WIP Patch (13.80 KB, patch)
2020-01-09 03:14 PST, Fujii Hironori
no flags
WIP patch (11.46 KB, patch)
2020-01-09 20:19 PST, Fujii Hironori
no flags
WIP patch (11.97 KB, patch)
2020-01-09 22:34 PST, Fujii Hironori
no flags
Patch to add a test (1.46 KB, patch)
2020-01-16 21:53 PST, Fujii Hironori
no flags
Patch (18.46 KB, patch)
2020-01-17 01:19 PST, Fujii Hironori
no flags
Patch (11.97 KB, patch)
2020-01-17 01:22 PST, Fujii Hironori
no flags
Patch (11.97 KB, patch)
2020-01-17 01:24 PST, Fujii Hironori
no flags
Patch (16.45 KB, patch)
2020-01-17 01:26 PST, Fujii Hironori
no flags
Patch (16.99 KB, patch)
2020-01-20 00:17 PST, Fujii Hironori
no flags
Patch (24.07 KB, patch)
2020-01-20 19:03 PST, Fujii Hironori
no flags
Patch (23.91 KB, patch)
2020-01-20 19:51 PST, Fujii Hironori
no flags
Fujii Hironori
Comment 1 2020-01-08 22:30:03 PST
Created attachment 387194 [details] test case
Fujii Hironori
Comment 2 2020-01-08 22:32:06 PST
Created attachment 387195 [details] [screenshot] GTK port
Fujii Hironori
Comment 3 2020-01-08 23:29:08 PST
I put a break point at the end of FontCascade::getGlyphsAndAdvancesForComplexText, and observed 'glyphBuffer' variable. When drawing only latter 3 glyphs of "قُ ". (gdb) p glyphBuffer.size() $22 = 3 (gdb) p *glyphBuffer.glyphs(0)@3 $23 = {3, 1400, 1387} (gdb) p *glyphBuffer.advances(0)@3 $24 = {{m_width = 21.53125, m_height = 3.90625}, {m_width = 0.46875, m_height = -3.90625}, {m_width = 62, m_height = -0}} (gdb) p glyphBuffer.initialAdvance() $25 = (const WebCore::GlyphBufferAdvance &) @0x7ffe17333190: {m_width = -0.46875, m_height = -3.90625} When drawing all 5 glyphs, (gdb) p glyphBuffer.size() $26 = 5 (gdb) p *glyphBuffer.glyphs(0)@5 $28 = {1400, 1387, 3, 1400, 1387} (gdb) p *glyphBuffer.advances(0)@5 $29 = {{m_width = 0.46875, m_height = -3.90625}, {m_width = 62, m_height = -0}, {m_width = 21.53125, m_height = 3.90625}, {m_width = 0.46875, m_height = -3.90625}, {m_width = 62, m_height = -0}} (gdb) p glyphBuffer.initialAdvance() $30 = (const WebCore::GlyphBufferAdvance &) @0x7ffe17332cd0: {m_width = -0.46875, m_height = -3.90625} The glyph 1400 is painted on y=-3.90625 for the all glyphs case, but y=0 for latter 3 glyphs case.
Fujii Hironori
Comment 4 2020-01-08 23:51:15 PST
This issue will happen for WinCairo port if it'd use ComplexTextController by applying the patch of Bug 204884. All 5 glyphs painting case: glyphs: 757 981 3 757 981 initial advance: 9.0 4.0 advances: (-9,4) (47,0) (31,-4) (-9,4) (47,0) Only latter 3 glyphs painting case: glyphs: 3 757 981 initial advance: 9.0 4.0 advances: (31,-4) (-9,4) (47,0) The glyph 757 is painted at y=4 for the first case, and y=0 for the second case.
Fujii Hironori
Comment 5 2020-01-08 23:56:40 PST
Created attachment 387197 [details] [Screenshot] WinCairo port
Fujii Hironori
Comment 6 2020-01-09 02:16:38 PST
FontCascade::getGlyphsAndAdvancesForComplexText is calculating initialAdvance by subtracting RTL text's advances from totalWidth. It should do same for y-axis.
Fujii Hironori
Comment 7 2020-01-09 02:18:10 PST
Created attachment 387203 [details] WIP Patch
Fujii Hironori
Comment 8 2020-01-09 02:48:14 PST
Created attachment 387207 [details] WIP Patch
Fujii Hironori
Comment 9 2020-01-09 03:01:07 PST
Created attachment 387209 [details] WIP Patch
Fujii Hironori
Comment 10 2020-01-09 03:12:33 PST
Created attachment 387210 [details] WIP Patch
Fujii Hironori
Comment 11 2020-01-09 03:14:02 PST
Created attachment 387211 [details] WIP Patch
Fujii Hironori
Comment 12 2020-01-09 20:19:27 PST
Created attachment 387310 [details] WIP patch
Fujii Hironori
Comment 13 2020-01-09 22:34:43 PST
Created attachment 387314 [details] WIP patch
Fujii Hironori
Comment 14 2020-01-16 21:53:25 PST
Created attachment 388011 [details] Patch to add a test
Fujii Hironori
Comment 15 2020-01-17 01:19:36 PST
Fujii Hironori
Comment 16 2020-01-17 01:22:42 PST
Fujii Hironori
Comment 17 2020-01-17 01:24:47 PST
Fujii Hironori
Comment 18 2020-01-17 01:26:19 PST
Fujii Hironori
Comment 19 2020-01-20 00:17:05 PST
Darin Adler
Comment 20 2020-01-20 10:25:14 PST
Comment on attachment 388209 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388209&action=review Looks like the Windows build failed — I couldn't find the error message in the EWS results, though. I retried so maybe it will succeed without any further changes. > Source/WebCore/platform/graphics/ComplexTextController.h:68 > + float totalWidth() const { return m_totalAdvance.width(); } Are there any uses of this outside the class? Can this be a private member function instead? Or maybe we can just write m_totalAdvance.width() at each of the two call sites. I’d like to cut down on proliferation of functions that do nearly the same thing. > Source/WebCore/platform/graphics/FontCascade.cpp:292 > + FloatPoint oldStartPoint(startPoint); I suggest that instead of this, we write: float oldStartX = startPoint.x(); > Source/WebCore/platform/graphics/FontCascade.cpp:1438 > + FloatPoint startPoint(point); Style wise, I think this is nicer with an "=", but not sure everyone else will agree. > Source/WebCore/platform/graphics/GlyphBuffer.h:66 > + operator FloatSize() const { return FloatSize(width(), height()); } I think it’s a little risky to add an operator that does a lossy conversion from doubles to floats, implicitly and silently. Normally we would like conversions that narrow to be named function calls.
Fujii Hironori
Comment 21 2020-01-20 17:58:16 PST
Thank you very much for the review. (In reply to Darin Adler from comment #20) > Looks like the Windows build failed — I couldn't find the error message in > the EWS results, though. I retried so maybe it will succeed without any > further changes. compile-webkit-tot actually reported the following error: > Could NOT find interface definition for Node in ./dom/Node.idl at /home/buildbot/worker/Windows-EWS/build/Source/WebCore/bindings/scripts/CodeGenerator.pm line 502. I think preprocessor.pm, run by Cygin perl, was failing to spawn gcc as a child process. Bug 84274 is the past attempt to fix the issue. AppleWin should use Win32 Perl as well as WinCairo does.
Fujii Hironori
Comment 22 2020-01-20 18:33:50 PST
Comment on attachment 388209 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388209&action=review >> Source/WebCore/platform/graphics/ComplexTextController.h:68 >> + float totalWidth() const { return m_totalAdvance.width(); } > > Are there any uses of this outside the class? Can this be a private member function instead? Or maybe we can just write m_totalAdvance.width() at each of the two call sites. I’d like to cut down on proliferation of functions that do nearly the same thing. totalAdvance() is used in FontCascade. Will remove totalWidth(). >> Source/WebCore/platform/graphics/FontCascade.cpp:292 >> + FloatPoint oldStartPoint(startPoint); > > I suggest that instead of this, we write: > > float oldStartX = startPoint.x(); Will fix. >> Source/WebCore/platform/graphics/FontCascade.cpp:1438 >> + FloatPoint startPoint(point); > > Style wise, I think this is nicer with an "=", but not sure everyone else will agree. Will fix. >> Source/WebCore/platform/graphics/GlyphBuffer.h:66 >> + operator FloatSize() const { return FloatSize(width(), height()); } > > I think it’s a little risky to add an operator that does a lossy conversion from doubles to floats, implicitly and silently. Normally we would like conversions that narrow to be named function calls. I'm going to add inline FloatSize toFloatSize(const GlyphBufferAdvance& a)
Fujii Hironori
Comment 23 2020-01-20 19:03:49 PST
Fujii Hironori
Comment 24 2020-01-20 19:51:08 PST
Fujii Hironori
Comment 25 2020-01-21 05:50:27 PST
I'm going to land this patch if nobody objects for a few day.
Darin Adler
Comment 26 2020-01-21 09:51:30 PST
Comment on attachment 388274 [details] Patch Looks good. I agree you should land it.
Fujii Hironori
Comment 27 2020-01-21 18:01:16 PST
Comment on attachment 388274 [details] Patch Clearing flags on attachment: 388274 Committed r254898: <https://trac.webkit.org/changeset/254898>
Fujii Hironori
Comment 28 2020-01-21 18:01:20 PST
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 29 2020-01-21 18:02:15 PST
Note You need to log in before you can comment on or make changes to this bug.