LibWeb: Make inline paintables own their fragments

The paintable tree structure more closely matches the painting order
when fragments are owned by corresponding inline paintables. This
change does not affect the layout tree, as it is more convenient for
layout purposes to have all fragments owned by a block container in
one place.

Additionally, this improves performance significantly on pages with
many fragments, as we no longer have to walk the ancestor chain up
to the closest block container to determine if a fragment belongs
to an inline paintable.
This commit is contained in:
Aliaksandr Kalenik 2024-01-13 13:11:31 +01:00 committed by Alexander Kalenik
parent 5ed936289a
commit 2960bf4ec8
Notes: sideshowbarker 2024-07-17 09:37:30 +09:00
34 changed files with 310 additions and 258 deletions

View File

@ -95,23 +95,23 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
"agents should be able to render the document elements above this paragraph"
frag 2 from TextNode start: 167, length: 43, rect: [20,361 207.890625x13] baseline: 9.5
"indistinguishably (to the pixel) from this "
frag 3 from TextNode start: 0, length: 20, rect: [228,361 103.015625x13] baseline: 9.5
"reference rendering,"
frag 4 from TextNode start: 0, length: 31, rect: [331,361 159.671875x13] baseline: 9.5
frag 3 from TextNode start: 0, length: 31, rect: [331,361 159.671875x13] baseline: 9.5
" (except font rasterization and"
frag 5 from TextNode start: 32, length: 89, rect: [20,374 465.015625x13] baseline: 9.5
frag 4 from TextNode start: 32, length: 89, rect: [20,374 465.015625x13] baseline: 9.5
"form widgets). All discrepancies should be traceable to CSS1 implementation shortcomings."
frag 6 from TextNode start: 122, length: 67, rect: [20,387 345.546875x13] baseline: 9.5
frag 5 from TextNode start: 122, length: 67, rect: [20,387 345.546875x13] baseline: 9.5
"Once you have finished evaluating this test, you can return to the "
frag 7 from TextNode start: 0, length: 11, rect: [366,387 59.890625x13] baseline: 9.5
"parent page"
frag 8 from TextNode start: 0, length: 1, rect: [425,387 2.71875x13] baseline: 9.5
frag 6 from TextNode start: 0, length: 1, rect: [425,387 2.71875x13] baseline: 9.5
"."
TextNode <#text>
InlineNode <a>
frag 0 from TextNode start: 0, length: 20, rect: [228,361 103.015625x13] baseline: 9.5
"reference rendering,"
TextNode <#text>
TextNode <#text>
InlineNode <a>
frag 0 from TextNode start: 0, length: 11, rect: [366,387 59.890625x13] baseline: 9.5
"parent page"
TextNode <#text>
TextNode <#text>
BlockContainer <(anonymous)> at (20,400) content-size 480x0 children: inline

View File

@ -1,15 +1,13 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x34 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [108,8 6.34375x17] baseline: 13.296875
"1"
frag 1 from TextNode start: 0, length: 1, rect: [108,25 8.8125x17] baseline: 13.296875
"2"
BlockContainer <span.a> at (8,8) content-size 100x17 floating [BFC] children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,8 14.265625x17] baseline: 13.296875
"A"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [108,8 6.34375x17] baseline: 13.296875
"1"
TextNode <#text>
TextNode <#text>
BreakNode <br>
@ -19,6 +17,8 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
"B"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [108,25 8.8125x17] baseline: 13.296875
"2"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]

View File

@ -2,9 +2,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,16) content-size 784x19 children: not-inline
BlockContainer <pre> at (9,17) content-size 782x17 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [9,17 8x17] baseline: 13.296875
" "
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [9,17 8x17] baseline: 13.296875
" "
TextNode <#text>
TextNode <#text>

View File

@ -3,9 +3,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <body> at (10,10) content-size 500x81 children: not-inline
BlockContainer <div.a> at (51,21) content-size 413x49 children: not-inline
BlockContainer <div.b> at (92,32) content-size 326x17 children: inline
frag 0 from TextNode start: 0, length: 5, rect: [93,32 39.78125x17] baseline: 13.296875
"Hello"
InlineNode <span>
frag 0 from TextNode start: 0, length: 5, rect: [93,32 39.78125x17] baseline: 13.296875
"Hello"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]

View File

@ -3,9 +3,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <body> at (10,10) content-size 500x101 children: not-inline
BlockContainer <div.a> at (31,21) content-size 458x79 children: not-inline
BlockContainer <div.b> at (72,52) content-size 376x17 children: inline
frag 0 from TextNode start: 0, length: 5, rect: [73,52 39.78125x17] baseline: 13.296875
"Hello"
InlineNode <span>
frag 0 from TextNode start: 0, length: 5, rect: [73,52 39.78125x17] baseline: 13.296875
"Hello"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]

View File

