LibWeb: Unbreak harfbuzz text layout

The reason we were keeping track of the pre-shaping buffer was to know
where we had tab characters in the input. This is a very strange way of
doing that, but since it broke the web, let's patch it up quickly.

Follow-up to #1870 which broke text layout on many web pages.
This commit is contained in:
Andreas Kling 2024-10-21 10:30:12 +02:00
parent 14f5f51147
commit a8d0712c28
3 changed files with 23 additions and 18 deletions

View File

@ -3,7 +3,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <body> at (8,8) content-size 784x68 children: not-inline
BlockContainer <div> at (8,8) content-size 784x17 children: inline
frag 0 from BlockContainer start: 0, length: 0, rect: [8,21 60x0] baseline: 0
frag 1 from TextNode start: 0, length: 2, rect: [68,8 88.109375x17] baseline: 13.296875
frag 1 from TextNode start: 0, length: 2, rect: [68,8 82.265625x17] baseline: 13.296875
" A"
BlockContainer <span#s1> at (8,21) content-size 60x0 inline-block [BFC] children: not-inline
TextNode <#text>
@ -11,7 +11,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
TextNode <#text>
BlockContainer <div> at (8,25) content-size 784x17 children: inline
frag 0 from BlockContainer start: 0, length: 0, rect: [8,38 70x0] baseline: 0
frag 1 from TextNode start: 0, length: 2, rect: [78,25 78.109375x17] baseline: 13.296875
frag 1 from TextNode start: 0, length: 2, rect: [78,25 72.265625x17] baseline: 13.296875
" A"
BlockContainer <span#s2> at (8,38) content-size 70x0 inline-block [BFC] children: not-inline
TextNode <#text>
@ -19,7 +19,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
TextNode <#text>
BlockContainer <div> at (8,42) content-size 784x17 children: inline
frag 0 from BlockContainer start: 0, length: 0, rect: [8,55 73x0] baseline: 0
frag 1 from TextNode start: 0, length: 2, rect: [81,42 75.109375x17] baseline: 13.296875
frag 1 from TextNode start: 0, length: 2, rect: [81,42 69.265625x17] baseline: 13.296875
" A"
BlockContainer <span#s3> at (8,55) content-size 73x0 inline-block [BFC] children: not-inline
TextNode <#text>

View File

@ -2,19 +2,19 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x67 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x51 children: not-inline
BlockContainer <div> at (8,8) content-size 100x51 children: inline
frag 0 from BlockContainer start: 0, length: 0, rect: [8,8 120.109375x17] baseline: 13.296875
frag 1 from BlockContainer start: 0, length: 0, rect: [8,25 129.453125x17] baseline: 13.296875
frag 2 from BlockContainer start: 0, length: 0, rect: [8,42 139.765625x17] baseline: 13.296875
BlockContainer <span> at (8,8) content-size 120.109375x17 inline-block [BFC] children: inline
frag 0 from TextNode start: 0, length: 2, rect: [8,8 120.109375x17] baseline: 13.296875
frag 0 from BlockContainer start: 0, length: 0, rect: [8,8 114.265625x17] baseline: 13.296875
frag 1 from BlockContainer start: 0, length: 0, rect: [8,25 123.609375x17] baseline: 13.296875
frag 2 from BlockContainer start: 0, length: 0, rect: [8,42 133.921875x17] baseline: 13.296875
BlockContainer <span> at (8,8) content-size 114.265625x17 inline-block [BFC] children: inline
frag 0 from TextNode start: 0, length: 2, rect: [8,8 114.265625x17] baseline: 13.296875
" A"
TextNode <#text>
BlockContainer <span> at (8,25) content-size 129.453125x17 inline-block [BFC] children: inline
frag 0 from TextNode start: 0, length: 3, rect: [8,25 129.453125x17] baseline: 13.296875
BlockContainer <span> at (8,25) content-size 123.609375x17 inline-block [BFC] children: inline
frag 0 from TextNode start: 0, length: 3, rect: [8,25 123.609375x17] baseline: 13.296875
" AB"
TextNode <#text>
BlockContainer <span> at (8,42) content-size 139.765625x17 inline-block [BFC] children: inline
frag 0 from TextNode start: 0, length: 4, rect: [8,42 139.765625x17] baseline: 13.296875
BlockContainer <span> at (8,42) content-size 133.921875x17 inline-block [BFC] children: inline
frag 0 from TextNode start: 0, length: 4, rect: [8,42 133.921875x17] baseline: 13.296875
" ABC"
TextNode <#text>
BlockContainer <(anonymous)> at (8,59) content-size 784x0 children: inline
@ -23,11 +23,11 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x67]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x51]
PaintableWithLines (BlockContainer<DIV>) [8,8 100x51] overflow: [8,8 139.765625x51]
PaintableWithLines (BlockContainer<SPAN>) [8,8 120.109375x17]
PaintableWithLines (BlockContainer<DIV>) [8,8 100x51] overflow: [8,8 133.921875x51]
PaintableWithLines (BlockContainer<SPAN>) [8,8 114.265625x17]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<SPAN>) [8,25 129.453125x17]
PaintableWithLines (BlockContainer<SPAN>) [8,25 123.609375x17]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<SPAN>) [8,42 139.765625x17]
PaintableWithLines (BlockContainer<SPAN>) [8,42 133.921875x17]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,59 784x0]

View File

@ -22,17 +22,22 @@ RefPtr<GlyphRun> shape_text(FloatPoint baseline_start, Utf8View string, Gfx::Fon
u32 glyph_count;
auto* glyph_info = hb_buffer_get_glyph_infos(buffer, &glyph_count);
// FIXME: This is a very inefficient way to keep track of where we had tabs in the input string.
Vector<u32> input_code_points;
input_code_points.ensure_capacity(glyph_count);
for (size_t i = 0; i < glyph_count; ++i)
input_code_points.append(glyph_info[i].codepoint);
auto* hb_font = font.harfbuzz_font();
hb_shape(hb_font, buffer, nullptr, 0);
glyph_info = hb_buffer_get_glyph_infos(buffer, &glyph_count);
auto* positions = hb_buffer_get_glyph_positions(buffer, &glyph_count);
Vector<hb_glyph_info_t> const input_glyph_info({ glyph_info, glyph_count });
Vector<Gfx::DrawGlyph> glyph_run;
FloatPoint point = baseline_start;
for (size_t i = 0; i < glyph_count; ++i) {
if (input_glyph_info[i].codepoint == '\t')
if (input_code_points[i] == '\t')
continue;
auto position = point