Simple line layout: Do not use invalid m_lastNonWhitespaceFragment while removing...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Mar 2017 21:02:15 +0000 (21:02 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Mar 2017 21:02:15 +0000 (21:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169288
rdar://problem/30576976

Reviewed by Antti Koivisto.

Source/WebCore:

When the current line has nothing but whitespace, m_lastNonWhitespaceFragment is invalid so
we should not use the start/end values to decide how many characters we need to revert.
This patch makes m_lastNonWhitespaceFragment optional. When it's invalid we just remove
all the runs from the current line since they are all considered whitespace runs.

Test: fast/text/simple-line-layout-line-is-all-whitespace.html

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::revertAllRunsOnCurrentLine):
(WebCore::SimpleLineLayout::LineState::removeTrailingWhitespace):

LayoutTests:

* fast/text/simple-line-layout-line-is-all-whitespace-expected.txt: Added.
* fast/text/simple-line-layout-line-is-all-whitespace.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213534 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/text/simple-line-layout-line-is-all-whitespace-expected.txt [new file with mode: 0644]
LayoutTests/fast/text/simple-line-layout-line-is-all-whitespace.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/SimpleLineLayout.cpp

index b00f857..3419c2a 100644 (file)
@@ -1,3 +1,14 @@
+2017-03-07  Zalan Bujtas  <zalan@apple.com>
+
+        Simple line layout: Do not use invalid m_lastNonWhitespaceFragment while removing trailing whitespace.
+        https://bugs.webkit.org/show_bug.cgi?id=169288
+        rdar://problem/30576976
+
+        Reviewed by Antti Koivisto.
+
+        * fast/text/simple-line-layout-line-is-all-whitespace-expected.txt: Added.
+        * fast/text/simple-line-layout-line-is-all-whitespace.html: Added.
+
 2017-03-07  Antoine Quint  <graouts@apple.com>
 
         Flaky Test: media/modern-media-controls/tracks-support/tracks-support-click-track-in-panel.html
diff --git a/LayoutTests/fast/text/simple-line-layout-line-is-all-whitespace-expected.txt b/LayoutTests/fast/text/simple-line-layout-line-is-all-whitespace-expected.txt
new file mode 100644 (file)
index 0000000..83fb6d8
--- /dev/null
@@ -0,0 +1,15 @@
+PASS if no crash.
+f bar f bar foo bar foo bar
+f bar
+foobar foobar foobar
+bar
+f
+
+
+  
+fo
+o
+f bar foo foobar foobar fo
+o
+
+
diff --git a/LayoutTests/fast/text/simple-line-layout-line-is-all-whitespace.html b/LayoutTests/fast/text/simple-line-layout-line-is-all-whitespace.html
new file mode 100644 (file)
index 0000000..5ab951f
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<pre>
+PASS if no crash.
+f bar f bar foo bar foo bar
+f bar
+foobar foobar foobar
+f bar foo foobar foobar foobar
+f
+
+foo
+  <script>
+if (window.testRunner)
+  testRunner.dumpAsText();
+document.designMode = "on";
+document.execCommand("SelectAll");
+document.execCommand("JustifyRight");
+document.execCommand("JustifyLeft");
+</script>
index aa72c66..79155da 100644 (file)
@@ -1,3 +1,22 @@
+2017-03-07  Zalan Bujtas  <zalan@apple.com>
+
+        Simple line layout: Do not use invalid m_lastNonWhitespaceFragment while removing trailing whitespace.
+        https://bugs.webkit.org/show_bug.cgi?id=169288
+        rdar://problem/30576976
+
+        Reviewed by Antti Koivisto.
+
+        When the current line has nothing but whitespace, m_lastNonWhitespaceFragment is invalid so
+        we should not use the start/end values to decide how many characters we need to revert.
+        This patch makes m_lastNonWhitespaceFragment optional. When it's invalid we just remove
+        all the runs from the current line since they are all considered whitespace runs.
+
+        Test: fast/text/simple-line-layout-line-is-all-whitespace.html
+
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::revertAllRunsOnCurrentLine):
+        (WebCore::SimpleLineLayout::LineState::removeTrailingWhitespace):
+
 2017-03-07  Alex Christensen  <achristensen@webkit.org>
 
         [Content Extensions] Rename "Domain" to "Condition" where appropriate
index 5421153..58319af 100644 (file)
@@ -344,6 +344,12 @@ static float computeLineLeft(ETextAlign textAlign, float availableWidth, float c
     return 0;
 }
 
+static void revertAllRunsOnCurrentLine(Layout::RunVector& runs)
+{
+    while (!runs.isEmpty() && !runs.last().isEndOfLine)
+        runs.removeLast();
+}
+
 static void revertRuns(Layout::RunVector& runs, unsigned positionToRevertTo, float width)
 {
     while (runs.size()) {
@@ -489,11 +495,26 @@ public:
 
     void removeTrailingWhitespace(Layout::RunVector& runs)
     {
-        if (m_lastFragment.type() != TextFragmentIterator::TextFragment::Whitespace || m_lastFragment.end() == m_lastNonWhitespaceFragment.end())
+        if (m_lastFragment.type() != TextFragmentIterator::TextFragment::Whitespace)
             return;
-        revertRuns(runs, m_lastNonWhitespaceFragment.end(), m_trailingWhitespaceWidth);
-        m_runsWidth -= m_trailingWhitespaceWidth;
-        m_lastFragment = m_lastNonWhitespaceFragment;
+        if (m_lastNonWhitespaceFragment) {
+            auto needsReverting = m_lastNonWhitespaceFragment->end() != m_lastFragment.end();
+            // Trailing whitespace fragment might actually have zero length.
+            ASSERT(needsReverting || !m_trailingWhitespaceWidth);
+            if (needsReverting) {
+                revertRuns(runs, m_lastNonWhitespaceFragment->end(), m_trailingWhitespaceWidth);
+                m_runsWidth -= m_trailingWhitespaceWidth;
+            }
+            m_trailingWhitespaceWidth = 0;
+            m_lastFragment = *m_lastNonWhitespaceFragment;
+            return;
+        }
+        // This line is all whitespace.
+        revertAllRunsOnCurrentLine(runs);
+        m_runsWidth = 0;
+        m_trailingWhitespaceWidth = 0;
+        // FIXME: Make m_lastFragment optional.
+        m_lastFragment = TextFragmentIterator::TextFragment();
     }
 
 private:
@@ -508,7 +529,7 @@ private:
     float m_runsWidth { 0 };
     TextFragmentIterator::TextFragment m_overflowedFragment;
     TextFragmentIterator::TextFragment m_lastFragment;
-    TextFragmentIterator::TextFragment m_lastNonWhitespaceFragment;
+    std::optional<TextFragmentIterator::TextFragment> m_lastNonWhitespaceFragment;
     TextFragmentIterator::TextFragment m_lastCompleteFragment;
     float m_uncompletedWidth { 0 };
     float m_trailingWhitespaceWidth { 0 }; // Use this to remove trailing whitespace without re-mesuring the text.