@ -2,17 +2,17 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x152 children: not-inline
BlockContainer <(anonymous)> at (8,8) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 5, rect: [8,8 36.40625x17] baseline: 13.296875
"well "
frag 1 from TextNode start: 0, length: 6, rect: [44,33 44.84375x17] baseline: 13.296875
"hello "
frag 2 from TextNode start: 0, length: 7, rect: [89,58 55.359375x17] baseline: 13.296875
"friends"
InlineNode <span>
frag 0 from TextNode start: 0, length: 5, rect: [8,8 36.40625x17] baseline: 13.296875
"well "
TextNode <#text>
InlineNode <b>
frag 0 from TextNode start: 0, length: 6, rect: [44,33 44.84375x17] baseline: 13.296875
"hello "
TextNode <#text>
InlineNode <i>
frag 0 from TextNode start: 0, length: 7, rect: [89,58 55.359375x17] baseline: 13.296875
"friends"
TextNode <#text>
TextNode <#text>
BlockContainer <div> at (8,25) content-size 784x135 children: not-inline
@ -36,7 +36,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x152] overflow: [8,8 784x168]
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x17] overflow: [8,8 784x67]
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x17]
InlinePaintable (InlineNode<SPAN>)
TextPaintable (TextNode<#text>)
InlinePaintable (InlineNode<B>)

View File

@ -3,24 +3,24 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <body> at (8,8) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 4, rect: [8,8 35.15625x17] baseline: 13.296875
"foo "
frag 1 from TextNode start: 0, length: 3, rect: [43,33 27.640625x17] baseline: 13.296875
"bar"
frag 2 from TextNode start: 0, length: 1, rect: [71,8 8x17] baseline: 13.296875
frag 1 from TextNode start: 0, length: 1, rect: [71,8 8x17] baseline: 13.296875
" "
frag 3 from TextNode start: 0, length: 3, rect: [54,58 27.203125x17] baseline: 13.296875
"baz"
TextNode <#text>
InlineNode <b>
frag 0 from TextNode start: 0, length: 3, rect: [43,33 27.640625x17] baseline: 13.296875
"bar"
TextNode <#text>
TextNode <#text>
InlineNode <b>
InlineNode <i>
frag 0 from TextNode start: 0, length: 3, rect: [54,58 27.203125x17] baseline: 13.296875
"baz"
TextNode <#text>
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x17] overflow: [8,8 784x67]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x17] overflow: [8,8 784x42]
TextPaintable (TextNode<#text>)
InlinePaintable (InlineNode<B>)
TextPaintable (TextNode<#text>)

View File

@ -2,11 +2,11 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x83 [BFC] children: not-inline
BlockContainer <body> at (8,16) content-size 784x67 children: not-inline
BlockContainer <p> at (8,16) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,16 10.625x17] baseline: 13.296875
"+"
frag 1 from TextNode start: 0, length: 36, rect: [19,16 300x17] baseline: 13.296875
frag 0 from TextNode start: 0, length: 36, rect: [19,16 300x17] baseline: 13.296875
"P should generate a ::before pseudo."
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [8,16 10.625x17] baseline: 13.296875
"+"
TextNode <#text>
TextNode <#text>
BlockContainer <(anonymous)> at (8,49) content-size 784x34 children: inline

View File

@ -1,13 +1,13 @@
Viewport <#document> at (0,0) content-size 800x600 children: inline
frag 0 from TextNode start: 1, length: 18, rect: [0,0 134.984375x17] baseline: 13.296875
"* { all: unset; } "
frag 1 from TextNode start: 0, length: 13, rect: [135,0 103.140625x17] baseline: 13.296875
"Hello friends"
InlineNode <html>
InlineNode <head>
InlineNode <style>
frag 0 from TextNode start: 1, length: 18, rect: [0,0 134.984375x17] baseline: 13.296875
"* { all: unset; } "
TextNode <#text>
InlineNode <body>
frag 0 from TextNode start: 0, length: 13, rect: [135,0 103.140625x17] baseline: 13.296875
"Hello friends"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]

View File

@ -1,25 +1,25 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x79 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,25 39.09375x56] baseline: 43.328125
"H"
frag 1 from TextNode start: 0, length: 1, rect: [47,38 19.78125x40] baseline: 30.875
"e"
frag 2 from TextNode start: 0, length: 1, rect: [67,47 6.8125x28] baseline: 21.71875
"l"
frag 3 from TextNode start: 0, length: 1, rect: [74,53 4.84375x20] baseline: 15.484375
"l"
frag 4 from TextNode start: 0, length: 1, rect: [79,58 8.40625x14] baseline: 10.890625
"o"
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [8,25 39.09375x56] baseline: 43.328125
"H"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [47,38 19.78125x40] baseline: 30.875
"e"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [67,47 6.8125x28] baseline: 21.71875
"l"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [74,53 4.84375x20] baseline: 15.484375
"l"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [79,58 8.40625x14] baseline: 10.890625
"o"
TextNode <#text>
TextNode <#text>

View File

@ -2,10 +2,10 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,20) content-size 784x22 children: not-inline
BlockContainer <p> at (8,20) content-size 784x22 children: inline
frag 0 from TextNode start: 0, length: 15, rect: [18,20 163.890625x22] baseline: 17
"Should be green"
TextNode <#text>
InlineNode <a>
frag 0 from TextNode start: 0, length: 15, rect: [18,20 163.890625x22] baseline: 17
"Should be green"
TextNode <#text>
TextNode <#text>
BlockContainer <(anonymous)> at (8,62) content-size 784x0 children: inline

View File

@ -2,10 +2,10 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,20) content-size 784x22 children: not-inline
BlockContainer <p> at (8,20) content-size 784x22 children: inline
frag 0 from TextNode start: 0, length: 13, rect: [13,20 141.34375x22] baseline: 17
"Should be red"
TextNode <#text>
InlineNode <a>
frag 0 from TextNode start: 0, length: 13, rect: [13,20 141.34375x22] baseline: 17
"Should be red"
TextNode <#text>
TextNode <#text>
BlockContainer <(anonymous)> at (8,62) content-size 784x0 children: inline

View File

@ -16,9 +16,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
TextNode <#text>
TextNode <#text>
BlockContainer <div> at (9,164) content-size 782x44 children: inline
frag 0 from TextNode start: 0, length: 5, rect: [10,164 99.453125x44] baseline: 34
"Hello"
InlineNode <a>
frag 0 from TextNode start: 0, length: 5, rect: [10,164 99.453125x44] baseline: 34
"Hello"
TextNode <#text>
BlockContainer <(anonymous)> at (8,209) content-size 784x0 children: inline
TextNode <#text>

