<!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>[211738] trunk/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/211738">211738</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2017-02-06 11:06:39 -0800 (Mon, 06 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Simple line layout: Use simplified text measuring when possible.
https://bugs.webkit.org/show_bug.cgi?id=167843
&lt;rdar://problem/30364907&gt;

Reviewed by Antti Koivisto.

This patch adds a simplified version of text width measuring.
Certain type of text runs (no spacing etc) only require a subset of what we
currently do in FontCascade::width().

* platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::widthForSimpleText):
* platform/graphics/FontCascade.h:
* platform/graphics/WidthCache.h:
(WebCore::WidthCache::add):
(WebCore::WidthCache::addSlowCase):
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::advanceInternal):
* rendering/RenderText.cpp:
(WebCore::RenderText::styleDidChange):
(WebCore::RenderText::setRenderedText):
(WebCore::RenderText::computeCanUseSimplifiedTextMeasuring):
* rendering/RenderText.h:
(WebCore::RenderText::canUseSimplifiedTextMeasuring):
* rendering/SimpleLineLayoutFlowContents.cpp:
(WebCore::SimpleLineLayout::initializeSegments):
* rendering/SimpleLineLayoutFlowContents.h:
* rendering/SimpleLineLayoutTextFragmentIterator.cpp:
(WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style):
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragmentIterator):
(WebCore::SimpleLineLayout::TextFragmentIterator::textWidth):
* rendering/SimpleLineLayoutTextFragmentIterator.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontCascadecpp">trunk/Source/WebCore/platform/graphics/FontCascade.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontCascadeh">trunk/Source/WebCore/platform/graphics/FontCascade.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsWidthCacheh">trunk/Source/WebCore/platform/graphics/WidthCache.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsWidthIteratorcpp">trunk/Source/WebCore/platform/graphics/WidthIterator.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextcpp">trunk/Source/WebCore/rendering/RenderText.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTexth">trunk/Source/WebCore/rendering/RenderText.h</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutFlowContentscpp">trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutFlowContentsh">trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorcpp">trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorh">trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/ChangeLog        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2017-02-06  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Simple line layout: Use simplified text measuring when possible.
+        https://bugs.webkit.org/show_bug.cgi?id=167843
+        &lt;rdar://problem/30364907&gt;
+
+        Reviewed by Antti Koivisto.
+
+        This patch adds a simplified version of text width measuring.
+        Certain type of text runs (no spacing etc) only require a subset of what we
+        currently do in FontCascade::width().
+
+        * platform/graphics/FontCascade.cpp:
+        (WebCore::FontCascade::widthForSimpleText):
+        * platform/graphics/FontCascade.h:
+        * platform/graphics/WidthCache.h:
+        (WebCore::WidthCache::add):
+        (WebCore::WidthCache::addSlowCase):
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::advanceInternal):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::styleDidChange):
+        (WebCore::RenderText::setRenderedText):
+        (WebCore::RenderText::computeCanUseSimplifiedTextMeasuring):
+        * rendering/RenderText.h:
+        (WebCore::RenderText::canUseSimplifiedTextMeasuring):
+        * rendering/SimpleLineLayoutFlowContents.cpp:
+        (WebCore::SimpleLineLayout::initializeSegments):
+        * rendering/SimpleLineLayoutFlowContents.h:
+        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragmentIterator):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::textWidth):
+        * rendering/SimpleLineLayoutTextFragmentIterator.h:
+
</ins><span class="cx"> 2017-02-06  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Resource usage overlay should ignore mouse events outside bounds by default
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontCascadecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -33,6 +33,9 @@
</span><span class="cx"> #include &quot;SurrogatePairAwareTextIterator.h&quot;
</span><span class="cx"> #include &quot;TextRun.h&quot;
</span><span class="cx"> #include &quot;WidthIterator.h&quot;
</span><ins>+#if USE(CAIRO)
+#include &lt;cairo.h&gt;
+#endif
</ins><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="lines">@@ -377,6 +380,37 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+float FontCascade::widthForSimpleText(StringView text) const
+{
+    ASSERT(codePath(TextRun(text)) != FontCascade::Complex);
+    float* cacheEntry = m_fonts-&gt;widthCache().add(text, std::numeric_limits&lt;float&gt;::quiet_NaN());
+    if (cacheEntry &amp;&amp; !std::isnan(*cacheEntry))
+        return *cacheEntry;
+
+    Vector&lt;GlyphBufferGlyph, 16&gt; glyphs;
+    Vector&lt;GlyphBufferAdvance, 16&gt; advances;
+    auto&amp; font = primaryFont();
+    for (unsigned i = 0; i &lt; text.length(); ++i) {
+        auto glyph = glyphDataForCharacter(text[i], false).glyph;
+#if USE(CAIRO)
+        cairo_glyph_t cairoGlyph;
+        cairoGlyph.index = glyph;
+        glyphs.append(cairoGlyph);
+#else
+        glyphs.append(glyph);
+#endif
+        advances.append(FloatSize(font.widthForGlyph(glyph), 0));
+    }
+    font.applyTransforms(&amp;glyphs[0], &amp;advances[0], glyphs.size(), enableKerning(), requiresShaping());
+    float runWidth = 0;
+    for (auto&amp; advance : advances)
+        runWidth += advance.width();
+
+    if (cacheEntry)
+        *cacheEntry = runWidth;
+    return runWidth;
+}
+
</ins><span class="cx"> GlyphData FontCascade::glyphDataForCharacter(UChar32 c, bool mirror, FontVariant variant) const
</span><span class="cx"> {
</span><span class="cx">     if (variant == AutoVariant) {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontCascadeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontCascade.h (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontCascade.h        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.h        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -139,6 +139,7 @@
</span><span class="cx">     DashArray dashesForIntersectionsWithRect(const TextRun&amp;, const FloatPoint&amp; textOrigin, const FloatRect&amp; lineExtents) const;
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT float width(const TextRun&amp;, HashSet&lt;const Font*&gt;* fallbackFonts = 0, GlyphOverflow* = 0) const;
</span><ins>+    float widthForSimpleText(StringView text) const;
</ins><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;TextLayout, TextLayoutDeleter&gt; createLayout(RenderText&amp;, float xPos, bool collapseWhiteSpace) const;
</span><span class="cx">     static float width(TextLayout&amp;, unsigned from, unsigned len, HashSet&lt;const Font*&gt;* fallbackFonts = 0);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsWidthCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/WidthCache.h (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/WidthCache.h        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/platform/graphics/WidthCache.h        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -119,6 +119,21 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    float* add(StringView text, float entry)
+    {
+        if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
+            return nullptr;
+
+        if (static_cast&lt;unsigned&gt;(text.length()) &gt; SmallStringKey::capacity())
+            return nullptr;
+
+        if (m_countdown &gt; 0) {
+            --m_countdown;
+            return nullptr;
+        }
+        return addSlowCase(text, entry);
+    }
+
</ins><span class="cx">     float* add(const TextRun&amp; run, float entry, bool hasKerningOrLigatures, bool hasWordSpacingOrLetterSpacing, GlyphOverflow* glyphOverflow)
</span><span class="cx">     {
</span><span class="cx">         if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
</span><span class="lines">@@ -143,7 +158,7 @@
</span><span class="cx">             return 0;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        return addSlowCase(run, entry);
</del><ins>+        return addSlowCase(run.text(), entry);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void clear()
</span><span class="lines">@@ -153,23 +168,24 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    float* addSlowCase(const TextRun&amp; run, float entry)
</del><ins>+
+    float* addSlowCase(StringView text, float entry)
</ins><span class="cx">     {
</span><del>-        int length = run.length();
</del><ins>+        int length = text.length();
</ins><span class="cx">         bool isNewEntry;
</span><del>-        float *value;
</del><ins>+        float* value;
</ins><span class="cx">         if (length == 1) {
</span><del>-            SingleCharMap::AddResult addResult = m_singleCharMap.add(run[0], entry);
</del><ins>+            SingleCharMap::AddResult addResult = m_singleCharMap.fastAdd(text[0], entry);
</ins><span class="cx">             isNewEntry = addResult.isNewEntry;
</span><span class="cx">             value = &amp;addResult.iterator-&gt;value;
</span><span class="cx">         } else {
</span><span class="cx">             SmallStringKey smallStringKey;
</span><del>-            if (run.is8Bit())
-                smallStringKey = SmallStringKey(run.characters8(), length);
</del><ins>+            if (text.is8Bit())
+                smallStringKey = SmallStringKey(text.characters8(), length);
</ins><span class="cx">             else
</span><del>-                smallStringKey = SmallStringKey(run.characters16(), length);
</del><ins>+                smallStringKey = SmallStringKey(text.characters16(), length);
</ins><span class="cx"> 
</span><del>-            Map::AddResult addResult = m_map.add(smallStringKey, entry);
</del><ins>+            Map::AddResult addResult = m_map.fastAdd(smallStringKey, entry);
</ins><span class="cx">             isNewEntry = addResult.isNewEntry;
</span><span class="cx">             value = &amp;addResult.iterator-&gt;value;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsWidthIteratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.cpp (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/WidthIterator.cpp        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.cpp        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -172,6 +172,7 @@
</span><span class="cx"> template &lt;typename TextIterator&gt;
</span><span class="cx"> inline unsigned WidthIterator::advanceInternal(TextIterator&amp; textIterator, GlyphBuffer* glyphBuffer)
</span><span class="cx"> {
</span><ins>+    // The core logic here needs to match SimpleLineLayout::widthForSimpleText()
</ins><span class="cx">     bool rtl = m_run.rtl();
</span><span class="cx">     bool hasExtraSpacing = (m_font-&gt;letterSpacing() || m_font-&gt;wordSpacing() || m_expansion) &amp;&amp; !m_run.spacingDisabled();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderText.cpp (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderText.cpp        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/rendering/RenderText.cpp        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -257,6 +257,8 @@
</span><span class="cx">     if (!oldStyle) {
</span><span class="cx">         m_useBackslashAsYenSymbol = computeUseBackslashAsYenSymbol();
</span><span class="cx">         needsResetText = m_useBackslashAsYenSymbol;
</span><ins>+        // It should really be computed in the c'tor, but during construction we don't have parent yet -and RenderText style == parent()-&gt;style()
+        m_canUseSimplifiedTextMeasuring = computeCanUseSimplifiedTextMeasuring();
</ins><span class="cx">     } else if (oldStyle-&gt;fontCascade().useBackslashAsYenSymbol() != newStyle.fontCascade().useBackslashAsYenSymbol()) {
</span><span class="cx">         m_useBackslashAsYenSymbol = computeUseBackslashAsYenSymbol();
</span><span class="cx">         needsResetText = true;
</span><span class="lines">@@ -1179,7 +1181,8 @@
</span><span class="cx"> 
</span><span class="cx">     m_isAllASCII = m_text.containsOnlyASCII();
</span><span class="cx">     m_canUseSimpleFontCodePath = computeCanUseSimpleFontCodePath();
</span><del>-
</del><ins>+    m_canUseSimplifiedTextMeasuring = computeCanUseSimplifiedTextMeasuring();
+    
</ins><span class="cx">     if (m_text != originalText) {
</span><span class="cx">         originalTextMap().set(this, originalText);
</span><span class="cx">         m_originalTextDiffersFromRendered = true;
</span><span class="lines">@@ -1221,6 +1224,29 @@
</span><span class="cx">         characters[revealedCharactersOffset] = characterToReveal;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool RenderText::computeCanUseSimplifiedTextMeasuring() const
+{
+    if (!m_canUseSimpleFontCodePath)
+        return false;
+    
+    auto&amp; font = style().fontCascade();
+    if (font.wordSpacing() || font.letterSpacing())
+        return false;
+
+    // Additional check on the font codepath.
+    TextRun run(m_text);
+    run.setCharacterScanForCodePath(false);
+    if (font.codePath(run) != FontCascade::Simple)
+        return false;
+
+    auto whitespaceIsCollapsed = style().collapseWhiteSpace();
+    for (unsigned i = 0; i &lt; m_text.length(); ++i) {
+        if ((!whitespaceIsCollapsed &amp;&amp; m_text[i] == '\t') || m_text[i] == noBreakSpace || m_text[i] &gt;= HiraganaLetterSmallA)
+            return false;
+    }
+    return true;
+}
+
</ins><span class="cx"> void RenderText::setText(const String&amp; text, bool force)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!text.isNull());
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderText.h (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderText.h        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/rendering/RenderText.h        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -171,6 +171,8 @@
</span><span class="cx">     LayoutUnit topOfFirstText() const;
</span><span class="cx">     
</span><span class="cx">     bool containsOnlyWhitespace(unsigned from, unsigned len) const;
</span><ins>+    
+    bool canUseSimplifiedTextMeasuring() const { return m_canUseSimplifiedTextMeasuring; }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     virtual void computePreferredLogicalWidths(float leadWidth);
</span><span class="lines">@@ -202,6 +204,7 @@
</span><span class="cx">     void secureText(UChar mask);
</span><span class="cx"> 
</span><span class="cx">     LayoutRect collectSelectionRectsForLineBoxes(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent, Vector&lt;LayoutRect&gt;*);
</span><ins>+    bool computeCanUseSimplifiedTextMeasuring() const;
</ins><span class="cx"> 
</span><span class="cx">     void node() const = delete;
</span><span class="cx">     void container() const = delete; // Use parent() instead.
</span><span class="lines">@@ -223,6 +226,7 @@
</span><span class="cx">     mutable unsigned m_knownToHaveNoOverflowAndNoFallbackFonts : 1;
</span><span class="cx">     unsigned m_useBackslashAsYenSymbol : 1;
</span><span class="cx">     unsigned m_originalTextDiffersFromRendered : 1;
</span><ins>+    unsigned m_canUseSimplifiedTextMeasuring : 1;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(TEXT_AUTOSIZING)
</span><span class="cx">     // FIXME: This should probably be part of the text sizing structures in Document instead. That would save some memory.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutFlowContentscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -47,12 +47,13 @@
</span><span class="cx">         if (is&lt;RenderText&gt;(child)) {
</span><span class="cx">             auto&amp; textChild = downcast&lt;RenderText&gt;(child);
</span><span class="cx">             unsigned textLength = textChild.text()-&gt;length();
</span><del>-            segments.append(FlowContents::Segment { startPosition, startPosition + textLength, textChild.text(), textChild });
</del><ins>+            segments.append(FlowContents::Segment { startPosition, startPosition + textLength, textChild.text(),
+                textChild, textChild.canUseSimplifiedTextMeasuring() });
</ins><span class="cx">             startPosition += textLength;
</span><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="cx">         if (is&lt;RenderLineBreak&gt;(child)) {
</span><del>-            segments.append(FlowContents::Segment { startPosition, startPosition, String(), child });
</del><ins>+            segments.append(FlowContents::Segment { startPosition, startPosition, String(), child, true });
</ins><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="cx">         ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutFlowContentsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx">         unsigned end;
</span><span class="cx">         StringView text;
</span><span class="cx">         const RenderObject&amp; renderer;
</span><ins>+        bool canUseSimplifiedTextMeasuring;
</ins><span class="cx">     };
</span><span class="cx">     const Segment&amp; segmentForRun(unsigned start, unsigned end) const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace SimpleLineLayout {
</span><span class="cx"> 
</span><del>-TextFragmentIterator::Style::Style(const RenderStyle&amp; style)
</del><ins>+TextFragmentIterator::Style::Style(const RenderStyle&amp; style, bool useSimplifiedTextMeasuring)
</ins><span class="cx">     : font(style.fontCascade())
</span><span class="cx">     , textAlign(style.textAlign())
</span><span class="cx">     , collapseWhitespace(style.collapseWhiteSpace())
</span><span class="lines">@@ -44,11 +44,11 @@
</span><span class="cx">     , breakFirstWordOnOverflow(breakAnyWordOnOverflow || (style.breakWords() &amp;&amp; (wrapLines || preserveNewline)))
</span><span class="cx">     , breakNBSP(wrapLines &amp;&amp; style.nbspMode() == SPACE)
</span><span class="cx">     , keepAllWordsForCJK(style.wordBreak() == KeepAllWordBreak)
</span><del>-    , spaceWidth(font.width(TextRun(StringView(&amp;space, 1))))
</del><ins>+    , spaceWidth(useSimplifiedTextMeasuring ? font.widthForSimpleText(StringView(&amp;space, 1)) : font.width(TextRun(StringView(&amp;space, 1))))
</ins><span class="cx">     , wordSpacing(font.wordSpacing())
</span><span class="cx">     , tabWidth(collapseWhitespace ? 0 : style.tabSize())
</span><span class="cx">     , shouldHyphenate(style.hyphens() == HyphensAuto &amp;&amp; canHyphenate(style.locale()))
</span><del>-    , hyphenStringWidth(shouldHyphenate ? font.width(TextRun(style.hyphenString())) : 0)
</del><ins>+    , hyphenStringWidth(shouldHyphenate ? (useSimplifiedTextMeasuring ? font.widthForSimpleText(style.hyphenString()) : font.width(TextRun(style.hyphenString()))) : 0)
</ins><span class="cx">     , hyphenLimitBefore(style.hyphenationLimitBefore() &lt; 0 ? 2 : style.hyphenationLimitBefore())
</span><span class="cx">     , hyphenLimitAfter(style.hyphenationLimitAfter() &lt; 0 ? 2 : style.hyphenationLimitAfter())
</span><span class="cx">     , locale(style.locale())
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx">     : m_flowContents(flow)
</span><span class="cx">     , m_currentSegment(m_flowContents.begin())
</span><span class="cx">     , m_lineBreakIterator(m_currentSegment-&gt;text, flow.style().locale())
</span><del>-    , m_style(flow.style())
</del><ins>+    , m_style(flow.style(), m_currentSegment-&gt;canUseSimplifiedTextMeasuring)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -247,10 +247,15 @@
</span><span class="cx">     bool measureWithEndSpace = m_style.collapseWhitespace &amp;&amp; segmentTo &lt; segment.text.length() &amp;&amp; segment.text[segmentTo] == ' ';
</span><span class="cx">     if (measureWithEndSpace)
</span><span class="cx">         ++segmentTo;
</span><del>-    TextRun run(StringView(segment.text).substring(segmentFrom, segmentTo - segmentFrom), xPosition);
-    if (m_style.tabWidth)
-        run.setTabSize(true, m_style.tabWidth);
-    float width = m_style.font.width(run);
</del><ins>+    float width = 0;
+    if (segment.canUseSimplifiedTextMeasuring)
+        width = m_style.font.widthForSimpleText(StringView(segment.text).substring(segmentFrom, segmentTo - segmentFrom));
+    else {
+        TextRun run(StringView(segment.text).substring(segmentFrom, segmentTo - segmentFrom), xPosition);
+        if (m_style.tabWidth)
+            run.setTabSize(true, m_style.tabWidth);
+        width = m_style.font.width(run);
+    }
</ins><span class="cx">     if (measureWithEndSpace)
</span><span class="cx">         width -= (m_style.spaceWidth + m_style.wordSpacing);
</span><span class="cx">     return std::max&lt;float&gt;(0, width);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutTextFragmentIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h (211737 => 211738)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h        2017-02-06 18:59:19 UTC (rev 211737)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h        2017-02-06 19:06:39 UTC (rev 211738)
</span><span class="lines">@@ -105,7 +105,7 @@
</span><span class="cx">     std::optional&lt;unsigned&gt; lastHyphenPosition(const TextFragmentIterator::TextFragment&amp; run, unsigned beforeIndex) const;
</span><span class="cx"> 
</span><span class="cx">     struct Style {
</span><del>-        explicit Style(const RenderStyle&amp;);
</del><ins>+        explicit Style(const RenderStyle&amp;, bool useSimplifiedTextMeasuring);
</ins><span class="cx"> 
</span><span class="cx">         const FontCascade&amp; font;
</span><span class="cx">         ETextAlign textAlign;
</span></span></pre>
</div>
</div>

</body>
</html>