Title: [214816] releases/WebKitGTK/webkit-2.16/Source/WebCore
Revision
214816
Author
carlo...@webkit.org
Date
2017-04-03 10:32:26 -0700 (Mon, 03 Apr 2017)

Log Message

Merge r214726 - Long Arabic text in ContentEditable with css white-space=pre hangs Safari
https://bugs.webkit.org/show_bug.cgi?id=170245

Reviewed by Myles C. Maxfield.

While searching for mid-word break, we measure the text by codepoints in a loop until the accumulated width > available width.
When we see that the accumulated width for the individual codepoints overflows, we join the codepoints and re-measure them.
These 2 widths could be considerably different for number of reasons (ligatures is a prime example). When we figure that
the run still fits, we go back to the main loop (since we are not supposed to wrap the line here) and take the next codepoint.
However this time we start the measurement from the last whitespace, so we end up remeasuring a potentially long chuck of text
until we hit the wrapping point. This is way too expensive.
This patch changes the logic so that we just go back to measuring individual codepoints until we hit the constrain again.

Covered by existing tests.

* rendering/line/BreakingContext.h:
(WebCore::BreakingContext::handleText): canUseSimpleFontCodePath() is just to mitigate the potential risk of regression and
complex text is more likely to fall into this category.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog (214815 => 214816)


--- releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog	2017-04-03 17:29:09 UTC (rev 214815)
+++ releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog	2017-04-03 17:32:26 UTC (rev 214816)
@@ -1,3 +1,24 @@
+2017-04-01  Zalan Bujtas  <za...@apple.com>
+
+        Long Arabic text in ContentEditable with css white-space=pre hangs Safari
+        https://bugs.webkit.org/show_bug.cgi?id=170245
+
+        Reviewed by Myles C. Maxfield.
+
+        While searching for mid-word break, we measure the text by codepoints in a loop until the accumulated width > available width.
+        When we see that the accumulated width for the individual codepoints overflows, we join the codepoints and re-measure them.
+        These 2 widths could be considerably different for number of reasons (ligatures is a prime example). When we figure that
+        the run still fits, we go back to the main loop (since we are not supposed to wrap the line here) and take the next codepoint.
+        However this time we start the measurement from the last whitespace, so we end up remeasuring a potentially long chuck of text
+        until we hit the wrapping point. This is way too expensive.
+        This patch changes the logic so that we just go back to measuring individual codepoints until we hit the constrain again.  
+
+        Covered by existing tests.
+
+        * rendering/line/BreakingContext.h:
+        (WebCore::BreakingContext::handleText): canUseSimpleFontCodePath() is just to mitigate the potential risk of regression and
+        complex text is more likely to fall into this category. 
+
 2017-03-30  Eric Carlson  <eric.carl...@apple.com>
 
         [Crash] WebCore::AudioBuffer::AudioBuffer don't checking illegal value

Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/rendering/line/BreakingContext.h (214815 => 214816)


--- releases/WebKitGTK/webkit-2.16/Source/WebCore/rendering/line/BreakingContext.h	2017-04-03 17:29:09 UTC (rev 214815)
+++ releases/WebKitGTK/webkit-2.16/Source/WebCore/rendering/line/BreakingContext.h	2017-04-03 17:32:26 UTC (rev 214816)
@@ -794,7 +794,8 @@
     float lastSpaceWordSpacing = 0;
     float wordSpacingForWordMeasurement = 0;
 
-    float wrapW = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, true);
+    float wrapWidthOffset = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, true);
+    float wrapW = wrapWidthOffset;
     float charWidth = 0;
     bool breakNBSP = m_autoWrap && m_currentStyle->nbspMode() == SPACE;
     // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
@@ -1028,7 +1029,8 @@
 
             if (m_autoWrap && betweenWords) {
                 commitLineBreakAtCurrentWidth(renderObject, m_current.offset(), m_current.nextBreakablePosition());
-                wrapW = 0;
+                wrapWidthOffset = 0;
+                wrapW = wrapWidthOffset;
                 // Auto-wrapping text should not wrap in the middle of a word once it has had an
                 // opportunity to break after a word.
                 breakWords = false;
@@ -1060,7 +1062,12 @@
                     m_trailingObjects.updateWhitespaceCollapsingTransitionsForTrailingBoxes(m_lineWhitespaceCollapsingState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
                 }
             }
-            
+            // Measuring the width of complex text character-by-character, rather than measuring it all together,
+            // could produce considerably different width values.
+            if (!renderText.canUseSimpleFontCodePath() && midWordBreak && m_width.fitsOnLine()) {
+                midWordBreak = false;
+                wrapW = wrapWidthOffset + additionalTempWidth;
+            }
             isLineEmpty = m_lineInfo.isEmpty();
         } else {
             if (m_ignoringSpaces) {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to