View File

@ -2,41 +2,41 @@ 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.a> at (8,8) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,8 9.34375x17] baseline: 13.296875
"a"
frag 1 from TextNode start: 0, length: 1, rect: [17,8 9.46875x17] baseline: 13.296875
"b"
frag 2 from TextNode start: 0, length: 1, rect: [27,8 8.890625x17] baseline: 13.296875
"c"
frag 3 from TextNode start: 0, length: 1, rect: [36,8 7.859375x17] baseline: 13.296875
"d"
frag 4 from TextNode start: 0, length: 1, rect: [44,8 8.71875x17] baseline: 13.296875
"e"
frag 5 from TextNode start: 0, length: 1, rect: [52,8 6.4375x17] baseline: 13.296875
"f"
frag 6 from TextNode start: 0, length: 1, rect: [59,8 7.5625x17] baseline: 13.296875
"g"
frag 7 from TextNode start: 0, length: 1, rect: [66,8 9.296875x17] baseline: 13.296875
"h"
frag 8 from TextNode start: 0, length: 1, rect: [76,8 4.5625x17] baseline: 13.296875
"i"
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [8,8 9.34375x17] baseline: 13.296875
"a"
frag 1 from TextNode start: 0, length: 1, rect: [76,8 4.5625x17] baseline: 13.296875
"i"
InlineNode <(anonymous)>
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [17,8 9.46875x17] baseline: 13.296875
"b"
frag 1 from TextNode start: 0, length: 1, rect: [66,8 9.296875x17] baseline: 13.296875
"h"
InlineNode <(anonymous)>
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [27,8 8.890625x17] baseline: 13.296875
"c"
frag 1 from TextNode start: 0, length: 1, rect: [59,8 7.5625x17] baseline: 13.296875
"g"
InlineNode <(anonymous)>
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [36,8 7.859375x17] baseline: 13.296875
"d"
frag 1 from TextNode start: 0, length: 1, rect: [52,8 6.4375x17] baseline: 13.296875
"f"
InlineNode <(anonymous)>
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [44,8 8.71875x17] baseline: 13.296875
"e"
InlineNode <(anonymous)>
TextNode <#text>
TextNode <#text>
@ -57,152 +57,152 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <(anonymous)> at (8,25) content-size 784x0 children: inline
TextNode <#text>
BlockContainer <div.b> at (8,25) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 3, rect: [8,25 5.84375x17] baseline: 13.296875
"“"
frag 1 from TextNode start: 0, length: 1, rect: [14,25 9.34375x17] baseline: 13.296875
"a"
frag 2 from TextNode start: 0, length: 3, rect: [23,25 5.84375x17] baseline: 13.296875
""
frag 3 from TextNode start: 0, length: 1, rect: [29,25 9.46875x17] baseline: 13.296875
"b"
frag 4 from TextNode start: 0, length: 3, rect: [39,25 5.84375x17] baseline: 13.296875
""
frag 5 from TextNode start: 0, length: 1, rect: [44,25 8.890625x17] baseline: 13.296875
"c"
frag 6 from TextNode start: 0, length: 3, rect: [53,25 5.84375x17] baseline: 13.296875
""
frag 7 from TextNode start: 0, length: 1, rect: [59,25 7.859375x17] baseline: 13.296875
"d"
frag 8 from TextNode start: 0, length: 3, rect: [67,25 5.84375x17] baseline: 13.296875
""
frag 9 from TextNode start: 0, length: 1, rect: [73,25 8.71875x17] baseline: 13.296875
"e"
frag 10 from TextNode start: 0, length: 3, rect: [82,25 5.84375x17] baseline: 13.296875
""
frag 11 from TextNode start: 0, length: 1, rect: [87,25 6.4375x17] baseline: 13.296875
"f"
frag 12 from TextNode start: 0, length: 3, rect: [94,25 5.84375x17] baseline: 13.296875
""
frag 13 from TextNode start: 0, length: 1, rect: [100,25 7.5625x17] baseline: 13.296875
"g"
frag 14 from TextNode start: 0, length: 3, rect: [107,25 5.84375x17] baseline: 13.296875
""
frag 15 from TextNode start: 0, length: 1, rect: [113,25 9.296875x17] baseline: 13.296875
"h"
frag 16 from TextNode start: 0, length: 3, rect: [122,25 5.84375x17] baseline: 13.296875
""
frag 17 from TextNode start: 0, length: 1, rect: [128,25 4.5625x17] baseline: 13.296875
"i"
frag 18 from TextNode start: 0, length: 3, rect: [133,25 5.84375x17] baseline: 13.296875
"”"
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [14,25 9.34375x17] baseline: 13.296875
"a"
frag 1 from TextNode start: 0, length: 1, rect: [128,25 4.5625x17] baseline: 13.296875
"i"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [8,25 5.84375x17] baseline: 13.296875
"“"
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [29,25 9.46875x17] baseline: 13.296875
"b"
frag 1 from TextNode start: 0, length: 1, rect: [113,25 9.296875x17] baseline: 13.296875
"h"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [23,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [44,25 8.890625x17] baseline: 13.296875
"c"
frag 1 from TextNode start: 0, length: 1, rect: [100,25 7.5625x17] baseline: 13.296875
"g"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [39,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [59,25 7.859375x17] baseline: 13.296875
"d"
frag 1 from TextNode start: 0, length: 1, rect: [87,25 6.4375x17] baseline: 13.296875
"f"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [53,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [73,25 8.71875x17] baseline: 13.296875
"e"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [67,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [82,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [94,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [107,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [122,25 5.84375x17] baseline: 13.296875
""
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 3, rect: [133,25 5.84375x17] baseline: 13.296875
"”"
TextNode <#text>
BlockContainer <(anonymous)> at (8,42) content-size 784x0 children: inline
TextNode <#text>
BlockContainer <div.c> at (8,42) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,42 5.484375x17] baseline: 13.296875
"("
frag 1 from TextNode start: 0, length: 1, rect: [13,42 9.34375x17] baseline: 13.296875
"a"
frag 2 from TextNode start: 0, length: 1, rect: [23,42 7.625x17] baseline: 13.296875
"{"
frag 3 from TextNode start: 0, length: 1, rect: [30,42 9.46875x17] baseline: 13.296875
"b"
frag 4 from TextNode start: 0, length: 1, rect: [40,42 6.953125x17] baseline: 13.296875
"["
frag 5 from TextNode start: 0, length: 1, rect: [47,42 8.890625x17] baseline: 13.296875
"c"
frag 6 from TextNode start: 0, length: 1, rect: [56,42 6.953125x17] baseline: 13.296875
"["
frag 7 from TextNode start: 0, length: 1, rect: [63,42 7.859375x17] baseline: 13.296875
"d"
frag 8 from TextNode start: 0, length: 1, rect: [71,42 6.953125x17] baseline: 13.296875
"["
frag 9 from TextNode start: 0, length: 1, rect: [78,42 8.71875x17] baseline: 13.296875
"e"
frag 10 from TextNode start: 0, length: 1, rect: [86,42 7.21875x17] baseline: 13.296875
"]"
frag 11 from TextNode start: 0, length: 1, rect: [93,42 6.4375x17] baseline: 13.296875
"f"
frag 12 from TextNode start: 0, length: 1, rect: [100,42 7.21875x17] baseline: 13.296875
"]"
frag 13 from TextNode start: 0, length: 1, rect: [107,42 7.5625x17] baseline: 13.296875
"g"
frag 14 from TextNode start: 0, length: 1, rect: [115,42 7.21875x17] baseline: 13.296875
"]"
frag 15 from TextNode start: 0, length: 1, rect: [122,42 9.296875x17] baseline: 13.296875
"h"
frag 16 from TextNode start: 0, length: 1, rect: [131,42 7.65625x17] baseline: 13.296875
"}"
frag 17 from TextNode start: 0, length: 1, rect: [139,42 4.5625x17] baseline: 13.296875
"i"
frag 18 from TextNode start: 0, length: 1, rect: [143,42 4.8125x17] baseline: 13.296875
")"
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [13,42 9.34375x17] baseline: 13.296875
"a"
frag 1 from TextNode start: 0, length: 1, rect: [139,42 4.5625x17] baseline: 13.296875
"i"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [8,42 5.484375x17] baseline: 13.296875
"("
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [30,42 9.46875x17] baseline: 13.296875
"b"
frag 1 from TextNode start: 0, length: 1, rect: [122,42 9.296875x17] baseline: 13.296875
"h"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [23,42 7.625x17] baseline: 13.296875
"{"
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [47,42 8.890625x17] baseline: 13.296875
"c"
frag 1 from TextNode start: 0, length: 1, rect: [107,42 7.5625x17] baseline: 13.296875
"g"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [40,42 6.953125x17] baseline: 13.296875
"["
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [63,42 7.859375x17] baseline: 13.296875
"d"
frag 1 from TextNode start: 0, length: 1, rect: [93,42 6.4375x17] baseline: 13.296875
"f"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [56,42 6.953125x17] baseline: 13.296875
"["
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [78,42 8.71875x17] baseline: 13.296875
"e"
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [71,42 6.953125x17] baseline: 13.296875
"["
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [86,42 7.21875x17] baseline: 13.296875
"]"
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [100,42 7.21875x17] baseline: 13.296875
"]"
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [115,42 7.21875x17] baseline: 13.296875
"]"
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [131,42 7.65625x17] baseline: 13.296875
"}"
TextNode <#text>
TextNode <#text>
InlineNode <(anonymous)>
frag 0 from TextNode start: 0, length: 1, rect: [143,42 4.8125x17] baseline: 13.296875
")"
TextNode <#text>
BlockContainer <(anonymous)> at (8,59) content-size 784x0 children: inline
TextNode <#text>

View File

@ -9,11 +9,11 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
TextNode <#text>
ListItemMarkerBox <(anonymous)> at (8,8) content-size 12x17 children: not-inline
BlockContainer <slot> at (8,25) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 10, rect: [8,25 82.3125x17] baseline: 13.296875
"I'm a node"
TextNode <#text>
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 10, rect: [8,25 82.3125x17] baseline: 13.296875
"I'm a node"
TextNode <#text>
TextNode <#text>
BlockContainer <(anonymous)> at (8,42) content-size 784x0 children: inline

View File

@ -1,8 +1,8 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x17 [BFC] children: inline
frag 0 from TextNode start: 0, length: 7, rect: [0,0 51.75x17] baseline: 13.296875
"whf :^)"
InlineNode <span>
frag 0 from TextNode start: 0, length: 7, rect: [0,0 51.75x17] baseline: 13.296875
"whf :^)"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]

View File

@ -9,9 +9,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
Box <div.aligncenter.block-image> at (8,8) content-size 1200x600 table-box [TFC] children: inline
Box <(anonymous)> at (8,8) content-size 1200x600 table-row children: inline
BlockContainer <(anonymous)> at (8,8) content-size 1200x600 table-cell [BFC] children: inline
frag 0 from ImageBox start: 0, length: 0, rect: [8,8 1200x600] baseline: 600
TextNode <#text>
InlineNode <a>
frag 0 from ImageBox start: 0, length: 0, rect: [8,8 1200x600] baseline: 600
TextNode <#text>
ImageBox <img> at (8,8) content-size 1200x600 children: not-inline
TextNode <#text>

View File

@ -1,23 +1,23 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x39 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x23 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,8 12.4375x22] baseline: 17.140625
"x"
frag 1 from TextNode start: 0, length: 1, rect: [20,12 8x17] baseline: 13.296875
frag 0 from TextNode start: 0, length: 1, rect: [20,12 8x17] baseline: 13.296875
" "
frag 2 from TextNode start: 0, length: 1, rect: [28,8 12.734375x23] baseline: 17.796875
"x"
frag 3 from TextNode start: 0, length: 1, rect: [41,12 8x17] baseline: 13.296875
frag 1 from TextNode start: 0, length: 1, rect: [41,12 8x17] baseline: 13.296875
" "
frag 4 from TextNode start: 0, length: 1, rect: [49,8 13.03125x23] baseline: 17.953125
"x"
InlineNode <span.a>
frag 0 from TextNode start: 0, length: 1, rect: [8,8 12.4375x22] baseline: 17.140625
"x"
TextNode <#text>
TextNode <#text>
InlineNode <span.b>
frag 0 from TextNode start: 0, length: 1, rect: [28,8 12.734375x23] baseline: 17.796875
"x"
TextNode <#text>
TextNode <#text>
InlineNode <span.c>
frag 0 from TextNode start: 0, length: 1, rect: [49,8 13.03125x23] baseline: 17.953125
"x"
TextNode <#text>
TextNode <#text>

View File

@ -1,9 +1,9 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x33 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 4, rect: [8,11 24.109375x13] baseline: 10.09375
"text"
InlineNode <font>
frag 0 from TextNode start: 0, length: 4, rect: [8,11 24.109375x13] baseline: 10.09375
"text"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]

View File

@ -1,30 +1,30 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x216 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x200 children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,8 79.296875x200] baseline: 159.96875
"1"
frag 1 from TextNode start: 0, length: 1, rect: [87,154 8x17] baseline: 13.296875
frag 0 from TextNode start: 0, length: 1, rect: [87,154 8x17] baseline: 13.296875
" "
frag 2 from TextNode start: 0, length: 1, rect: [95,8 110.15625x200] baseline: 159.96875
"2"
frag 3 from TextNode start: 0, length: 1, rect: [205,154 8x17] baseline: 13.296875
frag 1 from TextNode start: 0, length: 1, rect: [205,154 8x17] baseline: 13.296875
" "
frag 4 from TextNode start: 0, length: 1, rect: [213,8 113.671875x200] baseline: 159.96875
"3"
frag 5 from TextNode start: 0, length: 1, rect: [327,154 8x17] baseline: 13.296875
frag 2 from TextNode start: 0, length: 1, rect: [327,154 8x17] baseline: 13.296875
" "
frag 6 from TextNode start: 0, length: 1, rect: [335,8 96.875x200] baseline: 159.96875
"4"
InlineNode <span.one>
frag 0 from TextNode start: 0, length: 1, rect: [8,8 79.296875x200] baseline: 159.96875
"1"
TextNode <#text>
TextNode <#text>
InlineNode <span.two>
frag 0 from TextNode start: 0, length: 1, rect: [95,8 110.15625x200] baseline: 159.96875
"2"
TextNode <#text>
TextNode <#text>
InlineNode <span.three>
frag 0 from TextNode start: 0, length: 1, rect: [213,8 113.671875x200] baseline: 159.96875
"3"
TextNode <#text>
TextNode <#text>
InlineNode <span.four>
frag 0 from TextNode start: 0, length: 1, rect: [335,8 96.875x200] baseline: 159.96875
"4"
TextNode <#text>
TextNode <#text>

View File

@ -2,18 +2,18 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x19 children: not-inline
BlockContainer <div.fixed_width> at (9,9) content-size 50x17 children: inline
frag 0 from TextNode start: 0, length: 3, rect: [9,9 33.921875x17] baseline: 13.296875
"ABC"
frag 1 from TextNode start: 0, length: 1, rect: [43,9 11.5625x17] baseline: 13.296875
"X"
frag 2 from TextNode start: 0, length: 3, rect: [54,9 33.921875x17] baseline: 13.296875
"ABC"
TextNode <#text>
InlineNode <span.nowrap>
frag 0 from TextNode start: 0, length: 3, rect: [9,9 33.921875x17] baseline: 13.296875
"ABC"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [43,9 11.5625x17] baseline: 13.296875
"X"
TextNode <#text>
InlineNode <span.nowrap>
frag 0 from TextNode start: 0, length: 3, rect: [54,9 33.921875x17] baseline: 13.296875
"ABC"
TextNode <#text>
TextNode <#text>

View File

@ -9,9 +9,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <(anonymous)> at (10,31) content-size 780x0 children: inline
TextNode <#text>
BlockContainer <div.inline.formatting-context> at (11,32) content-size 778x17 [BFC] children: inline
frag 0 from TextNode start: 0, length: 6, rect: [12,32 41.296875x17] baseline: 13.296875
"inline"
InlineNode <div>
frag 0 from TextNode start: 0, length: 6, rect: [12,32 41.296875x17] baseline: 13.296875
"inline"
TextNode <#text>
BlockContainer <(anonymous)> at (10,50) content-size 780x0 children: inline
TextNode <#text>

View File

@ -1,9 +1,9 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x416 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x400 children: inline
frag 0 from ImageBox start: 0, length: 0, rect: [8,8 400x400] baseline: 400
TextNode <#text>
InlineNode <picture>
frag 0 from ImageBox start: 0, length: 0, rect: [8,8 400x400] baseline: 400
TextNode <#text>
InlineNode <source>
TextNode <#text>

View File

@ -1,9 +1,9 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 3, rect: [9,8 19.875x17] baseline: 13.296875
" | "
InlineNode <pre>
frag 0 from TextNode start: 0, length: 3, rect: [9,8 19.875x17] baseline: 13.296875
" | "
TextNode <#text>
TextNode <#text>

View File

@ -2,9 +2,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17 children: not-inline
BlockContainer <div#container> at (8,8) content-size 784x17 children: inline
frag 0 from TextNode start: 0, length: 5, rect: [8,8 43.421875x17] baseline: 13.296875
"Pass!"
InlineNode <span>
frag 0 from TextNode start: 0, length: 5, rect: [8,8 43.421875x17] baseline: 13.296875
"Pass!"
TextNode <#text>
BlockContainer <(anonymous)> at (8,25) content-size 784x0 children: inline
TextNode <#text>

View File

@ -2,16 +2,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x36 children: not-inline
BlockContainer <div.fixed_width> at (9,9) content-size 50x34 children: inline
frag 0 from TextNode start: 0, length: 3, rect: [9,9 33.921875x17] baseline: 13.296875
"ABC"
frag 1 from TextNode start: 0, length: 3, rect: [9,26 33.921875x17] baseline: 13.296875
"ABC"
TextNode <#text>
InlineNode <span.nowrap>
frag 0 from TextNode start: 0, length: 3, rect: [9,9 33.921875x17] baseline: 13.296875
"ABC"
TextNode <#text>
InlineNode <span>
TextNode <#text>
InlineNode <span.nowrap>
frag 0 from TextNode start: 0, length: 3, rect: [9,26 33.921875x17] baseline: 13.296875
"ABC"
TextNode <#text>
TextNode <#text>

View File

@ -13,10 +13,10 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <td> at (16,12) content-size 37.21875x17 table-cell [BFC] children: inline
frag 0 from TextNode start: 0, length: 4, rect: [16,12 37.21875x17] baseline: 13.296875
"Test"
TextNode <#text>
InlineNode <a>
frag 0 from TextNode start: 0, length: 4, rect: [16,12 37.21875x17] baseline: 13.296875
"Test"
TextNode <#text>
TextNode <#text>
BlockContainer <(anonymous)> (not painted) children: inline

View File

@ -31,10 +31,12 @@
#include <LibWeb/Layout/BlockContainer.h>
#include <LibWeb/Layout/FormattingContext.h>
#include <LibWeb/Layout/FrameBox.h>
#include <LibWeb/Layout/InlineNode.h>
#include <LibWeb/Layout/Node.h>
#include <LibWeb/Layout/SVGBox.h>
#include <LibWeb/Layout/TextNode.h>
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Painting/InlinePaintable.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/TextPaintable.h>
#include <LibWeb/SVG/SVGDecodedImageData.h>
@ -340,29 +342,43 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho
}
}
auto dump_fragment = [&](auto& fragment, size_t fragment_index) {
for (size_t i = 0; i < indent; ++i)
builder.append(" "sv);
builder.appendff(" {}frag {}{} from {} ",
fragment_color_on,
fragment_index,
color_off,
fragment.layout_node().class_name());
builder.appendff("start: {}, length: {}, rect: {} baseline: {}\n",
fragment.start(),
fragment.length(),
fragment.absolute_rect(),
fragment.baseline());
if (is<Layout::TextNode>(fragment.layout_node())) {
for (size_t i = 0; i < indent; ++i)
builder.append(" "sv);
auto const& layout_text = static_cast<Layout::TextNode const&>(fragment.layout_node());
auto fragment_text = MUST(layout_text.text_for_rendering().substring_from_byte_offset(fragment.start(), fragment.length()));
builder.appendff(" \"{}\"\n", fragment_text);
}
};
if (is<Layout::BlockContainer>(layout_node) && static_cast<Layout::BlockContainer const&>(layout_node).children_are_inline()) {
auto& block = static_cast<Layout::BlockContainer const&>(layout_node);
for (size_t fragment_index = 0; block.paintable_with_lines() && fragment_index < block.paintable_with_lines()->fragments().size(); ++fragment_index) {
auto const& fragment = block.paintable_with_lines()->fragments()[fragment_index];
for (size_t i = 0; i < indent; ++i)
builder.append(" "sv);
builder.appendff(" {}frag {}{} from {} ",
fragment_color_on,
fragment_index,
color_off,
fragment.layout_node().class_name());
builder.appendff("start: {}, length: {}, rect: {} baseline: {}\n",
fragment.start(),
fragment.length(),
fragment.absolute_rect(),
fragment.baseline());
if (is<Layout::TextNode>(fragment.layout_node())) {
for (size_t i = 0; i < indent; ++i)
builder.append(" "sv);
auto const& layout_text = static_cast<Layout::TextNode const&>(fragment.layout_node());
auto fragment_text = MUST(layout_text.text_for_rendering().substring_from_byte_offset(fragment.start(), fragment.length()));
builder.appendff(" \"{}\"\n", fragment_text);
}
dump_fragment(fragment, fragment_index);
}
}
if (is<Layout::InlineNode>(layout_node) && layout_node.paintable()) {
auto const& inline_node = static_cast<Layout::InlineNode const&>(layout_node);
auto const& inline_paintable = static_cast<Painting::InlinePaintable const&>(*inline_node.paintable());
auto const& fragments = inline_paintable.fragments();
for (size_t fragment_index = 0; fragment_index < fragments.size(); ++fragment_index) {
auto const& fragment = fragments[fragment_index];
dump_fragment(fragment, fragment_index);
}
}

View File

@ -7,6 +7,7 @@
#include <AK/Debug.h>
#include <LibWeb/Layout/AvailableSpace.h>
#include <LibWeb/Layout/BlockContainer.h>
#include <LibWeb/Layout/InlineNode.h>
#include <LibWeb/Layout/LayoutState.h>
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Painting/InlinePaintable.h>
@ -116,6 +117,13 @@ static CSSPixelRect measure_scrollable_overflow(Box const& box)
return IterationDecision::Continue;
});
} else {
box.for_each_child([&scrollable_overflow_rect](Node const& child) {
if (child.paintable() && child.paintable()->is_inline_paintable()) {
for (auto const& fragment : static_cast<Painting::InlinePaintable const&>(*child.paintable()).fragments())
scrollable_overflow_rect = scrollable_overflow_rect.united(fragment.absolute_rect());
}
});
}
// FIXME: - The margin areas of grid item and flex item boxes for which the box establishes a containing block.
@ -293,12 +301,7 @@ void LayoutState::resolve_border_radii()
}
for (auto& inline_paintable : inline_paintables) {
Vector<Painting::PaintableFragment&> fragments;
verify_cast<Painting::PaintableWithLines>(*inline_paintable.containing_block()->paintable_box()).for_each_fragment([&](auto& fragment) {
if (inline_paintable.layout_node().is_inclusive_ancestor_of(fragment.layout_node()))
fragments.append(const_cast<Painting::PaintableFragment&>(fragment));
return IterationDecision::Continue;
});
auto& fragments = inline_paintable.fragments();
auto const& top_left_border_radius = inline_paintable.computed_values().border_top_left_radius();
auto const& top_right_border_radius = inline_paintable.computed_values().border_top_right_radius();
@ -457,13 +460,29 @@ void LayoutState::commit(Box& root)
resolve_relative_positions(paintables_with_lines);
// Make a pass over all the line boxes to:
// - Measure absolute rect of each line box.
// - Collect all text nodes, so we can create paintables for them later.
// - Relocate fragments into matching inline paintables
for (auto& paintable_with_lines : paintables_with_lines) {
Vector<Painting::PaintableFragment> fragments_with_inline_paintables_removed;
for (auto& fragment : paintable_with_lines.fragments()) {
if (fragment.layout_node().is_text_node())
text_nodes.set(static_cast<Layout::TextNode*>(const_cast<Layout::Node*>(&fragment.layout_node())));
auto find_closest_inline_paintable = [&](auto& fragment) -> Painting::InlinePaintable const* {
for (auto const* parent = fragment.layout_node().parent(); parent; parent = parent->parent()) {
if (is<InlineNode>(*parent))
return static_cast<Painting::InlinePaintable const*>(parent->paintable());
}
return nullptr;
};
if (auto const* inline_paintable = find_closest_inline_paintable(fragment)) {
const_cast<Painting::InlinePaintable*>(inline_paintable)->fragments().append(fragment);
} else {
fragments_with_inline_paintables_removed.append(fragment);
}
}
paintable_with_lines.set_fragments(move(fragments_with_inline_paintables_removed));
}
for (auto* text_node : text_nodes)
@ -483,18 +502,6 @@ void LayoutState::commit(Box& root)
resolve_border_radii();
resolve_box_shadow_data();
resolve_text_shadows(paintables_with_lines);
for (auto& it : used_values_per_layout_node) {
auto& used_values = *it.value;
auto& node = const_cast<NodeWithStyle&>(used_values.node());
auto* paintable = node.paintable();
if (paintable && is<Painting::InlinePaintable>(*paintable)) {
auto& inline_paintable = static_cast<Painting::InlinePaintable&>(*paintable);
// FIXME: Marking fragments contained by inline node is a hack required to skip them while painting
// PaintableWithLines content.
inline_paintable.mark_contained_fragments();
}
}
}
void LayoutState::UsedValues::set_node(NodeWithStyle& node, UsedValues const* containing_block_used_values)

