<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[214816] releases/WebKitGTK/webkit-2.16/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/214816">214816</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2017-04-03 10:32:26 -0700 (Mon, 03 Apr 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/214726">r214726</a> - 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 &gt; 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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit216SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit216SourceWebCorerenderinglineBreakingContexth">releases/WebKitGTK/webkit-2.16/Source/WebCore/rendering/line/BreakingContext.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit216SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/ChangeLog (214815 => 214816)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2017-04-01  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        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 &gt; 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. 
+
</ins><span class="cx"> 2017-03-30  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Crash] WebCore::AudioBuffer::AudioBuffer don't checking illegal value
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit216SourceWebCorerenderinglineBreakingContexth"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.16/Source/WebCore/rendering/line/BreakingContext.h (214815 => 214816)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -794,7 +794,8 @@
</span><span class="cx">     float lastSpaceWordSpacing = 0;
</span><span class="cx">     float wordSpacingForWordMeasurement = 0;
</span><span class="cx"> 
</span><del>-    float wrapW = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, true);
</del><ins>+    float wrapWidthOffset = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, true);
+    float wrapW = wrapWidthOffset;
</ins><span class="cx">     float charWidth = 0;
</span><span class="cx">     bool breakNBSP = m_autoWrap &amp;&amp; m_currentStyle-&gt;nbspMode() == SPACE;
</span><span class="cx">     // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
</span><span class="lines">@@ -1028,7 +1029,8 @@
</span><span class="cx"> 
</span><span class="cx">             if (m_autoWrap &amp;&amp; betweenWords) {
</span><span class="cx">                 commitLineBreakAtCurrentWidth(renderObject, m_current.offset(), m_current.nextBreakablePosition());
</span><del>-                wrapW = 0;
</del><ins>+                wrapWidthOffset = 0;
+                wrapW = wrapWidthOffset;
</ins><span class="cx">                 // Auto-wrapping text should not wrap in the middle of a word once it has had an
</span><span class="cx">                 // opportunity to break after a word.
</span><span class="cx">                 breakWords = false;
</span><span class="lines">@@ -1060,7 +1062,12 @@
</span><span class="cx">                     m_trailingObjects.updateWhitespaceCollapsingTransitionsForTrailingBoxes(m_lineWhitespaceCollapsingState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
</span><span class="cx">                 }
</span><span class="cx">             }
</span><del>-            
</del><ins>+            // Measuring the width of complex text character-by-character, rather than measuring it all together,
+            // could produce considerably different width values.
+            if (!renderText.canUseSimpleFontCodePath() &amp;&amp; midWordBreak &amp;&amp; m_width.fitsOnLine()) {
+                midWordBreak = false;
+                wrapW = wrapWidthOffset + additionalTempWidth;
+            }
</ins><span class="cx">             isLineEmpty = m_lineInfo.isEmpty();
</span><span class="cx">         } else {
</span><span class="cx">             if (m_ignoringSpaces) {
</span></span></pre>
</div>
</div>

</body>
</html>