Commit 498ff64d authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Stop removing trailing spaces in CollectInlines

This patch stops removing trailing collapsible spaces at the
end of inline formatting contexts.

CSS defines to remove trailing collapsible spaces for each line.
Before this patch, CollectInlines() removes them before line
break as an micro-optimization because the end of an inline
formatting context is also the end of lines.

It turned out that this may prevent the re-use of NGInlineItem
(CL:986982) in some common cases, and since the re-use is a
great performance win, this micro-optimization turned out to
harmful.

Note, there are 19 tests that have 1px differences, probably
because we don't reshape when removing trailing spaces. Since
we already do this in HandleTrailingSpaces, rebaseline in this
patch but I'll work in following patches.

Bug: 636993
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: Iff30d0cb05b4b80950c0d6da10ce8f6eff23a61a
Reviewed-on: https://chromium-review.googlesource.com/1022191
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarXiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555320}
parent 70b332a1
......@@ -138,6 +138,7 @@ crbug.com/591099 css3/filters/effect-brightness-clamping.html [ Failure ]
crbug.com/591099 css3/filters/effect-brightness.html [ Failure ]
crbug.com/714962 css3/filters/effect-reference-zoom-hw.html [ Failure ]
crbug.com/591099 css3/filters/multiple-references-id-mutate-crash-2.html [ Crash ]
crbug.com/591099 css3/flexbox/bug669714.html [ Failure ]
crbug.com/591099 css3/flexbox/flex-flow-border.html [ Failure ]
crbug.com/591099 css3/flexbox/flex-flow-margins-auto-size.html [ Failure ]
crbug.com/591099 css3/flexbox/flex-flow-padding.html [ Failure ]
......@@ -1148,6 +1149,7 @@ crbug.com/824918 fast/multicol/hit-test-above-or-below.html [ Failure ]
crbug.com/824918 fast/multicol/inline-block-baseline.html [ Failure ]
crbug.com/824918 fast/multicol/nested-one-line-in-inner.html [ Failure ]
crbug.com/824918 fast/multicol/newmulticol/list-item.html [ Failure ]
crbug.com/591099 fast/multicol/out-of-flow/abspos-auto-position-on-line-rtl.html [ Failure ]
crbug.com/824918 fast/multicol/span/overflow-on-multicol.html [ Failure ]
crbug.com/824918 fast/multicol/span/summary-split.html [ Failure ]
crbug.com/824918 fast/multicol/span/vertical-rl.html [ Failure ]
......@@ -1884,6 +1886,7 @@ crbug.com/591099 svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html [ Fai
crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml [ Failure ]
crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ Failure ]
crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-percentage-size.xhtml [ Failure ]
crbug.com/591099 svg/zoom/text/zoom-hixie-mixed-008.xml [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug101674.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug110566.html [ Failure ]
crbug.com/591099 tables/mozilla/bugs/bug12008.html [ Failure ]
......@@ -1966,6 +1969,7 @@ crbug.com/714962 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll
crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ]
crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-event-buttons-attribute.html [ Timeout ]
crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-relative-position.html [ Failure ]
crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseclick-target-and-positioning.html [ Failure ]
crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseevent-getModifierState.html [ Timeout ]
crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ]
crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-capture-transition-events.html [ Timeout ]
......
......@@ -873,6 +873,7 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/positioned-with-co
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/positive-leading.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/pushed-line-affected-by-float.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/relayout-and-push-float.html [ Failure ]
crbug.com/591099 [ Mac ] virtual/layout_ng_experimental/fast/multicol/relpos-inside-inline-block.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/renderer-positioned-assert-crash.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/rule-in-nested-with-too-tall-line.html [ Failure ]
crbug.com/714962 virtual/layout_ng_experimental/fast/multicol/scale-transform-text.html [ Failure ]
......
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x178
LayoutNGBlockFlow {HTML} at (0,0) size 800x178
LayoutNGBlockFlow {BODY} at (8,16) size 784x146
LayoutNGBlockFlow {P} at (0,0) size 784x20
LayoutText {#text} at (0,0) size 448x19
text run at (0,0) width 448: "The three boxes below should have progressively thinner right borders."
LayoutNGBlockFlow {P} at (0,36) size 784x26 [border: (3px solid #000000) (5px solid #000000) (3px solid #000000)]
LayoutText {#text} at (3,3) size 11x19
text run at (3,3) width 11: "A"
LayoutNGBlockFlow {P} at (0,78) size 784x26 [border: (3px solid #000000)]
LayoutText {#text} at (3,3) size 11x19
text run at (3,3) width 11: "B"
LayoutNGBlockFlow {P} at (0,120) size 784x26 [border: (3px solid #000000) (1px solid #000000) (3px solid #000000)]
LayoutText {#text} at (3,3) size 11x19
text run at (3,3) width 11: "C"
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x178
LayoutNGBlockFlow {HTML} at (0,0) size 800x178
LayoutNGBlockFlow {BODY} at (8,16) size 784x146
LayoutNGBlockFlow {P} at (0,0) size 784x20
LayoutText {#text} at (0,0) size 439x19
text run at (0,0) width 439: "The three boxes below should have progressively thinner left borders."
LayoutNGBlockFlow {P} at (0,36) size 784x26 [border: (3px solid #000000) (5px solid #000000)]
LayoutText {#text} at (5,3) size 11x19
text run at (5,3) width 11: "A"
LayoutNGBlockFlow {P} at (0,78) size 784x26 [border: (3px solid #000000)]
LayoutText {#text} at (3,3) size 11x19
text run at (3,3) width 11: "B"
LayoutNGBlockFlow {P} at (0,120) size 784x26 [border: (3px solid #000000) (1px solid #000000)]
LayoutText {#text} at (1,3) size 11x19
text run at (1,3) width 11: "C"
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x178
LayoutNGBlockFlow {HTML} at (0,0) size 800x178
LayoutNGBlockFlow {BODY} at (8,16) size 784x146
LayoutNGBlockFlow {P} at (0,0) size 784x20
LayoutText {#text} at (0,0) size 415x19
text run at (0,0) width 415: "The three boxes below should have progressively thinner borders."
LayoutNGBlockFlow {P} at (0,36) size 784x30 [border: (5px solid #000000)]
LayoutText {#text} at (5,5) size 11x19
text run at (5,5) width 11: "A"
LayoutNGBlockFlow {P} at (0,82) size 784x26 [border: (3px solid #000000)]
LayoutText {#text} at (3,3) size 11x19
text run at (3,3) width 11: "B"
LayoutNGBlockFlow {P} at (0,124) size 784x22 [border: (1px solid #000000)]
LayoutText {#text} at (1,1) size 11x19
text run at (1,1) width 11: "C"
......@@ -29,5 +29,5 @@ layer at (0,0) size 800x288
text run at (0,200) width 588: "FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL"
text run at (0,220) width 588: "FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL"
text run at (0,240) width 588: "FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL"
text run at (0,260) width 149: "FAIL FAIL FAIL FAIL"
text run at (0,260) width 148: "FAIL FAIL FAIL FAIL"
LayoutText {#text} at (0,0) size 0x0
......@@ -73,11 +73,11 @@ layer at (0,0) size 800x100
text run at (139,0) width 12: "K"
LayoutText {#text} at (151,0) size 4x19
text run at (151,0) width 4: " "
LayoutInline {SPAN} at (0,0) size 10x19
LayoutInline {<pseudo:before>} at (0,0) size 10x19
LayoutCounter (anonymous) at (155,0) size 10x19
text run at (155,0) width 10: "L"
LayoutInline {SPAN} at (0,0) size 9x19
LayoutInline {<pseudo:before>} at (0,0) size 9x19
LayoutCounter (anonymous) at (155,0) size 9x19
text run at (155,0) width 9: "L"
LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 165x19
text run at (0,0) width 165: "A B C D E F G H I J K L"
LayoutText {#text} at (0,0) size 164x19
text run at (0,0) width 164: "A B C D E F G H I J K L"
......@@ -73,11 +73,11 @@ layer at (0,0) size 800x100
text run at (139,0) width 12: "K"
LayoutText {#text} at (151,0) size 4x19
text run at (151,0) width 4: " "
LayoutInline {SPAN} at (0,0) size 10x19
LayoutInline {<pseudo:before>} at (0,0) size 10x19
LayoutCounter (anonymous) at (155,0) size 10x19
text run at (155,0) width 10: "L"
LayoutInline {SPAN} at (0,0) size 9x19
LayoutInline {<pseudo:before>} at (0,0) size 9x19
LayoutCounter (anonymous) at (155,0) size 9x19
text run at (155,0) width 9: "L"
LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 165x19
text run at (0,0) width 165: "A B C D E F G H I J K L"
LayoutText {#text} at (0,0) size 164x19
text run at (0,0) width 164: "A B C D E F G H I J K L"
......@@ -73,11 +73,11 @@ layer at (0,0) size 800x100
text run at (289,0) width 28: "A.K"
LayoutText {#text} at (317,0) size 3x19
text run at (317,0) width 3: " "
LayoutInline {SPAN} at (0,0) size 26x19
LayoutInline {<pseudo:before>} at (0,0) size 26x19
LayoutCounter (anonymous) at (320,0) size 26x19
text run at (320,0) width 26: "A.L"
LayoutInline {SPAN} at (0,0) size 25x19
LayoutInline {<pseudo:before>} at (0,0) size 25x19
LayoutCounter (anonymous) at (320,0) size 25x19
text run at (320,0) width 25: "A.L"
LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 346x19
text run at (0,0) width 346: "A.A A.B A.C A.D A.E A.F A.G A.H A.I A.J A.K A.L"
LayoutText {#text} at (0,0) size 345x19
text run at (0,0) width 345: "A.A A.B A.C A.D A.E A.F A.G A.H A.I A.J A.K A.L"
......@@ -73,11 +73,11 @@ layer at (0,0) size 800x100
text run at (289,0) width 28: "A.K"
LayoutText {#text} at (317,0) size 3x19
text run at (317,0) width 3: " "
LayoutInline {SPAN} at (0,0) size 26x19
LayoutInline {<pseudo:before>} at (0,0) size 26x19
LayoutCounter (anonymous) at (320,0) size 26x19
text run at (320,0) width 26: "A.L"
LayoutInline {SPAN} at (0,0) size 25x19
LayoutInline {<pseudo:before>} at (0,0) size 25x19
LayoutCounter (anonymous) at (320,0) size 25x19
text run at (320,0) width 25: "A.L"
LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 346x19
text run at (0,0) width 346: "A.A A.B A.C A.D A.E A.F A.G A.H A.I A.J A.K A.L"
LayoutText {#text} at (0,0) size 345x19
text run at (0,0) width 345: "A.A A.B A.C A.D A.E A.F A.G A.H A.I A.J A.K A.L"
......@@ -4,8 +4,8 @@ layer at (0,0) size 800x600
LayoutNGBlockFlow {HTML} at (0,0) size 800x600
LayoutNGBlockFlow {BODY} at (8,8) size 784x568
LayoutNGBlockFlow {H1} at (0,0) size 784x57
LayoutText {#text} at (0,1) size 773x55
text run at (0,1) width 773: "Inheritance bug for floated first-letter"
LayoutText {#text} at (0,1) size 772x55
text run at (0,1) width 772: "Inheritance bug for floated first-letter"
LayoutNGBlockFlow {P} at (0,89.16) size 784x172 [bgcolor=#EEEEEE] [border: (1px solid #000000)]
LayoutInline {<pseudo:first-letter>} at (0,0) size 54x86 [color=#008000] [border: (1px dashed #008000)]
LayoutTextFragment (anonymous) at (2,2) size 52x84
......
......@@ -18,14 +18,14 @@ layer at (0,0) size 800x600
LayoutText {#text} at (0,0) size 29x19
text run at (0,0) width 29: "DIV"
LayoutNGBlockFlow {P} at (11,46) size 747x20
LayoutText {#text} at (0,0) size 9x19
text run at (0,0) width 9: "P"
LayoutText {#text} at (0,0) size 8x19
text run at (0,0) width 8: "P"
LayoutNGBlockFlow {DIV} at (6,66) size 752x20 [color=#FF0000] [bgcolor=#9999FF]
LayoutText {#text} at (0,0) size 131x19
text run at (0,0) width 131: "DIV red text blue bg"
LayoutNGBlockFlow {P} at (11,86) size 747x20
LayoutText {#text} at (0,0) size 9x19
text run at (0,0) width 9: "P"
LayoutText {#text} at (0,0) size 8x19
text run at (0,0) width 8: "P"
LayoutNGBlockFlow {DIV} at (6,106) size 752x20
LayoutText {#text} at (0,0) size 29x19
text run at (0,0) width 29: "DIV"
......@@ -36,14 +36,14 @@ layer at (0,0) size 800x600
LayoutText {#text} at (0,0) size 29x19
text run at (0,0) width 29: "DIV"
LayoutNGBlockFlow {P} at (11,166) size 747x20
LayoutText {#text} at (0,0) size 9x19
text run at (0,0) width 9: "P"
LayoutText {#text} at (0,0) size 8x19
text run at (0,0) width 8: "P"
LayoutNGBlockFlow {DIV} at (6,186) size 752x20 [color=#FF0000]
LayoutText {#text} at (0,0) size 80x19
text run at (0,0) width 80: "DIV red text"
LayoutNGBlockFlow {P} at (11,206) size 747x20
LayoutText {#text} at (0,0) size 9x19
text run at (0,0) width 9: "P"
LayoutText {#text} at (0,0) size 8x19
text run at (0,0) width 8: "P"
LayoutNGBlockFlow {DIV} at (10,314) size 764x252 [border: (1px solid #000000)]
LayoutText {#text} at (6,6) size 261x19
text run at (6,6) width 261: "child 0: PASS: found color rgb(255, 0, 0)"
......
......@@ -7,5 +7,5 @@ layer at (0,0) size 800x600
LayoutImage {IMG} at (0,0) size 300x300
LayoutText {#text} at (300,285) size 4x19
text run at (300,285) width 4: " "
LayoutText {#text} at (304,285) size 443x19
text run at (304,285) width 443: "The element at position (100, 100) should be the body. Result: BODY"
LayoutText {#text} at (304,285) size 442x19
text run at (304,285) width 442: "The element at position (100, 100) should be the body. Result: BODY"
This page tests whether a click event propagates with the correct target and positioning. See rdar://problem/4477126.
click inside the red box:[]
......@@ -7,8 +7,8 @@ layer at (0,0) size 1600x356
LayoutText {#text} at (0,0) size 58x36
text run at (0,0) width 58: "LTR"
LayoutNGBlockFlow (anonymous) at (0,81) size 1568x37
LayoutText {#text} at (0,0) size 59x36
text run at (0,0) width 59: "RTL"
LayoutText {#text} at (0,0) size 58x36
text run at (0,0) width 58: "RTL"
LayoutNGBlockFlow (anonymous) at (0,162) size 1568x37
LayoutText {#text} at (0,0) size 367x36
text run at (0,0) width 367: "LTR (text-overflow:ellipses)"
......
......@@ -7,8 +7,8 @@ layer at (0,0) size 1600x356
LayoutText {#text} at (0,0) size 58x36
text run at (0,0) width 58: "LTR"
LayoutNGBlockFlow (anonymous) at (0,81) size 1568x37
LayoutText {#text} at (0,0) size 59x36
text run at (0,0) width 59: "RTL"
LayoutText {#text} at (0,0) size 58x36
text run at (0,0) width 58: "RTL"
LayoutNGBlockFlow (anonymous) at (0,162) size 1568x37
LayoutText {#text} at (0,0) size 367x36
text run at (0,0) width 367: "LTR (text-overflow:ellipses)"
......
......@@ -7,8 +7,8 @@ layer at (0,0) size 800x184
LayoutText {#text} at (0,0) size 30x19
text run at (0,0) width 30: "LTR"
LayoutNGBlockFlow (anonymous) at (0,42) size 784x20
LayoutText {#text} at (0,0) size 30x19
text run at (0,0) width 30: "RTL"
LayoutText {#text} at (0,0) size 29x19
text run at (0,0) width 29: "RTL"
LayoutNGBlockFlow (anonymous) at (0,84) size 784x20
LayoutText {#text} at (0,0) size 183x19
text run at (0,0) width 183: "LTR (text-overflow:ellipses):"
......
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x465
LayoutNGBlockFlow {html} at (0,0) size 800x465
LayoutNGBlockFlow {body} at (8,16) size 784x441
LayoutNGBlockFlow {p} at (0,0) size 784x20 [color=#000080]
LayoutText {#text} at (0,0) size 405x19
text run at (0,0) width 405: "There should be a blue circle with the word \"TEST\" in it below."
LayoutNGBlockFlow (anonymous) at (0,36) size 784x405
LayoutSVGRoot {svg} at (0,0) size 400x400
LayoutSVGRect {rect} at (0,0) size 400x400 [fill={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=0.00] [width=400.00] [height=400.00]
LayoutSVGEllipse {circle} at (0,0) size 400x400 [fill={[type=SOLID] [color=#000080]}] [cx=200.00] [cy=200.00] [r=200.00]
LayoutSVGForeignObject {foreignObject} at (0,175) size 400x50 [color=#FFFFFF]
LayoutNGBlockFlow {div} at (0,0) size 400x59
LayoutText {#text} at (140,1) size 120x57
text run at (140,1) width 120: "TEST"
LayoutText {#text} at (0,0) size 0x0
layer at (8,227) size 400x50 scrollHeight 59
LayoutSVGForeignObject {foreignObject} at (0,175) size 400x50 [color=#FFFFFF]
LayoutNGBlockFlow {div} at (0,0) size 400x59
LayoutText {#text} at (140,1) size 120x57
text run at (140,1) width 120: "TEST"
layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 668
LayoutView at (0,0) size 800x600
layer at (0,0) size 785x668 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
LayoutNGBlockFlow {html} at (0,0) size 785x667.58
LayoutNGBlockFlow {body} at (11.52,23.03) size 761.97x633.03
LayoutNGBlockFlow {p} at (0,0) size 761.97x27 [color=#000080]
LayoutText {#text} at (0,0) size 594x26
text run at (0,0) width 594: "There should be a blue circle with the word \"TEST\" in it below."
LayoutNGBlockFlow (anonymous) at (0,50.03) size 761.97x583
LayoutSVGRoot {svg} at (0,0) size 576x576
LayoutSVGRect {rect} at (0,0) size 400x400 [fill={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=0.00] [width=400.00] [height=400.00]
LayoutSVGEllipse {circle} at (0,0) size 400x400 [fill={[type=SOLID] [color=#000080]}] [cx=200.00] [cy=200.00] [r=200.00]
LayoutSVGForeignObject {foreignObject} at (0,175) size 400x50 [color=#FFFFFF]
LayoutNGBlockFlow {div} at (0,0) size 400x59
LayoutText {#text} at (140,1) size 120x57
text run at (140,1) width 120: "TEST"
LayoutText {#text} at (0,0) size 0x0
layer at (12,248) size 400x50 backgroundClip at (12,325) size 576x72 clip at (0,0) size 0x0 scrollHeight 59
LayoutSVGForeignObject {foreignObject} at (0,175) size 400x50 [color=#FFFFFF]
LayoutNGBlockFlow {div} at (0,0) size 400x59
LayoutText {#text} at (140,1) size 120x57
text run at (140,1) width 120: "TEST"
......@@ -20,11 +20,29 @@ NGInlineItemsBuilderTemplate<
template <typename OffsetMappingBuilder>
String NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ToString() {
// Segment Break Transformation Rules[1] defines to keep trailing new lines,
// but it will be removed in Phase II[2]. We prefer not to add trailing new
// lines and collapsible spaces in Phase I.
// Segment Break Transformation Rules[1] defines to keep trailing new lines in
// Phase I, but to remove after line break, in Phase II[2]. Although the spec
// defines so, trailing collapsible spaces at the end of an inline formatting
// context will be removed in Phase II and that removing here makes no
// differences.
//
// However, doing so reduces the opportunities to re-use NGInlineItem a lot in
// appending scenario, which is quite common. In order to re-use NGInlineItem
// as much as posssible, trailing spaces are removed in Phase II, exactly as
// defined in the spec.
//
// [1] https://drafts.csswg.org/css-text-3/#line-break-transform
// [2] https://drafts.csswg.org/css-text-3/#white-space-phase-2
return text_.ToString();
}
template <>
String NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::ToString() {
// While trailing collapsible space is kept as above, NGOffsetMappingBuilder
// assumes NGLineBreaker does not remove it. For now, remove only for
// NGOffsetMappingBuilder.
// TODO(kojii): Consider NGOffsetMappingBuilder to support NGLineBreaker to
// remove trailing spaces.
RemoveTrailingCollapsibleSpaceIfExists();
return text_.ToString();
......
......@@ -149,6 +149,9 @@ class CORE_TEMPLATE_CLASS_EXPORT NGInlineItemsBuilderTemplate {
void Exit(LayoutObject*);
};
template <>
String NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::ToString();
extern template class CORE_EXTERN_TEMPLATE_EXPORT
NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
......
......@@ -228,7 +228,8 @@ const NGInlineNodeData& NGInlineNode::EnsureData() {
const NGOffsetMapping* NGInlineNode::ComputeOffsetMappingIfNeeded() {
DCHECK(!GetLayoutBlockFlow()->GetDocument().NeedsLayoutTreeUpdate());
if (!Data().offset_mapping_) {
NGInlineNodeData* data = MutableData();
if (!data->offset_mapping_) {
// TODO(xiaochengh): ComputeOffsetMappingIfNeeded() discards the
// NGInlineItems and text content built by |builder|, because they are
// already there in NGInlineNodeData. For efficiency, we should make
......@@ -236,17 +237,22 @@ const NGOffsetMapping* NGInlineNode::ComputeOffsetMappingIfNeeded() {
Vector<NGInlineItem> items;
NGInlineItemsBuilderForOffsetMapping builder(&items);
CollectInlinesInternal(GetLayoutBlockFlow(), &builder);
builder.ToString();
String text = builder.ToString();
// The trailing space of the text for offset mapping may be removed. If not,
// share the string instance.
if (text == data->text_content_)
text = data->text_content_;
// TODO(xiaochengh): This doesn't compute offset mapping correctly when
// text-transform CSS property changes text length.
NGOffsetMappingBuilder& mapping_builder = builder.GetOffsetMappingBuilder();
mapping_builder.SetDestinationString(Text());
MutableData()->offset_mapping_ =
mapping_builder.SetDestinationString(text);
data->offset_mapping_ =
std::make_unique<NGOffsetMapping>(mapping_builder.Build());
}
return Data().offset_mapping_.get();
return data->offset_mapping_.get();
}
// Depth-first-scan of all LayoutInline and LayoutText nodes that make up this
......
......@@ -108,6 +108,19 @@ inline void NGLineBreaker::ComputeCanBreakAfter(
auto_wrap_ && break_iterator_.IsBreakable(item_result->end_offset);
}
// True if |item| is trailing; i.e., |item| and all items after it are opaque to
// whitespace collapsing.
bool NGLineBreaker::IsTrailing(const NGInlineItem& item,
const NGLineInfo& line_info) const {
const Vector<NGInlineItem>& items =
node_.Items(line_info.UseFirstLineStyle());
for (const NGInlineItem* it = &item; it != items.end(); ++it) {
if (it->EndCollapseType() != NGInlineItem::kOpaqueToCollapsing)
return false;
}
return true;
}
// @return if this is the "first formatted line".
// https://www.w3.org/TR/CSS22/selector.html#first-formatted-line
bool NGLineBreaker::IsFirstFormattedLine() const {
......@@ -210,6 +223,7 @@ void NGLineBreaker::BreakLine(NGLineInfo* line_info) {
// If we reach at the end of the block, this is the last line.
DCHECK_LE(item_index_, items.size());
if (item_index_ == items.size()) {
RemoveTrailingCollapsibleSpace(line_info);
line_info->SetIsLastLine(true);
return;
}
......@@ -251,7 +265,7 @@ void NGLineBreaker::BreakLine(NGLineInfo* line_info) {
} else if (item.Type() == NGInlineItem::kOpenTag) {
HandleOpenTag(item, AddItem(item, item_results));
} else if (item.Type() == NGInlineItem::kFloating) {
HandleFloat(item, AddItem(item, item_results));
HandleFloat(item, line_info, AddItem(item, item_results));
} else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) {
DCHECK_EQ(item.Length(), 0u);
AddItem(item, item_results);
......@@ -434,6 +448,7 @@ NGLineBreaker::LineBreakState NGLineBreaker::HandleTrailingSpaces(
NGInlineItemResult* item_result = AddItem(item, end, item_results);
item_result->has_only_trailing_spaces = true;
// TODO(kojii): Should reshape if it's not safe to break.
item_result->shape_result = item.TextShapeResult()->SubRange(offset_, end);
item_result->inline_size = item_result->shape_result->SnappedWidth();
line_.position += item_result->inline_size;
......@@ -451,6 +466,44 @@ NGLineBreaker::LineBreakState NGLineBreaker::HandleTrailingSpaces(
return LineBreakState::kTrailing;
}
// Remove trailing collapsible spaces in |line_info|.
// https://drafts.csswg.org/css-text-3/#white-space-phase-2
void NGLineBreaker::RemoveTrailingCollapsibleSpace(NGLineInfo* line_info) {
NGInlineItemResults* item_results = &line_info->Results();
if (item_results->IsEmpty())
return;
for (auto it = item_results->rbegin(); it != item_results->rend(); ++it) {
NGInlineItemResult& item_result = *it;
DCHECK(item_result.item);
const NGInlineItem& item = *item_result.item;
if (item.EndCollapseType() == NGInlineItem::kOpaqueToCollapsing)
continue;
if (item.Type() != NGInlineItem::kText)
return;
const String& text = Text();
if (text[item_result.end_offset - 1] != kSpaceCharacter)
return;
DCHECK(item.Style());
if (!item.Style()->CollapseWhiteSpace())
return;
// We have a trailing collapsible space. Remove it.
line_.position -= item_result.inline_size;
--item_result.end_offset;
if (item_result.end_offset == item_result.start_offset) {
unsigned index = std::distance(item_results->begin(), &item_result);
item_results->EraseAt(index);
} else {
// TODO(kojii): Should reshape if it's not safe to break.
item_result.shape_result = item_result.shape_result->SubRange(
item_result.start_offset, item_result.end_offset);
item_result.inline_size = item_result.shape_result->SnappedWidth();
line_.position += item_result.inline_size;
}
return;
}
}
void NGLineBreaker::AppendHyphen(const NGInlineItem& item,
NGLineInfo* line_info) {
DCHECK(item.Style());
......@@ -600,6 +653,7 @@ void NGLineBreaker::HandleAtomicInline(const NGInlineItem& item,
//
// TODO(glebl): Add the support of clearance for inline floats.
void NGLineBreaker::HandleFloat(const NGInlineItem& item,
NGLineInfo* line_info,
NGInlineItemResult* item_result) {
// When rewind occurs, an item may be handled multiple times.
// Since floats are put into a separate list, avoid handling same floats
......@@ -615,6 +669,13 @@ void NGLineBreaker::HandleFloat(const NGInlineItem& item,
if (item_index_ <= handled_floats_end_item_index_ || ignore_floats_)
return;
// Floats need to know the current line width to determine whether to put it
// into the current line or to the next line. Remove trailing spaces if this
// float is trailing, because whitespace should be collapsed across floats,
// and this logic requires the width after trailing spaces are collapsed.
if (IsTrailing(item, *line_info))
RemoveTrailingCollapsibleSpace(line_info);
NGBlockNode node(ToLayoutBox(item.GetLayoutObject()));
const ComputedStyle& float_style = node.Style();
......
......@@ -130,6 +130,7 @@ class CORE_EXPORT NGLineBreaker {
LayoutUnit available_width,
NGLineInfo*);
LineBreakState HandleTrailingSpaces(const NGInlineItem&, NGLineInfo*);
void RemoveTrailingCollapsibleSpace(NGLineInfo*);
void AppendHyphen(const NGInlineItem& item, NGLineInfo*);
LineBreakState HandleControlItem(const NGInlineItem&,
......@@ -139,7 +140,7 @@ class CORE_EXPORT NGLineBreaker {
LineBreakState,
NGLineInfo*);
void HandleAtomicInline(const NGInlineItem&, NGLineInfo*);
void HandleFloat(const NGInlineItem&, NGInlineItemResult*);
void HandleFloat(const NGInlineItem&, NGLineInfo*, NGInlineItemResult*);
void HandleOpenTag(const NGInlineItem&, NGInlineItemResult*);
void HandleCloseTag(const NGInlineItem&, NGInlineItemResults*);
......@@ -157,6 +158,7 @@ class CORE_EXPORT NGLineBreaker {
bool IsFirstFormattedLine() const;
void ComputeBaseDirection();
bool IsTrailing(const NGInlineItem&, const NGLineInfo&) const;
LineData line_;
NGInlineNode node_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment