Title: [249895] trunk
Revision
249895
Author
[email protected]
Date
2019-09-16 07:31:37 -0700 (Mon, 16 Sep 2019)

Log Message

LayoutTests/imported/w3c:
    Eliminate separate simple line layout path from TextIterator
    https://bugs.webkit.org/show_bug.cgi?id=201760

    Reviewed by Zalan Bujtas.

    * web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-015-expected.txt:
    * web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-016-expected.txt:
    * web-platform-tests/innerText/getter-expected.txt:

    Two '\t' subtests flip to FAIL because this was only supported on TextIterator simple line layout path.
    This can now be fixed correctly for both paths.


Source/WebCore:
Eliminate separate simple line layout path from TextIterator
https://bugs.webkit.org/show_bug.cgi?id=201760

Reviewed by Zalan Bujtas.

Use the new line layout iterator to implement linebox traversal in TextIterator.

* WebCore.xcodeproj/project.pbxproj:
* editing/TextIterator.cpp:
(WebCore::TextIterator::advance):
(WebCore::TextIterator::handleTextNode):
(WebCore::TextIterator::handleTextBox):

InlineTextBox* -> LineLayoutInterface::TextBoxIterator
Delete the seperate simple line layout path.

(WebCore::TextIterator::handleTextNodeFirstLetter):
(WebCore::TextIterator::emitCharacter):
(WebCore::TextIterator::emitText):
* editing/TextIterator.h:
* rendering/RenderTreeAsText.cpp:
(WebCore::RenderTreeAsText::writeRenderObject):
(WebCore::write):
* rendering/SimpleLineLayoutResolver.cpp:
(WebCore::SimpleLineLayout::RunResolver::Iterator::Iterator):
(WebCore::SimpleLineLayout::RunResolver::Iterator::advanceLines):
* rendering/SimpleLineLayoutResolver.h:
(WebCore::SimpleLineLayout::RunResolver::Iterator::resolver const):
(WebCore::SimpleLineLayout::RunResolver::Iterator::inQuirksMode const):
(WebCore::SimpleLineLayout::RunResolver::Iterator::operator== const):
(WebCore::SimpleLineLayout::RunResolver::Iterator::simpleRun const):

Make RunResolver::Iterator copyable (so TextBoxIterator becomes copyable too).

* rendering/SimpleLineLayoutTextFragmentIterator.cpp:
(WebCore::SimpleLineLayout::TextFragmentIterator::findNextTextFragment):
* rendering/line/LineLayoutInterfaceTextBoxes.cpp:
(WebCore::LineLayoutInterface::TextBox::rect const):
(WebCore::LineLayoutInterface::TextBox::logicalRect const):
(WebCore::LineLayoutInterface::TextBox::hasHyphen const):
(WebCore::LineLayoutInterface::TextBox::isLeftToRightDirection const):
(WebCore::LineLayoutInterface::TextBox::dirOverride const):
(WebCore::LineLayoutInterface::TextBox::text const):
(WebCore::LineLayoutInterface::TextBox::localStartOffset const):
(WebCore::LineLayoutInterface::TextBox::localEndOffset const):
(WebCore::LineLayoutInterface::TextBox::length const):

Add offset and length functions.

(WebCore::LineLayoutInterface::TextBox::iterator const):
(WebCore::LineLayoutInterface::TextBoxIterator::TextBoxIterator):
(WebCore::LineLayoutInterface::TextBoxIterator::traverseNext):
(WebCore::LineLayoutInterface::TextBoxIterator::operator== const):
(WebCore::LineLayoutInterface::TextBoxIterator::atEnd const):
(WebCore::LineLayoutInterface::Provider::firstTextBoxFor):
(WebCore::LineLayoutInterface::Provider::textBoxRangeFor):
(WebCore::LineLayoutInterface::Provider::iteratorForInlineTextBox):

Add Provider class for making iterators. It constructs and keeps SimpleLineLayout::Resolvers alive during traversal as needed.

* rendering/line/LineLayoutInterfaceTextBoxes.h:
(WebCore::LineLayoutInterface::TextBoxIterator::TextBoxIterator):
(WebCore::LineLayoutInterface::TextBoxIterator::operator bool const):
(WebCore::LineLayoutInterface::TextBoxIterator::operator== const):
(WebCore::LineLayoutInterface::TextBoxIterator::operator!= const):
(WebCore::LineLayoutInterface::TextBoxIterator::operator* const):
(WebCore::LineLayoutInterface::TextBoxIterator::operator-> const):

Make TextBoxIterator privately inherit TextBox. This way we don't need to construct temporaries and can easily implement operator->.

(WebCore::LineLayoutInterface::TextBoxRange::TextBoxRange):
(WebCore::LineLayoutInterface::TextBoxRange::begin const):
(WebCore::LineLayoutInterface::TextBoxRange::end const):

Use separate end() type of C++17 ranges.

LayoutTests:
Eliminate separate simple line layout path from TextIterator
https://bugs.webkit.org/show_bug.cgi?id=201760

Reviewed by Zalan Bujtas.

This patch makes simple and complex line layout path results from TextIterator match, causing some whitespace changes.

* animations/lineheight-animation-expected.txt:
* animations/simultaneous-start-transform-expected.txt:
* animations/width-using-ems-expected.txt:
* compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt:
* css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt:
* fast/events/window-events-bubble-expected.txt:
* fast/events/window-events-bubble2-expected.txt:
* fast/tokenizer/script_extra_close-expected.txt:
* legacy-animation-engine/animations/lineheight-animation-expected.txt:
* legacy-animation-engine/animations/simultaneous-start-transform-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (249894 => 249895)


--- trunk/LayoutTests/ChangeLog	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/ChangeLog	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,3 +1,24 @@
+2019-09-16  Antti Koivisto  <[email protected]>
+
+        Eliminate separate simple line layout path from TextIterator
+        https://bugs.webkit.org/show_bug.cgi?id=201760
+
+        Reviewed by Zalan Bujtas.
+
+        This patch makes simple and complex line layout path results from TextIterator match, causing some whitespace changes.
+
+        * animations/lineheight-animation-expected.txt:
+        * animations/simultaneous-start-transform-expected.txt:
+        * animations/width-using-ems-expected.txt:
+        * compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt:
+        * css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt:
+        * fast/events/window-events-bubble-expected.txt:
+        * fast/events/window-events-bubble2-expected.txt:
+        * fast/tokenizer/script_extra_close-expected.txt:
+        * legacy-animation-engine/animations/lineheight-animation-expected.txt:
+        * legacy-animation-engine/animations/simultaneous-start-transform-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt:
+
 2019-09-16  Andres Gonzalez  <[email protected]>
 
         Expose misspelling ranges for editable content to accessibility clients.

Modified: trunk/LayoutTests/animations/lineheight-animation-expected.txt (249894 => 249895)


--- trunk/LayoutTests/animations/lineheight-animation-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/animations/lineheight-animation-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,3 +1,3 @@
-This test performs an animation of the line-height property. It tests whether or not we are properly getting the font-size.Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
+This test performs an animation of the line-height property. It tests whether or not we are properly getting the font-size. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
 PASS - "lineHeight" property for "box" element at 0.1s saw something close to: 10
 

Modified: trunk/LayoutTests/animations/simultaneous-start-transform-expected.txt (249894 => 249895)


--- trunk/LayoutTests/animations/simultaneous-start-transform-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/animations/simultaneous-start-transform-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-This test performs an animation of the transform property. It animates over 10 seconds. It takes 3 snapshots and expects each result to be within a specified range.PASS - "webkitTransform" property for "box1" element at 2s saw something close to: 0.309017,0.951057
+This test performs an animation of the transform property. It animates over 10 seconds. It takes 3 snapshots and expects each result to be within a specified range. PASS - "webkitTransform" property for "box1" element at 2s saw something close to: 0.309017,0.951057
 PASS - "webkitTransform" property for "box2" element at 2s saw something close to: 0.309017,0.951057
 PASS - "webkitTransform" property for "box1" and "box2" elements at 2s are close enough to each other
 PASS - "webkitTransform" property for "box1" element at 5s saw something close to: -1,0

Modified: trunk/LayoutTests/animations/width-using-ems-expected.txt (249894 => 249895)


--- trunk/LayoutTests/animations/width-using-ems-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/animations/width-using-ems-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,3 +1,3 @@
-This test performs an animation of the width property using 'em' units. It tests whether or not we are properly getting the default font-size.Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
+This test performs an animation of the width property using 'em' units. It tests whether or not we are properly getting the default font-size. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
 PASS - "width" property for "box" element at 0.333s saw something close to: 133
 

Modified: trunk/LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt (249894 => 249895)


--- trunk/LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-relativeabsolute
+relative absolute
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)

Modified: trunk/LayoutTests/css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt (249894 => 249895)


--- trunk/LayoutTests/css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-foofoobar
+foo foobar
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)

Modified: trunk/LayoutTests/fast/events/window-events-bubble-expected.txt (249894 => 249895)


--- trunk/LayoutTests/fast/events/window-events-bubble-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/fast/events/window-events-bubble-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1 +1 @@
-Test that stopPropagation() will not allow window events to bubble. Clicking on this should not fire window.onclick. This matches our old behavior and Firefox behavior.stopPropagation called. Test Passed.
+Test that stopPropagation() will not allow window events to bubble. Clicking on this should not fire window.onclick. This matches our old behavior and Firefox behavior. stopPropagation called. Test Passed.

Modified: trunk/LayoutTests/fast/events/window-events-bubble2-expected.txt (249894 => 249895)


--- trunk/LayoutTests/fast/events/window-events-bubble2-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/fast/events/window-events-bubble2-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1 +1 @@
-Tests that preventDefault() will still allow window events to bubble. Clicking here should fire window.onclick. This will match Firefox behavior.Window.onClick fired. Test Passed.
+Tests that preventDefault() will still allow window events to bubble. Clicking here should fire window.onclick. This will match Firefox behavior. Window.onClick fired. Test Passed.

Modified: trunk/LayoutTests/fast/tokenizer/script_extra_close-expected.txt (249894 => 249895)


--- trunk/LayoutTests/fast/tokenizer/script_extra_close-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/fast/tokenizer/script_extra_close-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1 +1 @@
-TEST... PASSED. This text should show up.
+TEST...	PASSED. This text should show up.

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (249894 => 249895)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,3 +1,17 @@
+2019-09-16  Antti Koivisto  <[email protected]>
+
+    Eliminate separate simple line layout path from TextIterator
+    https://bugs.webkit.org/show_bug.cgi?id=201760
+
+    Reviewed by Zalan Bujtas.
+
+    * web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-015-expected.txt:
+    * web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-016-expected.txt:
+    * web-platform-tests/innerText/getter-expected.txt:
+
+    Two '\t' subtests flip to FAIL because this was only supported on TextIterator simple line layout path.
+    This can now be fixed correctly for both paths.
+
 2019-09-15  Chris Dumez  <[email protected]>
 
         Re-sync HTML web-platform-tests from upstream

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-015-expected.txt (249894 => 249895)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-015-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-015-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -3,7 +3,7 @@
 XX XXXX XX XXX X
 X XXX
 X
-XX XXXX XX XXX X
+XX XXX X XX XXX X
 X XXX X
 XX XXXX XX XXX X
 X XXX

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-016-expected.txt (249894 => 249895)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-016-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/alignment/grid-row-axis-alignment-positioned-items-016-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -3,7 +3,7 @@
 XX XXXX XX XXX X
 X XXX
 X
-XX XXXX XX XXX X
+XX XXX X XX XXX X
 X XXX X
 XX XXXX XX XXX X
 X XXX

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt (249894 => 249895)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -7,7 +7,7 @@
 PASS Internal whitespace compressed ("<div>abc  def") 
 PASS \n converted to space ("<div>abc\ndef") 
 PASS \r converted to space ("<div>abc\rdef") 
-PASS \t converted to space ("<div>abc\tdef") 
+FAIL \t converted to space ("<div>abc\tdef") assert_equals: expected "abc def" but got "abc\tdef"
 FAIL Trailing whitespace before hard line break removed ("<div>abc <br>def") assert_equals: expected "abc\ndef" but got "abc \ndef"
 PASS Leading whitespace after hard line break removed ("<div>abc<br> def") 
 PASS Leading whitespace preserved ("<pre> abc") 
@@ -32,9 +32,9 @@
 PASS Leading whitespace removed ("<div style='white-space:pre-line'> abc") 
 PASS Trailing whitespace removed ("<div style='white-space:pre-line'>abc ") 
 PASS Internal whitespace collapsed ("<div style='white-space:pre-line'>abc  def") 
-FAIL \n preserved ("<div style='white-space:pre-line'>abc\ndef") assert_equals: expected "abc\ndef" but got "abcdef"
-FAIL \r converted to newline ("<div style='white-space:pre-line'>abc\rdef") assert_equals: expected "abc\ndef" but got "abcdef"
-PASS \t converted to space ("<div style='white-space:pre-line'>abc\tdef") 
+FAIL \n preserved ("<div style='white-space:pre-line'>abc\ndef") assert_equals: expected "abc\ndef" but got "abc def"
+FAIL \r converted to newline ("<div style='white-space:pre-line'>abc\rdef") assert_equals: expected "abc\ndef" but got "abc def"
+FAIL \t converted to space ("<div style='white-space:pre-line'>abc\tdef") assert_equals: expected "abc def" but got "abc\tdef"
 PASS Whitespace collapses across element boundaries ("<div><span>abc </span> def") 
 PASS Whitespace collapses across element boundaries ("<div><span>abc </span><span></span> def") 
 FAIL Whitespace collapses across element boundaries ("<div><span>abc </span><span style='white-space:pre'></span> def") assert_equals: expected "abc def" but got "abc  def"
@@ -151,7 +151,7 @@
 FAIL Invisible <p> doesn't induce extra line breaks ("<div style='visibility:hidden'><p><span style='visibility:visible'>abc</span></p>\n<div style='visibility:visible'>def</div>") assert_equals: expected "abc\ndef" but got "abc\n\ndef\n"
 FAIL No blank lines around <div> with margin ("<div>abc<div style='margin:2em'>def") assert_equals: expected "abc\ndef" but got "abc\ndef\n"
 PASS No newlines at display:inline-block boundary ("<div>123<span style='display:inline-block'>abc</span>def") 
-FAIL Leading/trailing space removal at display:inline-block boundary ("<div>123<span style='display:inline-block'> abc </span>def") assert_equals: expected "123abcdef" but got "123abc def"
+FAIL Leading/trailing space removal at display:inline-block boundary ("<div>123<span style='display:inline-block'> abc </span>def") assert_equals: expected "123abcdef" but got "123 abc def"
 FAIL Blank lines around <p> even without margin ("<div>123<p style='margin:0px'>abc</p>def") assert_equals: expected "123\n\nabc\n\ndef" but got "123\nabc\ndef"
 FAIL No blank lines around <h1> ("<div>123<h1>abc</h1>def") assert_equals: expected "123\nabc\ndef" but got "123\nabc\n\ndef"
 FAIL No blank lines around <h2> ("<div>123<h2>abc</h2>def") assert_equals: expected "123\nabc\ndef" but got "123\nabc\n\ndef"

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/innerText/getter-expected.txt (249894 => 249895)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/innerText/getter-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/innerText/getter-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -7,7 +7,7 @@
 PASS Internal whitespace compressed ("<div>abc  def") 
 PASS \n converted to space ("<div>abc\ndef") 
 PASS \r converted to space ("<div>abc\rdef") 
-PASS \t converted to space ("<div>abc\tdef") 
+FAIL \t converted to space ("<div>abc\tdef") assert_equals: expected "abc def" but got "abc\tdef"
 FAIL Trailing whitespace before hard line break removed ("<div>abc <br>def") assert_equals: expected "abc\ndef" but got "abc \ndef"
 PASS Leading whitespace preserved ("<pre> abc") 
 PASS Trailing whitespace preserved ("<pre>abc ") 
@@ -31,9 +31,9 @@
 PASS Leading whitespace removed ("<div style='white-space:pre-line'> abc") 
 PASS Trailing whitespace removed ("<div style='white-space:pre-line'>abc ") 
 PASS Internal whitespace collapsed ("<div style='white-space:pre-line'>abc  def") 
-FAIL \n preserved ("<div style='white-space:pre-line'>abc\ndef") assert_equals: expected "abc\ndef" but got "abcdef"
-FAIL \r converted to newline ("<div style='white-space:pre-line'>abc\rdef") assert_equals: expected "abc\ndef" but got "abcdef"
-PASS \t converted to space ("<div style='white-space:pre-line'>abc\tdef") 
+FAIL \n preserved ("<div style='white-space:pre-line'>abc\ndef") assert_equals: expected "abc\ndef" but got "abc def"
+FAIL \r converted to newline ("<div style='white-space:pre-line'>abc\rdef") assert_equals: expected "abc\ndef" but got "abc def"
+FAIL \t converted to space ("<div style='white-space:pre-line'>abc\tdef") assert_equals: expected "abc def" but got "abc\tdef"
 PASS Whitespace collapses across element boundaries ("<div><span>abc </span> def") 
 PASS Whitespace collapses across element boundaries ("<div><span>abc </span><span></span> def") 
 FAIL Whitespace collapses across element boundaries ("<div><span>abc </span><span style='white-space:pre'></span> def") assert_equals: expected "abc def" but got "abc  def"
@@ -135,7 +135,7 @@
 FAIL Invisible <p> doesn't induce extra line breaks ("<div style='visibility:hidden'><p><span style='visibility:visible'>abc</span></p>\n<div style='visibility:visible'>def</div>") assert_equals: expected "abc\ndef" but got "abc\n\ndef\n"
 FAIL No blank lines around <div> with margin ("<div>abc<div style='margin:2em'>def") assert_equals: expected "abc\ndef" but got "abc\ndef\n"
 PASS No newlines at display:inline-block boundary ("<div>123<span style='display:inline-block'>abc</span>def") 
-FAIL Leading/trailing space removal at display:inline-block boundary ("<div>123<span style='display:inline-block'> abc </span>def") assert_equals: expected "123abcdef" but got "123abc def"
+FAIL Leading/trailing space removal at display:inline-block boundary ("<div>123<span style='display:inline-block'> abc </span>def") assert_equals: expected "123abcdef" but got "123 abc def"
 FAIL Blank lines around <p> even without margin ("<div>123<p style='margin:0px'>abc</p>def") assert_equals: expected "123\n\nabc\n\ndef" but got "123\nabc\ndef"
 FAIL No blank lines around <h1> ("<div>123<h1>abc</h1>def") assert_equals: expected "123\nabc\ndef" but got "123\nabc\n\ndef"
 FAIL No blank lines around <h2> ("<div>123<h2>abc</h2>def") assert_equals: expected "123\nabc\ndef" but got "123\nabc\n\ndef"

Modified: trunk/LayoutTests/legacy-animation-engine/animations/lineheight-animation-expected.txt (249894 => 249895)


--- trunk/LayoutTests/legacy-animation-engine/animations/lineheight-animation-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/legacy-animation-engine/animations/lineheight-animation-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,3 +1,3 @@
-This test performs an animation of the line-height property. It tests whether or not we are properly getting the font-size.Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
+This test performs an animation of the line-height property. It tests whether or not we are properly getting the font-size. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
 PASS - "lineHeight" property for "box" element at 0.1s saw something close to: 10
 

Modified: trunk/LayoutTests/legacy-animation-engine/animations/simultaneous-start-transform-expected.txt (249894 => 249895)


--- trunk/LayoutTests/legacy-animation-engine/animations/simultaneous-start-transform-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/legacy-animation-engine/animations/simultaneous-start-transform-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-This test performs an animation of the transform property. It animates over 10 seconds. It takes 3 snapshots and expects each result to be within a specified range.PASS - "webkitTransform" property for "box1" element at 2s saw something close to: 0.309017,0.951057
+This test performs an animation of the transform property. It animates over 10 seconds. It takes 3 snapshots and expects each result to be within a specified range. PASS - "webkitTransform" property for "box1" element at 2s saw something close to: 0.309017,0.951057
 PASS - "webkitTransform" property for "box2" element at 2s saw something close to: 0.309017,0.951057
 PASS - "webkitTransform" property for "box1" and "box2" elements at 2s are close enough to each other
 PASS - "webkitTransform" property for "box1" element at 5s saw something close to: -1,0

Modified: trunk/LayoutTests/legacy-animation-engine/animations/width-using-ems-expected.txt (249894 => 249895)


--- trunk/LayoutTests/legacy-animation-engine/animations/width-using-ems-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/legacy-animation-engine/animations/width-using-ems-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,3 +1,3 @@
-This test performs an animation of the width property using 'em' units. It tests whether or not we are properly getting the default font-size.Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
+This test performs an animation of the width property using 'em' units. It tests whether or not we are properly getting the default font-size. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
 PASS - "width" property for "box" element at 0.333s saw something close to: 133
 

Modified: trunk/LayoutTests/platform/ios/css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt (249894 => 249895)


--- trunk/LayoutTests/platform/ios/css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/platform/ios/css3/filters/backdrop/backdrop-filter-does-not-size-properly-absolute-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-foofoobar
+foo foobar
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)

Modified: trunk/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt (249894 => 249895)


--- trunk/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-relativeabsolute
+relative absolute
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)

Modified: trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt (249894 => 249895)


--- trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-absabs
+abs abs
 
 (Frame scrolling node
   (scrollable area size 800 600)

Modified: trunk/LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt (249894 => 249895)


--- trunk/LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-overflow-expected.txt	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,4 +1,4 @@
-absabs
+abs abs
 
 (Frame scrolling node
   (scrollable area size 800 600)

Modified: trunk/Source/WebCore/ChangeLog (249894 => 249895)


--- trunk/Source/WebCore/ChangeLog	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/ChangeLog	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1,3 +1,81 @@
+2019-09-16  Antti Koivisto  <[email protected]>
+
+        Eliminate separate simple line layout path from TextIterator
+        https://bugs.webkit.org/show_bug.cgi?id=201760
+
+        Reviewed by Zalan Bujtas.
+
+        Use the new line layout iterator to implement linebox traversal in TextIterator.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * editing/TextIterator.cpp:
+        (WebCore::TextIterator::advance):
+        (WebCore::TextIterator::handleTextNode):
+        (WebCore::TextIterator::handleTextBox):
+
+        InlineTextBox* -> LineLayoutInterface::TextBoxIterator
+        Delete the seperate simple line layout path.
+
+        (WebCore::TextIterator::handleTextNodeFirstLetter):
+        (WebCore::TextIterator::emitCharacter):
+        (WebCore::TextIterator::emitText):
+        * editing/TextIterator.h:
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::RenderTreeAsText::writeRenderObject):
+        (WebCore::write):
+        * rendering/SimpleLineLayoutResolver.cpp:
+        (WebCore::SimpleLineLayout::RunResolver::Iterator::Iterator):
+        (WebCore::SimpleLineLayout::RunResolver::Iterator::advanceLines):
+        * rendering/SimpleLineLayoutResolver.h:
+        (WebCore::SimpleLineLayout::RunResolver::Iterator::resolver const):
+        (WebCore::SimpleLineLayout::RunResolver::Iterator::inQuirksMode const):
+        (WebCore::SimpleLineLayout::RunResolver::Iterator::operator== const):
+        (WebCore::SimpleLineLayout::RunResolver::Iterator::simpleRun const):
+
+        Make RunResolver::Iterator copyable (so TextBoxIterator becomes copyable too).
+
+        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::findNextTextFragment):
+        * rendering/line/LineLayoutInterfaceTextBoxes.cpp:
+        (WebCore::LineLayoutInterface::TextBox::rect const):
+        (WebCore::LineLayoutInterface::TextBox::logicalRect const):
+        (WebCore::LineLayoutInterface::TextBox::hasHyphen const):
+        (WebCore::LineLayoutInterface::TextBox::isLeftToRightDirection const):
+        (WebCore::LineLayoutInterface::TextBox::dirOverride const):
+        (WebCore::LineLayoutInterface::TextBox::text const):
+        (WebCore::LineLayoutInterface::TextBox::localStartOffset const):
+        (WebCore::LineLayoutInterface::TextBox::localEndOffset const):
+        (WebCore::LineLayoutInterface::TextBox::length const):
+
+        Add offset and length functions.
+
+        (WebCore::LineLayoutInterface::TextBox::iterator const):
+        (WebCore::LineLayoutInterface::TextBoxIterator::TextBoxIterator):
+        (WebCore::LineLayoutInterface::TextBoxIterator::traverseNext):
+        (WebCore::LineLayoutInterface::TextBoxIterator::operator== const):
+        (WebCore::LineLayoutInterface::TextBoxIterator::atEnd const):
+        (WebCore::LineLayoutInterface::Provider::firstTextBoxFor):
+        (WebCore::LineLayoutInterface::Provider::textBoxRangeFor):
+        (WebCore::LineLayoutInterface::Provider::iteratorForInlineTextBox):
+
+        Add Provider class for making iterators. It constructs and keeps SimpleLineLayout::Resolvers alive during traversal as needed.
+
+        * rendering/line/LineLayoutInterfaceTextBoxes.h:
+        (WebCore::LineLayoutInterface::TextBoxIterator::TextBoxIterator):
+        (WebCore::LineLayoutInterface::TextBoxIterator::operator bool const):
+        (WebCore::LineLayoutInterface::TextBoxIterator::operator== const):
+        (WebCore::LineLayoutInterface::TextBoxIterator::operator!= const):
+        (WebCore::LineLayoutInterface::TextBoxIterator::operator* const):
+        (WebCore::LineLayoutInterface::TextBoxIterator::operator-> const):
+
+        Make TextBoxIterator privately inherit TextBox. This way we don't need to construct temporaries and can easily implement operator->.
+
+        (WebCore::LineLayoutInterface::TextBoxRange::TextBoxRange):
+        (WebCore::LineLayoutInterface::TextBoxRange::begin const):
+        (WebCore::LineLayoutInterface::TextBoxRange::end const):
+
+        Use separate end() type of C++17 ranges.
+
 2019-09-16  Andres Gonzalez  <[email protected]>
 
         Expose misspelling ranges for editable content to accessibility clients.

Modified: trunk/Source/WebCore/Headers.cmake (249894 => 249895)


--- trunk/Source/WebCore/Headers.cmake	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/Headers.cmake	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1303,7 +1303,10 @@
     rendering/SelectionRangeData.h
     rendering/SimpleLineLayout.h
     rendering/SimpleLineLayoutCoverage.h
+    rendering/SimpleLineLayoutFlowContents.h
+    rendering/SimpleLineLayoutResolver.h
 
+    rendering/line/LineLayoutInterfaceTextBoxes.h
     rendering/line/LineWidth.h
     rendering/line/TrailingObjects.h
 

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (249894 => 249895)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-09-16 14:31:37 UTC (rev 249895)
@@ -1832,7 +1832,7 @@
 		5824ABA71AE81384009074B7 /* RubyTextElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 5824ABA51AE81384009074B7 /* RubyTextElement.h */; };
 		582CB0531A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 582CB0521A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h */; };
 		582DE3251C30C85400BE02A8 /* TextDecorationPainter.h in Headers */ = {isa = PBXBuildFile; fileRef = 582DE3231C30C85400BE02A8 /* TextDecorationPainter.h */; };
-		585D6E041A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h in Headers */ = {isa = PBXBuildFile; fileRef = 585D6E021A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h */; };
+		585D6E041A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h in Headers */ = {isa = PBXBuildFile; fileRef = 585D6E021A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		589556ED18D4A44000764B03 /* BorderEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 589556EC18D4A44000764B03 /* BorderEdge.h */; };
 		58B2F9F42232D45300938D63 /* ResizeObservation.h in Headers */ = {isa = PBXBuildFile; fileRef = 58B2F9F32232D43F00938D63 /* ResizeObservation.h */; };
 		58B2F9F52232D45800938D63 /* ResizeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 58B2F9EC2232D43B00938D63 /* ResizeObserver.h */; };
@@ -4795,7 +4795,7 @@
 		E47C39331FE6E10800BBBC6B /* RenderTreeBuilderMultiColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39271FE6E0DC00BBBC6B /* RenderTreeBuilderMultiColumn.h */; };
 		E47E276516036ED200EE2AFB /* ExtensionStyleSheets.h in Headers */ = {isa = PBXBuildFile; fileRef = E47E276416036ED200EE2AFB /* ExtensionStyleSheets.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E48137B91DB3B526005C59BF /* StyleValidity.h in Headers */ = {isa = PBXBuildFile; fileRef = E48137B81DB3B526005C59BF /* StyleValidity.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		E484A33E23055325009ADE6A /* LineLayoutInterfaceTextBoxes.h in Headers */ = {isa = PBXBuildFile; fileRef = E484A33B23055303009ADE6A /* LineLayoutInterfaceTextBoxes.h */; };
+		E484A33E23055325009ADE6A /* LineLayoutInterfaceTextBoxes.h in Headers */ = {isa = PBXBuildFile; fileRef = E484A33B23055303009ADE6A /* LineLayoutInterfaceTextBoxes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E48944A1180B57D800F165D8 /* SimpleLineLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4916FF7195DF6A0005AB349 /* LayerFlushThrottleState.h in Headers */ = {isa = PBXBuildFile; fileRef = E4916FF6195DF6A0005AB349 /* LayerFlushThrottleState.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */ = {isa = PBXBuildFile; fileRef = E4946EAD156E64DD00D3297F /* StyleRuleImport.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4832,7 +4832,7 @@
 		E4E8B4EC216B79E500B8834D /* SystemFontDatabaseCoreText.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E8B4EA216B79E500B8834D /* SystemFontDatabaseCoreText.h */; };
 		E4E8B4F5216B956500B8834D /* FontCascadeDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E8B4F2216B8B6000B8834D /* FontCascadeDescription.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4E94D6122FF158A00DD191F /* ComplexLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E4A1AC7822FAFD500017B75B /* ComplexLineLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */; };
+		E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */; };
 		E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E516699120FF9918009D2C27 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = E516698F20FF9916009D2C27 /* [email protected] */; };

Modified: trunk/Source/WebCore/editing/TextIterator.cpp (249894 => 249895)


--- trunk/Source/WebCore/editing/TextIterator.cpp	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/editing/TextIterator.cpp	2019-09-16 14:31:37 UTC (rev 249895)
@@ -474,8 +474,8 @@
 
     if (!m_textBox && m_remainingTextBox) {
         m_textBox = m_remainingTextBox;
-        m_remainingTextBox = nullptr;
-        m_firstLetterText = nullptr;
+        m_remainingTextBox = { };
+        m_firstLetterText = { };
         m_offset = 0;
     }
     // handle remembered text box
@@ -574,25 +574,6 @@
     return false;
 }
 
-static unsigned textNodeOffsetInFlow(const Text& firstTextNodeInRange)
-{
-    // Calculate the text offset for simple lines.
-    RenderObject* renderer = firstTextNodeInRange.renderer();
-    if (!renderer)
-        return 0;
-    unsigned textOffset = 0;
-    for (renderer = renderer->previousSibling(); renderer; renderer = renderer->previousSibling()) {
-        if (is<RenderText>(renderer))
-            textOffset += downcast<RenderText>(renderer)->text().length();
-    }
-    return textOffset;
-}
-
-static bool isNewLineOrTabCharacter(UChar character)
-{
-    return character == '\n' || character == '\t';
-}
-
 bool TextIterator::handleTextNode()
 {
     Text& textNode = downcast<Text>(*m_node);
@@ -617,7 +598,7 @@
                 String firstLetter = m_firstLetterText->text();
                 emitText(textNode, *m_firstLetterText, m_offset, m_offset + firstLetter.length());
                 m_firstLetterText = nullptr;
-                m_textBox = nullptr;
+                m_textBox = { };
                 return false;
             }
         }
@@ -634,102 +615,13 @@
         return true;
     }
 
-    if (const auto* layout = renderer.simpleLineLayout()) {
-        if (renderer.style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility))
-            return true;
-        ASSERT(renderer.parent());
-        ASSERT(is<RenderBlockFlow>(*renderer.parent()));
-        const auto& blockFlow = downcast<RenderBlockFlow>(*renderer.parent());
-        // Use the simple layout runs to iterate over the text content.
-        bool isNewTextNode = m_previousSimpleTextNodeInFlow && m_previousSimpleTextNodeInFlow != &textNode;
-        // Simple line layout run positions are all absolute to the parent flow.
-        // Offsetting is required when multiple renderers are present.
-        m_accumulatedSimpleTextLengthInFlow += isNewTextNode ? m_previousSimpleTextNodeInFlow->renderer()->text().length() : 0;
-        m_previousSimpleTextNodeInFlow = &textNode;
+    m_textBox = m_lineLayoutProvider.firstTextBoxFor(renderer);
 
-        unsigned endPosition = (m_node == m_endContainer) ? static_cast<unsigned>(m_endOffset) : rendererText.length();
-        if (!m_flowRunResolverCache || &m_flowRunResolverCache->flow() != &blockFlow) {
-            m_accumulatedSimpleTextLengthInFlow = m_flowRunResolverCache ? 0 : textNodeOffsetInFlow(textNode);
-            m_flowRunResolverCache = makeUnique<SimpleLineLayout::RunResolver>(blockFlow, *layout);
-        }
-        // Skip to m_offset position.
-        auto range = m_flowRunResolverCache->rangeForRenderer(renderer);
-        auto it = range.begin();
-        auto end = range.end();
-        auto startPosition = static_cast<unsigned>(m_offset) + m_accumulatedSimpleTextLengthInFlow;
-        while (it != end && (*it).end() <= startPosition)
-            ++it;
-        if (m_nextRunNeedsWhitespace && rendererText[m_offset - 1] == '\n') {
-            emitCharacter(' ', textNode, nullptr, m_offset, m_offset + 1);
-            return it == end;
-        }
-        if (it == end) {
-            // Collapsed trailing whitespace.
-            m_offset = endPosition;
-            m_lastTextNodeEndedWithCollapsedSpace = true;
-            return true;
-        }
-        if (m_nextRunNeedsWhitespace) {
-            emitCharacter(' ', textNode, nullptr, m_offset, m_offset + 1);
-            return false;
-        }
-        // If the position we are looking for is to the left of the renderer's first run, it could mean that
-        // the runs and the renderers are out of sync (e.g. we skipped a renderer in between).
-        // Better bail out at this point.
-        auto run = *it;
-        if (run.start() > startPosition) {
-            ASSERT(m_flowRunResolverCache);
-            if (&(rendererForPosition(m_flowRunResolverCache->flowContents(), startPosition)) != &renderer) {
-                ASSERT_NOT_REACHED();
-                return true;
-            }
-        }
-        ASSERT(run.end() - run.start() <= rendererText.length());
-        // contentStart skips leading whitespace.
-        unsigned contentStart = std::max<unsigned>(m_offset, run.start() - m_accumulatedSimpleTextLengthInFlow);
-        unsigned contentEnd = std::min(endPosition, run.end() - m_accumulatedSimpleTextLengthInFlow);
-        ASSERT_WITH_SECURITY_IMPLICATION(contentStart <= contentEnd);
-        // Check if whitespace adjustment is needed when crossing renderer boundary.
-        if (isNewTextNode) {
-            bool lastCharacterIsNotWhitespace = m_lastCharacter && !renderer.style().isCollapsibleWhiteSpace(m_lastCharacter);
-            bool addTrailingWhitespaceForPrevious = m_lastTextNodeEndedWithCollapsedSpace && lastCharacterIsNotWhitespace;
-            bool leadingWhitespaceIsNeededForCurrent = contentStart > static_cast<unsigned>(m_offset) && lastCharacterIsNotWhitespace;
-            if (addTrailingWhitespaceForPrevious || leadingWhitespaceIsNeededForCurrent) {
-                emitCharacter(' ', textNode, nullptr, m_offset, m_offset + 1);
-                return false;
-            }
-        }
-        // \n \t single whitespace characters need replacing so that the new line/tab characters don't show up.
-        unsigned stopPosition = contentStart;
-        while (stopPosition < contentEnd && !isNewLineOrTabCharacter(rendererText[stopPosition]))
-            ++stopPosition;
-        // Emit the text up to the new line/tab character.
-        if (stopPosition < contentEnd) {
-            if (stopPosition == contentStart) {
-                emitCharacter(' ', textNode, nullptr, contentStart, contentStart + 1);
-                m_offset = contentStart + 1;
-                return false;
-            }
-            emitText(textNode, renderer, contentStart, stopPosition);
-            m_offset = stopPosition + 1;
-            m_nextRunNeedsWhitespace = true;
-            return false;
-        }
-        emitText(textNode, renderer, contentStart, contentEnd);
-        // When line ending with collapsed whitespace is present, we need to carry over one whitespace: foo(end of line)bar -> foo bar (otherwise we would end up with foobar).
-        m_nextRunNeedsWhitespace = run.isEndOfLine() && contentEnd < endPosition && renderer.style().isCollapsibleWhiteSpace(rendererText[contentEnd]);
-        m_offset = contentEnd;
-        return static_cast<unsigned>(m_offset) == endPosition;
-    }
-
-    if (renderer.firstTextBox())
-        m_textBox = renderer.firstTextBox();
-
     bool shouldHandleFirstLetter = !m_handledFirstLetter && is<RenderTextFragment>(renderer) && !m_offset;
     if (shouldHandleFirstLetter)
         handleTextNodeFirstLetter(downcast<RenderTextFragment>(renderer));
 
-    if (!renderer.firstTextBox() && rendererText.length() && !shouldHandleFirstLetter) {
+    if (!m_textBox && rendererText.length() && !shouldHandleFirstLetter) {
         if (renderer.style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility))
             return false;
         m_lastTextNodeEndedWithCollapsedSpace = true; // entire block is collapsed space
@@ -744,7 +636,7 @@
             m_sortedTextBoxes.append(textBox);
         std::sort(m_sortedTextBoxes.begin(), m_sortedTextBoxes.end(), InlineTextBox::compareByStart);
         m_sortedTextBoxesPosition = 0;
-        m_textBox = m_sortedTextBoxes.isEmpty() ? nullptr : m_sortedTextBoxes[0];
+        m_textBox = m_lineLayoutProvider.iteratorForInlineTextBox(m_sortedTextBoxes.isEmpty() ? nullptr : m_sortedTextBoxes[0]);
     }
 
     handleTextBox();
@@ -757,18 +649,25 @@
 
     auto& renderer = m_firstLetterText ? *m_firstLetterText : *textNode.renderer();
     if (renderer.style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility)) {
-        m_textBox = nullptr;
+        m_textBox = { };
         return;
     }
+
+    auto firstTextBox = [&] {
+        if (renderer.containsReversedText())
+            return m_lineLayoutProvider.iteratorForInlineTextBox(m_sortedTextBoxes.isEmpty() ? nullptr : m_sortedTextBoxes[0]);
+
+        return m_lineLayoutProvider.firstTextBoxFor(renderer);
+    }();
+
     String rendererText = renderer.text();
     unsigned start = m_offset;
     unsigned end = (&textNode == m_endContainer) ? static_cast<unsigned>(m_endOffset) : UINT_MAX;
     while (m_textBox) {
-        unsigned textBoxStart = m_textBox->start();
+        unsigned textBoxStart = m_textBox->localStartOffset();
         unsigned runStart = std::max(textBoxStart, start);
 
         // Check for collapsed space at the start of this run.
-        InlineTextBox* firstTextBox = renderer.containsReversedText() ? (m_sortedTextBoxes.isEmpty() ? nullptr : m_sortedTextBoxes[0]) : renderer.firstTextBox();
         bool needSpace = m_lastTextNodeEndedWithCollapsedSpace || (m_textBox == firstTextBox && textBoxStart == runStart && runStart);
         if (needSpace && !renderer.style().isCollapsibleWhiteSpace(m_lastCharacter) && m_lastCharacter) {
             if (m_lastTextNode == &textNode && runStart && rendererText[runStart - 1] == ' ') {
@@ -780,17 +679,19 @@
                 emitCharacter(' ', textNode, nullptr, runStart, runStart);
             return;
         }
-        unsigned textBoxEnd = textBoxStart + m_textBox->len();
+        unsigned textBoxEnd = textBoxStart + m_textBox->length();
         unsigned runEnd = std::min(textBoxEnd, end);
         
         // Determine what the next text box will be, but don't advance yet
-        InlineTextBox* nextTextBox = nullptr;
+        LineLayoutInterface::TextBoxIterator nextTextBox;
         if (renderer.containsReversedText()) {
+            // FIXME: Handle reversed text in the line layout iterator.
             if (m_sortedTextBoxesPosition + 1 < m_sortedTextBoxes.size())
-                nextTextBox = m_sortedTextBoxes[m_sortedTextBoxesPosition + 1];
-        } else 
-            nextTextBox = m_textBox->nextTextBox();
-        ASSERT(!nextTextBox || &nextTextBox->renderer() == &renderer);
+                nextTextBox = m_lineLayoutProvider.iteratorForInlineTextBox(m_sortedTextBoxes[m_sortedTextBoxesPosition + 1]);
+        } else {
+            nextTextBox = m_textBox;
+            ++nextTextBox;
+        }
 
         if (runStart < runEnd) {
             // Handle either a single newline character (which becomes a space),
@@ -817,7 +718,7 @@
                 return;
 
             // Advance and return
-            unsigned nextRunStart = nextTextBox ? nextTextBox->start() : rendererText.length();
+            unsigned nextRunStart = nextTextBox ? nextTextBox->localStartOffset() : rendererText.length();
             if (nextRunStart > runEnd)
                 m_lastTextNodeEndedWithCollapsedSpace = true; // collapsed space between runs or at the end
             m_textBox = nextTextBox;
@@ -832,8 +733,8 @@
     }
     if (!m_textBox && m_remainingTextBox) {
         m_textBox = m_remainingTextBox;
-        m_remainingTextBox = nullptr;
-        m_firstLetterText = nullptr;
+        m_remainingTextBox = { };
+        m_firstLetterText = { };
         m_offset = 0;
         handleTextBox();
     }
@@ -856,7 +757,7 @@
         if (auto* firstLetterText = firstRenderTextInFirstLetter(firstLetter)) {
             m_handledFirstLetter = true;
             m_remainingTextBox = m_textBox;
-            m_textBox = firstLetterText->firstTextBox();
+            m_textBox = m_lineLayoutProvider.firstTextBoxFor(*firstLetterText);
             m_sortedTextBoxes.clear();
             m_firstLetterText = firstLetterText;
         }
@@ -1222,7 +1123,6 @@
     m_text = m_copyableText.text();
     m_lastCharacter = character;
     m_lastTextNodeEndedWithCollapsedSpace = false;
-    m_nextRunNeedsWhitespace = false;
 }
 
 void TextIterator::emitText(Text& textNode, RenderText& renderer, int textStartOffset, int textEndOffset)
@@ -1247,7 +1147,6 @@
     m_text = m_copyableText.text();
 
     m_lastTextNodeEndedWithCollapsedSpace = false;
-    m_nextRunNeedsWhitespace = false;
     m_hasEmitted = true;
 }
 

Modified: trunk/Source/WebCore/editing/TextIterator.h (249894 => 249895)


--- trunk/Source/WebCore/editing/TextIterator.h	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/editing/TextIterator.h	2019-09-16 14:31:37 UTC (rev 249895)
@@ -28,6 +28,7 @@
 // FIXME: Move each iterator class into a separate header file.
 
 #include "FindOptions.h"
+#include "LineLayoutInterfaceTextBoxes.h"
 #include "Range.h"
 #include "TextIteratorBehavior.h"
 #include <wtf/Vector.h>
@@ -167,10 +168,10 @@
 
     // Used when there is still some pending text from the current node; when these are false and null, we go back to normal iterating.
     Node* m_nodeForAdditionalNewline { nullptr };
-    InlineTextBox* m_textBox { nullptr };
+    LineLayoutInterface::TextBoxIterator m_textBox;
 
     // Used when iterating over :first-letter text to save pointer to remaining text box.
-    InlineTextBox* m_remainingTextBox { nullptr };
+    LineLayoutInterface::TextBoxIterator m_remainingTextBox;
 
     // Used to point to RenderText object for :first-letter.
     RenderText* m_firstLetterText { nullptr };
@@ -180,11 +181,7 @@
     bool m_lastTextNodeEndedWithCollapsedSpace { false };
     UChar m_lastCharacter { 0 };
 
-    // Used to do simple line layout run logic.
-    bool m_nextRunNeedsWhitespace { false };
-    unsigned m_accumulatedSimpleTextLengthInFlow { 0 };
-    Text* m_previousSimpleTextNodeInFlow { nullptr };
-    std::unique_ptr<SimpleLineLayout::RunResolver> m_flowRunResolverCache;
+    LineLayoutInterface::Provider m_lineLayoutProvider;
 
     // Used when text boxes are out of order (Hebrew/Arabic with embedded LTR text)
     Vector<InlineTextBox*> m_sortedTextBoxes;

Modified: trunk/Source/WebCore/rendering/RenderTreeAsText.cpp (249894 => 249895)


--- trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2019-09-16 14:31:37 UTC (rev 249895)
@@ -202,8 +202,8 @@
         // many test results.
         const RenderText& text = downcast<RenderText>(o);
         r = IntRect(text.firstRunLocation(), text.linesBoundingBox().size());