View File

@ -32,6 +32,7 @@
#include <LibWeb/Layout/TextNode.h>
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Page/Page.h>
#include <LibWeb/Painting/InlinePaintable.h>
#include <LibWeb/Platform/FontPlugin.h>
namespace Web::Layout {
@ -232,13 +233,20 @@ void Node::set_needs_display()
return;
if (!containing_block->paintable_box())
return;
auto navigable = this->navigable();
if (!navigable)
return;
if (this->paintable() && is<Painting::InlinePaintable>(this->paintable())) {
auto const& fragments = static_cast<Painting::InlinePaintable*>(this->paintable())->fragments();
for (auto const& fragment : fragments)
navigable->set_needs_display(fragment.absolute_rect());
}
if (!is<Painting::PaintableWithLines>(*containing_block->paintable_box()))
return;
static_cast<Painting::PaintableWithLines const&>(*containing_block->paintable_box()).for_each_fragment([&](auto& fragment) {
if (&fragment.layout_node() == this || is_ancestor_of(fragment.layout_node())) {
if (navigable())
navigable()->set_needs_display(fragment.absolute_rect());
}
navigable->set_needs_display(fragment.absolute_rect());
return IterationDecision::Continue;
});
}
@ -248,14 +256,19 @@ CSSPixelPoint Node::box_type_agnostic_position() const
if (is<Box>(*this))
return verify_cast<Box>(*this).paintable_box()->absolute_position();
VERIFY(is_inline());
if (paintable() && paintable()->is_inline_paintable()) {
auto const& inline_paintable = static_cast<Painting::InlinePaintable const&>(*paintable());
if (!inline_paintable.fragments().is_empty())
return inline_paintable.fragments().first().absolute_rect().location();
VERIFY_NOT_REACHED();
}
CSSPixelPoint position;
if (auto* block = containing_block(); block && block->paintable() && is<Painting::PaintableWithLines>(*block->paintable())) {
if (auto const* block = containing_block(); block && block->paintable() && is<Painting::PaintableWithLines>(*block->paintable())) {
static_cast<Painting::PaintableWithLines const&>(*block->paintable_box()).for_each_fragment([&](auto& fragment) {
if (&fragment.layout_node() == this || is_ancestor_of(fragment.layout_node())) {
position = fragment.absolute_rect().location();
return IterationDecision::Break;
}
return IterationDecision::Continue;
position = fragment.absolute_rect().location();
return IterationDecision::Break;
});
}
return position;

View File

@ -154,26 +154,26 @@ void InlinePaintable::paint(PaintContext& context, PaintPhase phase) const
template<typename Callback>
void InlinePaintable::for_each_fragment(Callback callback) const
{
// FIXME: This will be slow if the containing block has a lot of fragments!
Vector<PaintableFragment const&> fragments;
verify_cast<PaintableWithLines>(*containing_block()->paintable_box()).for_each_fragment([&](auto& fragment) {
if (layout_node().is_inclusive_ancestor_of(fragment.layout_node()))
fragments.append(fragment);
return IterationDecision::Continue;
});
for (size_t i = 0; i < fragments.size(); ++i) {
auto const& fragment = fragments[i];
callback(fragment, i == 0, i == fragments.size() - 1);
for (size_t i = 0; i < m_fragments.size(); ++i) {
auto const& fragment = m_fragments[i];
callback(fragment, i == 0, i == m_fragments.size() - 1);
}
}
void InlinePaintable::mark_contained_fragments()
Optional<HitTestResult> InlinePaintable::hit_test(CSSPixelPoint position, HitTestType type) const
{
verify_cast<PaintableWithLines>(*containing_block()->paintable_box()).for_each_fragment([&](auto& fragment) {
if (layout_node().is_inclusive_ancestor_of(fragment.layout_node()))
const_cast<PaintableFragment&>(fragment).set_contained_by_inline_node();
return IterationDecision::Continue;
});
for (auto& fragment : m_fragments) {
if (is<Layout::Box>(fragment.layout_node()) && static_cast<Layout::Box const&>(fragment.layout_node()).paintable_box()->stacking_context())
continue;
auto fragment_absolute_rect = fragment.absolute_rect();
if (fragment_absolute_rect.contains(position)) {
if (is<Layout::BlockContainer>(fragment.layout_node()) && fragment.layout_node().paintable())
return fragment.layout_node().paintable()->hit_test(position, type);
return HitTestResult { const_cast<Paintable&>(const_cast<Paintable&>(*fragment.layout_node().paintable())),
fragment.text_index_at(position.x()) };
}
}
return {};
}
CSSPixelRect InlinePaintable::bounding_rect() const

View File

@ -8,6 +8,7 @@
#include <LibWeb/Layout/InlineNode.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/PaintableFragment.h>
namespace Web::Painting {
@ -23,10 +24,12 @@ public:
auto const& box_model() const { return layout_node().box_model(); }
CSSPixelRect bounding_rect() const;
Vector<PaintableFragment> const& fragments() const { return m_fragments; }
Vector<PaintableFragment>& fragments() { return m_fragments; }
virtual bool is_inline_paintable() const override { return true; }
void mark_contained_fragments();
virtual Optional<HitTestResult> hit_test(CSSPixelPoint, HitTestType) const override;
void set_box_shadow_data(Vector<ShadowData>&& box_shadow_data) { m_box_shadow_data = move(box_shadow_data); }
Vector<ShadowData> const& box_shadow_data() const { return m_box_shadow_data; }
@ -38,6 +41,7 @@ private:
void for_each_fragment(Callback) const;
Vector<ShadowData> m_box_shadow_data;
Vector<PaintableFragment> m_fragments;
};
}

View File

@ -741,6 +741,15 @@ Optional<HitTestResult> PaintableWithLines::hit_test(CSSPixelPoint position, Hit
if (!layout_box().children_are_inline() || m_fragments.is_empty())
return PaintableBox::hit_test(position, type);
for (auto* child = first_child(); child; child = child->next_sibling()) {
auto result = child->hit_test(position, type);
if (!result.has_value())
continue;
if (!result->paintable->visible_for_hit_testing())
continue;
return result;
}
Optional<HitTestResult> last_good_candidate;
for (auto const& fragment : fragments()) {
if (is<Layout::Box>(fragment.layout_node()) && static_cast<Layout::Box const&>(fragment.layout_node()).paintable_box()->stacking_context())

View File

@ -230,12 +230,15 @@ public:
Layout::BlockContainer& layout_box();
Vector<PaintableFragment> const& fragments() const { return m_fragments; }
Vector<PaintableFragment>& fragments() { return m_fragments; }
void add_fragment(Layout::LineBoxFragment const& fragment)
{
m_fragments.append(PaintableFragment { fragment });
}
void set_fragments(Vector<PaintableFragment>&& fragments) { m_fragments = move(fragments); }
template<typename Callback>
void for_each_fragment(Callback callback) const
{