-        auto textBoxes = LineLayoutInterface::textBoxes(text);
-        if (textBoxes.begin() == textBoxes.end())
+        LineLayoutInterface::Provider lineLayoutProvider;
+        if (!lineLayoutProvider.firstTextBoxFor(text))
             adjustForTableCells = false;
     } else if (o.isBR()) {
         const RenderLineBreak& br = downcast<RenderLineBreak>(o);
@@ -549,8 +549,9 @@
     TextStream::IndentScope indentScope(ts);
 
     if (is<RenderText>(o)) {
+        LineLayoutInterface::Provider lineLayoutProvider;
         auto& text = downcast<RenderText>(o);
-        for (auto textBox : LineLayoutInterface::textBoxes(text)) {
+        for (auto& textBox : lineLayoutProvider.textBoxRangeFor(text)) {
             ts << indent;
             writeTextBox(ts, text, textBox);
         }

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp (249894 => 249895)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp	2019-09-16 14:31:37 UTC (rev 249895)
@@ -113,7 +113,7 @@
 }
 
 RunResolver::Iterator::Iterator(const RunResolver& resolver, unsigned runIndex, unsigned lineIndex)
-    : m_resolver(resolver)
+    : m_resolver(&resolver)
     , m_runIndex(runIndex)
     , m_lineIndex(lineIndex)
 {
@@ -129,8 +129,8 @@
 
 RunResolver::Iterator& RunResolver::Iterator::advanceLines(unsigned lineCount)
 {
-    unsigned runCount = m_resolver.m_layout.runCount();
-    if (runCount == m_resolver.m_layout.lineCount()) {
+    unsigned runCount = resolver().m_layout.runCount();
+    if (runCount == resolver().m_layout.lineCount()) {
         m_runIndex = std::min(runCount, m_runIndex + lineCount);
         m_lineIndex = m_runIndex;
         return *this;

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h (249894 => 249895)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h	2019-09-16 14:31:37 UTC (rev 249895)
@@ -94,10 +94,10 @@
         unsigned lineIndex() const { return m_lineIndex; }
         Iterator& advance();
         Iterator& advanceLines(unsigned);
-        const RunResolver& resolver() const { return m_resolver; }
-        bool inQuirksMode() const { return m_resolver.m_inQuirksMode; }
+        const RunResolver& resolver() const { return *m_resolver; }
+        bool inQuirksMode() const { return resolver().m_inQuirksMode; }
 
-        const RunResolver& m_resolver;
+        const RunResolver* m_resolver;
         unsigned m_runIndex;
         unsigned m_lineIndex;
     };
@@ -238,7 +238,7 @@
 
 inline bool RunResolver::Iterator::operator==(const Iterator& other) const
 {
-    ASSERT(&m_resolver == &other.m_resolver);
+    ASSERT(m_resolver == other.m_resolver);
     return m_runIndex == other.m_runIndex;
 }
 
@@ -254,7 +254,7 @@
 
 inline const SimpleLineLayout::Run& RunResolver::Iterator::simpleRun() const
 {
-    return m_resolver.m_layout.runAt(m_runIndex);
+    return resolver().m_layout.runAt(m_runIndex);
 }
 
 inline RunResolver::Iterator RunResolver::begin() const

Modified: trunk/Source/WebCore/rendering/line/LineLayoutInterfaceTextBoxes.cpp (249894 => 249895)


--- trunk/Source/WebCore/rendering/line/LineLayoutInterfaceTextBoxes.cpp	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/rendering/line/LineLayoutInterfaceTextBoxes.cpp	2019-09-16 14:31:37 UTC (rev 249895)
@@ -35,8 +35,8 @@
 
 FloatRect TextBox::rect() const
 {
-    auto simple = [](const SimpleLineLayout::RunResolver::Iterator simpleLineIterator) {
-        return (*simpleLineIterator).rect();
+    auto simple = [](const TextBoxIterator::SimplePath& path) {
+        return (*path.iterator).rect();
     };
 
     auto complex = [](const InlineTextBox* inlineTextBox) {
@@ -43,13 +43,13 @@
         return inlineTextBox->frameRect();
     };
 
-    return WTF::switchOn(m_iterator.m_pathVariant, simple, complex);
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
 }
 
 FloatRect TextBox::logicalRect() const
 {
-    auto simple = [](const SimpleLineLayout::RunResolver::Iterator simpleLineIterator) {
-        return (*simpleLineIterator).rect();
+    auto simple = [](const TextBoxIterator::SimplePath& path) {
+        return (*path.iterator).rect();
     };
 
     auto complex = [](const InlineTextBox* inlineTextBox) {
@@ -56,13 +56,13 @@
         return inlineTextBox->logicalFrameRect();
     };
 
-    return WTF::switchOn(m_iterator.m_pathVariant, simple, complex);
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
 }
 
 bool TextBox::hasHyphen() const
 {
-    auto simple = [](const SimpleLineLayout::RunResolver::Iterator simpleLineIterator) {
-        return (*simpleLineIterator).hasHyphen();
+    auto simple = [](const TextBoxIterator::SimplePath& path) {
+        return (*path.iterator).hasHyphen();
     };
 
     auto complex = [](const InlineTextBox* inlineTextBox) {
@@ -69,12 +69,12 @@
         return inlineTextBox->hasHyphen();
     };
 
-    return WTF::switchOn(m_iterator.m_pathVariant, simple, complex);
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
 }
 
 bool TextBox::isLeftToRightDirection() const
 {
-    auto simple = [](const SimpleLineLayout::RunResolver::Iterator) {
+    auto simple = [](const TextBoxIterator::SimplePath&) {
         return true;
     };
 
@@ -82,12 +82,12 @@
         return inlineTextBox->isLeftToRightDirection();
     };
 
-    return WTF::switchOn(m_iterator.m_pathVariant, simple, complex);
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
 }
 
 bool TextBox::dirOverride() const
 {
-    auto simple = [](const SimpleLineLayout::RunResolver::Iterator) {
+    auto simple = [](const TextBoxIterator::SimplePath&) {
         return false;
     };
 
@@ -95,13 +95,13 @@
         return inlineTextBox->dirOverride();
     };
 
-    return WTF::switchOn(m_iterator.m_pathVariant, simple, complex);
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
 }
 
 StringView TextBox::text() const
 {
-    auto simple = [](const SimpleLineLayout::RunResolver::Iterator simpleLineIterator) {
-        return (*simpleLineIterator).text();
+    auto simple = [](const TextBoxIterator::SimplePath& path) {
+        return (*path.iterator).text();
     };
 
     auto complex = [](const InlineTextBox* inlineTextBox) {
@@ -108,23 +108,67 @@
         return StringView(inlineTextBox->renderer().text()).substring(inlineTextBox->start(), inlineTextBox->len());
     };
 
-    return WTF::switchOn(m_iterator.m_pathVariant, simple, complex);
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
 }
 
+unsigned TextBox::localStartOffset() const
+{
+    auto simple = [](const TextBoxIterator::SimplePath& path) {
+        return (*path.iterator).localStart();
+    };
+
+    auto complex = [](const InlineTextBox* inlineTextBox) {
+        return inlineTextBox->start();
+    };
+
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+unsigned TextBox::localEndOffset() const
+{
+    auto simple = [](const TextBoxIterator::SimplePath& path) {
+        return (*path.iterator).localEnd();
+    };
+
+    auto complex = [](const InlineTextBox* inlineTextBox) {
+        return inlineTextBox->end();
+    };
+
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+unsigned TextBox::length() const
+{
+    auto simple = [](const TextBoxIterator::SimplePath& path) {
+        return (*path.iterator).end() - (*path.iterator).start();
+    };
+
+    auto complex = [](const InlineTextBox* inlineTextBox) {
+        return inlineTextBox->len();
+    };
+
+    return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+inline const TextBoxIterator& TextBox::iterator() const
+{
+    return static_cast<const TextBoxIterator&>(*this);
+}
+
 TextBoxIterator::TextBoxIterator(const InlineTextBox* inlineTextBox)
     : m_pathVariant(inlineTextBox)
 {
 }
 
-TextBoxIterator::TextBoxIterator(SimpleLineLayout::RunResolver::Iterator simpleLineIterator)
-    : m_pathVariant(simpleLineIterator)
+TextBoxIterator::TextBoxIterator(SimpleLineLayout::RunResolver::Iterator iterator, SimpleLineLayout::RunResolver::Iterator end)
+    : m_pathVariant(TextBoxIterator::SimplePath { iterator, end })
 {
 }
 
 TextBoxIterator& TextBoxIterator::traverseNext()
 {
-    auto simple = [](SimpleLineLayout::RunResolver::Iterator& simpleLineIterator) {
-        ++simpleLineIterator;
+    auto simple = [](TextBoxIterator::SimplePath& path) {
+        ++path.iterator;
     };
 
     auto complex = [](const InlineTextBox*& inlineTextBox) {
@@ -141,8 +185,8 @@
     if (m_pathVariant.index() != other.m_pathVariant.index())
         return false;
 
-    auto simple = [&](const SimpleLineLayout::RunResolver::Iterator simpleLineIterator) {
-        return simpleLineIterator == WTF::get<SimpleLineLayout::RunResolver::Iterator>(other.m_pathVariant);
+    auto simple = [&](const TextBoxIterator::SimplePath& path) {
+        return path.iterator == WTF::get<TextBoxIterator::SimplePath>(other.m_pathVariant).iterator;
     };
 
     auto complex = [&](const InlineTextBox* inlineTextBox) {
@@ -152,32 +196,48 @@
     return WTF::switchOn(m_pathVariant, simple, complex);
 }
 
-static Optional<SimpleLineLayout::RunResolver> simpleLineRunResolverForText(const RenderText& text)
+bool TextBoxIterator::atEnd() const
 {
-    if (!text.simpleLineLayout())
-        return WTF::nullopt;
-    return SimpleLineLayout::runResolver(downcast<const RenderBlockFlow>(*text.parent()), *text.simpleLineLayout());
+    auto simple = [&](const TextBoxIterator::SimplePath& path) {
+        return path.iterator == path.end;
+    };
+
+    auto complex = [&](const InlineTextBox* inlineTextBox) {
+        return !inlineTextBox;
+    };
+
+    return WTF::switchOn(m_pathVariant, simple, complex);
 }
 
-static auto rangeForText(const RenderText& text, Optional<SimpleLineLayout::RunResolver>& simpleLineRunResolver)
+Provider::Provider() = default;
+Provider::~Provider() = default;
+
+TextBoxIterator Provider::firstTextBoxFor(const RenderText& text)
 {
-    if (simpleLineRunResolver) {
-        auto range = simpleLineRunResolver->rangeForRenderer(text);
-        return WTF::makeIteratorRange(TextBoxIterator(range.begin()), TextBoxIterator(range.end()));
+    if (auto* simpleLineLayout = text.simpleLineLayout()) {
+        auto& parent = downcast<const RenderBlockFlow>(*text.parent());
+        auto& resolver = m_simpleLineLayoutResolvers.ensure(&parent, [&] {
+            return makeUnique<SimpleLineLayout::RunResolver>(parent, *simpleLineLayout);
+        }).iterator->value;
+
+        auto range = resolver->rangeForRenderer(text);
+        return { range.begin(), range.end() };
     }
-    return WTF::makeIteratorRange(TextBoxIterator(text.firstTextBox()), TextBoxIterator(nullptr));
+
+    return TextBoxIterator { text.firstTextBox() };
 }
 
-TextBoxRange::TextBoxRange(const RenderText& text)
-    : m_simpleLineRunResolver(simpleLineRunResolverForText(text))
-    , m_range(rangeForText(text, m_simpleLineRunResolver))
+TextBoxRange Provider::textBoxRangeFor(const RenderText& text)
 {
+    return { firstTextBoxFor(text) };
 }
 
-TextBoxRange textBoxes(const RenderText& text)
+TextBoxIterator Provider::iteratorForInlineTextBox(const InlineTextBox* inlineTextBox)
 {
-    return { text };
+    return TextBoxIterator { inlineTextBox };
 }
 
+
+
 }
 }

Modified: trunk/Source/WebCore/rendering/line/LineLayoutInterfaceTextBoxes.h (249894 => 249895)


--- trunk/Source/WebCore/rendering/line/LineLayoutInterfaceTextBoxes.h	2019-09-16 11:37:10 UTC (rev 249894)
+++ trunk/Source/WebCore/rendering/line/LineLayoutInterfaceTextBoxes.h	2019-09-16 14:31:37 UTC (rev 249895)
@@ -27,6 +27,7 @@
 
 #include "FloatRect.h"
 #include "SimpleLineLayoutResolver.h"
+#include <wtf/HashMap.h>
 #include <wtf/IteratorRange.h>
 #include <wtf/Variant.h>
 #include <wtf/text/StringView.h>
@@ -34,6 +35,7 @@
 namespace WebCore {
 
 class InlineTextBox;
+class Provider;
 class RenderText;
 
 namespace LineLayoutInterface {
@@ -41,12 +43,10 @@
 class TextBoxContext;
 class TextBoxIterator;
 
+struct EndIterator { };
+
 class TextBox {
 public:
-    TextBox(const TextBoxIterator& iterator)
-        : m_iterator(iterator)
-    { }
-
     FloatRect rect() const;
     FloatRect logicalRect() const;
 
@@ -56,45 +56,83 @@
 
     StringView text() const;
 
+    // These offsets are relative to the text renderer (not flow).
+    unsigned localStartOffset() const;
+    unsigned localEndOffset() const;
+    unsigned length() const;
+
+protected:
+    TextBox() = default;
+    TextBox(const TextBox&) = default;
+    TextBox(TextBox&&) = default;
+    TextBox& operator=(const TextBox&) = default;
+    TextBox& operator=(TextBox&&) = default;
+
 private:
-    const TextBoxIterator& m_iterator;
+    const TextBoxIterator& iterator() const;
 };
 
-class TextBoxIterator {
+class TextBoxIterator : private TextBox {
 public:
-    TextBoxIterator(const InlineTextBox*);
-    TextBoxIterator(SimpleLineLayout::RunResolver::Iterator);
+    TextBoxIterator() : m_pathVariant(nullptr) { };
+    explicit TextBoxIterator(const InlineTextBox*);
+    TextBoxIterator(SimpleLineLayout::RunResolver::Iterator, SimpleLineLayout::RunResolver::Iterator end);
 
     TextBoxIterator& operator++() { return traverseNext(); }
 
+    explicit operator bool() const { return !atEnd(); }
+
     bool operator==(const TextBoxIterator&) const;
     bool operator!=(const TextBoxIterator& other) const { return !(*this == other); }
 
-    TextBox operator*() const { return { *this }; }
+    bool operator==(EndIterator) const { return atEnd(); }
+    bool operator!=(EndIterator) const { return !atEnd(); }
 
+    const TextBox& operator*() const { return *this; }
+    const TextBox* operator->() const { return this; }
+
+    bool atEnd() const;
+
 private:
     friend class TextBox;
 
     TextBoxIterator& traverseNext();
 
-    Variant<SimpleLineLayout::RunResolver::Iterator, const InlineTextBox*> m_pathVariant;
+    struct SimplePath {
+        SimpleLineLayout::RunResolver::Iterator iterator;
+        SimpleLineLayout::RunResolver::Iterator end;
+    };
+    Variant<SimplePath, const InlineTextBox*> m_pathVariant;
 };
 
 class TextBoxRange {
 public:
-    TextBoxRange(const RenderText&);
+    TextBoxRange(TextBoxIterator begin)
+        : m_begin(begin)
+    {
+    }
 
-    TextBoxIterator begin() const { return m_range.begin(); }
-    TextBoxIterator end() const { return m_range.end(); }
+    TextBoxIterator begin() const { return m_begin; }
+    EndIterator end() const { return { }; }
 
 private:
-    friend class TextBoxIterator;
+    TextBoxIterator m_begin;
+};
 
-    Optional<SimpleLineLayout::RunResolver> m_simpleLineRunResolver;
-    WTF::IteratorRange<TextBoxIterator> m_range;
+class Provider {
+public:
+    Provider();
+    ~Provider();
+
+    TextBoxIterator firstTextBoxFor(const RenderText&);
+    TextBoxRange textBoxRangeFor(const RenderText&);
+
+    // FIXME: Remove.
+    TextBoxIterator iteratorForInlineTextBox(const InlineTextBox*);
+
+private:
+    HashMap<const RenderBlockFlow*, std::unique_ptr<SimpleLineLayout::RunResolver>> m_simpleLineLayoutResolvers;
 };
 
-TextBoxRange textBoxes(const RenderText&);
-
 }
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to