<!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>[179435] 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/179435">179435</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2015-01-30 19:37:46 -0800 (Fri, 30 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Simple line layout: Make LineState fragment handling simpler.
https://bugs.webkit.org/show_bug.cgi?id=141100

Reviewed by Andreas Kling.

New fragments are appeneded to the Run's last entry
instead of accumulating them until after a new run is required.
(whitespace collapse or line end)
LineState::appendFragment manages whitespace collapsing now.
This makes createLineRuns() logic lighter and no need to &quot;flush&quot;
the LineState when the line ends.

No change in functionality.

* rendering/SimpleLineLayout.cpp: Make LineState members private and introduce getters.
(WebCore::SimpleLineLayout::LineState::setAvailableWidth):
(WebCore::SimpleLineLayout::LineState::setLogicalLeftOffset):
(WebCore::SimpleLineLayout::LineState::setOverflowedFragment):
(WebCore::SimpleLineLayout::LineState::availableWidth):
(WebCore::SimpleLineLayout::LineState::logicalLeftOffset):
(WebCore::SimpleLineLayout::LineState::overflowedFragment):
(WebCore::SimpleLineLayout::LineState::hasTrailingWhitespace):
(WebCore::SimpleLineLayout::LineState::isWhitespaceOnly):
(WebCore::SimpleLineLayout::LineState::fits):
(WebCore::SimpleLineLayout::LineState::firstCharacterFits):
(WebCore::SimpleLineLayout::LineState::width):
(WebCore::SimpleLineLayout::LineState::appendFragment): Append each fragment to the Run
by either creating a new run or expanding the last one.
(WebCore::SimpleLineLayout::LineState::removeTrailingWhitespace): Remove trailing whitespace from
the Run's and reset the trailing whitespace variables.
(WebCore::SimpleLineLayout::removeTrailingWhitespace):
(WebCore::SimpleLineLayout::updateLineConstrains):
(WebCore::SimpleLineLayout::firstFragment):
(WebCore::SimpleLineLayout::createLineRuns):
(WebCore::SimpleLineLayout::closeLineEndingAndAdjustRuns):
(WebCore::SimpleLineLayout::createTextRuns):
(WebCore::SimpleLineLayout::LineState::createRun): Deleted.
(WebCore::SimpleLineLayout::LineState::addFragment): Deleted.
(WebCore::SimpleLineLayout::LineState::addWhitespace): Deleted.
(WebCore::SimpleLineLayout::LineState::hasWhitespaceOnly): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutcpp">trunk/Source/WebCore/rendering/SimpleLineLayout.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (179434 => 179435)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-01-31 03:06:11 UTC (rev 179434)
+++ trunk/Source/WebCore/ChangeLog        2015-01-31 03:37:46 UTC (rev 179435)
</span><span class="lines">@@ -1,3 +1,46 @@
</span><ins>+2015-01-30  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Simple line layout: Make LineState fragment handling simpler.
+        https://bugs.webkit.org/show_bug.cgi?id=141100
+
+        Reviewed by Andreas Kling.
+
+        New fragments are appeneded to the Run's last entry
+        instead of accumulating them until after a new run is required. 
+        (whitespace collapse or line end)
+        LineState::appendFragment manages whitespace collapsing now.
+        This makes createLineRuns() logic lighter and no need to &quot;flush&quot;
+        the LineState when the line ends.
+
+        No change in functionality.
+
+        * rendering/SimpleLineLayout.cpp: Make LineState members private and introduce getters.
+        (WebCore::SimpleLineLayout::LineState::setAvailableWidth):
+        (WebCore::SimpleLineLayout::LineState::setLogicalLeftOffset):
+        (WebCore::SimpleLineLayout::LineState::setOverflowedFragment):
+        (WebCore::SimpleLineLayout::LineState::availableWidth):
+        (WebCore::SimpleLineLayout::LineState::logicalLeftOffset):
+        (WebCore::SimpleLineLayout::LineState::overflowedFragment):
+        (WebCore::SimpleLineLayout::LineState::hasTrailingWhitespace):
+        (WebCore::SimpleLineLayout::LineState::isWhitespaceOnly):
+        (WebCore::SimpleLineLayout::LineState::fits):
+        (WebCore::SimpleLineLayout::LineState::firstCharacterFits):
+        (WebCore::SimpleLineLayout::LineState::width):
+        (WebCore::SimpleLineLayout::LineState::appendFragment): Append each fragment to the Run 
+        by either creating a new run or expanding the last one.
+        (WebCore::SimpleLineLayout::LineState::removeTrailingWhitespace): Remove trailing whitespace from
+        the Run's and reset the trailing whitespace variables.
+        (WebCore::SimpleLineLayout::removeTrailingWhitespace):
+        (WebCore::SimpleLineLayout::updateLineConstrains):
+        (WebCore::SimpleLineLayout::firstFragment):
+        (WebCore::SimpleLineLayout::createLineRuns):
+        (WebCore::SimpleLineLayout::closeLineEndingAndAdjustRuns):
+        (WebCore::SimpleLineLayout::createTextRuns):
+        (WebCore::SimpleLineLayout::LineState::createRun): Deleted.
+        (WebCore::SimpleLineLayout::LineState::addFragment): Deleted.
+        (WebCore::SimpleLineLayout::LineState::addWhitespace): Deleted.
+        (WebCore::SimpleLineLayout::LineState::hasWhitespaceOnly): Deleted.
+
</ins><span class="cx"> 2015-01-30  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Drop HistoryItem's m_prev / m_next
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (179434 => 179435)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp        2015-01-31 03:06:11 UTC (rev 179434)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp        2015-01-31 03:37:46 UTC (rev 179435)
</span><span class="lines">@@ -227,86 +227,74 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-struct LineState {
-    void createRun(Layout::RunVector&amp; lineRuns)
-    {
-        if (segmentStart == segmentEnd)
-            return;
</del><ins>+class LineState {
+public:
+    void setAvailableWidth(float width) { m_availableWidth = width; }
+    void setLogicalLeftOffset(float offset) { m_logicalLeftOffset = offset; }
+    void setOverflowedFragment(const FlowContentsIterator::TextFragment&amp; fragment) { m_overflowedFragment = fragment; }
</ins><span class="cx"> 
</span><del>-        lineRuns.append(Run(segmentStart, segmentEnd, runsWidth, runsWidth + segmentWidth, false));
-        // Move uncommitted to committed.
-        runsWidth += segmentWidth;
-        lastRunTrailingWhitespaceWidth = segmentTrailingWhitespaceWidth;
-        lastRunTrailingWhitespaceLength = segmentTrailingWhitespaceLength;
-        if (!m_firstCharacterFits)
-            m_firstCharacterFits = segmentStart + 1 &gt; segmentEnd || runsWidth &lt;= availableWidth;
</del><ins>+    float availableWidth() const { return m_availableWidth; }
+    float logicalLeftOffset() const { return m_logicalLeftOffset; }
+    FlowContentsIterator::TextFragment overflowedFragment() const { return m_overflowedFragment; }
+    bool hasTrailingWhitespace() const { return m_trailingWhitespaceLength; }
+    bool isWhitespaceOnly() const { return m_trailingWhitespaceWidth &amp;&amp; m_runsWidth == m_trailingWhitespaceWidth; }
+    bool fits(float extra) const { return m_availableWidth &gt;= m_runsWidth + extra; }
+    bool firstCharacterFits() const { return m_firstCharacterFits; }
+    float width() const { return m_runsWidth; }
</ins><span class="cx"> 
</span><del>-        segmentStart = segmentEnd;
-        segmentWidth = 0;
-        segmentTrailingWhitespaceWidth = 0;
-        segmentTrailingWhitespaceLength = 0;
-        m_newSegment = true;
-    }
-
-    void addFragment(const FlowContentsIterator::TextFragment&amp; fragment)
</del><ins>+    void appendFragment(const FlowContentsIterator::TextFragment&amp; fragment, Layout::RunVector&amp; runs)
</ins><span class="cx">     {
</span><del>-        // Start a new uncommitted segment.
-        if (m_newSegment) {
-            segmentStart = fragment.start;
-            m_newSegment = false;
</del><ins>+        // Adjust end position while collapsing.
+        unsigned endPosition = fragment.isCollapsed ? fragment.start + 1 : fragment.end;
+
+        if (m_createNewRun)
+            runs.append(Run(fragment.start, endPosition, m_runsWidth, m_runsWidth + fragment.width, false));
+        else {
+            ASSERT(runs.size());
+            Run&amp; lastRun = runs.last();
+            lastRun.end = endPosition;
+            lastRun.logicalRight = m_runsWidth + fragment.width;
</ins><span class="cx">         }
</span><del>-        segmentWidth += fragment.width;
-        segmentEnd = fragment.end;
-        segmentTrailingWhitespaceWidth = fragment.type == FlowContentsIterator::TextFragment::Whitespace ? fragment.width : 0;
-        segmentTrailingWhitespaceLength = fragment.type == FlowContentsIterator::TextFragment::Whitespace ? fragment.end - fragment.start  : 0;
-    }
</del><ins>+        m_createNewRun = fragment.isCollapsed;
+        m_runsWidth += fragment.width;
</ins><span class="cx"> 
</span><del>-    void addWhitespace(float whitespaceWidth)
-    {
-        addFragment(FlowContentsIterator::TextFragment(segmentEnd, segmentEnd + 1, whitespaceWidth, true));
-    }
</del><ins>+        if (fragment.type == FlowContentsIterator::TextFragment::Whitespace) {
+            m_trailingWhitespaceLength += endPosition - fragment.start;
+            m_trailingWhitespaceWidth += fragment.width;
+        } else {
+            m_trailingWhitespaceLength = 0;
+            m_trailingWhitespaceWidth = 0;
+        }
</ins><span class="cx"> 
</span><del>-    bool hasWhitespaceOnly() const
-    {
-        return lastRunTrailingWhitespaceWidth &amp;&amp; runsWidth == lastRunTrailingWhitespaceWidth;
</del><ins>+        if (!m_firstCharacterFits)
+            m_firstCharacterFits = fragment.start + 1 &gt; fragment.end || m_runsWidth &lt;= m_availableWidth;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    float width() const
</del><ins>+    void removeTrailingWhitespace(Layout::RunVector&amp; runs)
</ins><span class="cx">     {
</span><del>-        return runsWidth + segmentWidth;
-    }
</del><ins>+        ASSERT(runs.size());
+        Run&amp; lastRun = runs.last();
+        lastRun.logicalRight -= m_trailingWhitespaceWidth;
+        lastRun.end -= m_trailingWhitespaceLength;
+        if (lastRun.start == lastRun.end)
+            runs.removeLast();
</ins><span class="cx"> 
</span><del>-    bool fits(float extra) const
-    {
-        return availableWidth &gt;= width() + extra;
</del><ins>+        m_runsWidth -= m_trailingWhitespaceWidth;
+        m_trailingWhitespaceWidth = 0;
+        m_trailingWhitespaceLength = 0;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool firstCharacterFits() const { return m_firstCharacterFits; }
-
-    void removeTrailingWhitespace()
-    {
-        runsWidth -= lastRunTrailingWhitespaceWidth;
-        lastRunTrailingWhitespaceWidth = 0;
-        lastRunTrailingWhitespaceLength = 0;
-    }
-
-    float availableWidth { 0 };
-    float logicalLeftOffset { 0 };
-    float runsWidth { 0 };
-    float lastRunTrailingWhitespaceWidth { 0 }; // Use this to remove trailing whitespace without re-mesuring the text.
-    unsigned lastRunTrailingWhitespaceLength { 0 };
-    FlowContentsIterator::TextFragment overflowedFragment;
-
</del><span class="cx"> private:
</span><del>-    unsigned segmentStart { 0 };
-    unsigned segmentEnd { 0 };
-    float segmentWidth { 0 };
-    float segmentTrailingWhitespaceWidth { 0 };
-    unsigned segmentTrailingWhitespaceLength { 0 };
</del><ins>+    float m_availableWidth { 0 };
+    float m_logicalLeftOffset { 0 };
+    FlowContentsIterator::TextFragment m_overflowedFragment;
+    float m_runsWidth { 0 };
+    bool m_createNewRun { true };
+    float m_trailingWhitespaceWidth { 0 }; // Use this to remove trailing whitespace without re-mesuring the text.
+    unsigned m_trailingWhitespaceLength { 0 };
</ins><span class="cx">     // Having one character on the line does not necessarily mean it actually fits.
</span><span class="cx">     // First character of the first fragment might be forced on to the current line even if it does not fit.
</span><span class="cx">     bool m_firstCharacterFits { false };
</span><del>-    bool m_newSegment { true };
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static bool preWrap(const FlowContentsIterator::Style&amp; style)
</span><span class="lines">@@ -314,9 +302,9 @@
</span><span class="cx">     return style.wrapLines &amp;&amp; !style.collapseWhitespace;
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-static void removeTrailingWhitespace(LineState&amp; lineState, Layout::RunVector&amp; lineRuns, const FlowContentsIterator&amp; flowContentsIterator)
</del><ins>+static void removeTrailingWhitespace(LineState&amp; lineState, Layout::RunVector&amp; runs, const FlowContentsIterator&amp; flowContentsIterator)
</ins><span class="cx"> {
</span><del>-    if (!lineState.lastRunTrailingWhitespaceLength)
</del><ins>+    if (!lineState.hasTrailingWhitespace())
</ins><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     // Remove collapsed whitespace, or non-collapsed pre-wrap whitespace, unless it's the only content on the line -so removing the whitesapce would produce an empty line.
</span><span class="lines">@@ -325,25 +313,19 @@
</span><span class="cx">     if (!collapseWhitespace)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (preWrap(style) &amp;&amp; lineState.hasWhitespaceOnly())
</del><ins>+    if (preWrap(style) &amp;&amp; lineState.isWhitespaceOnly())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ASSERT(lineRuns.size());
-    Run&amp; lastRun = lineRuns.last();
-    lastRun.logicalRight -= lineState.lastRunTrailingWhitespaceWidth;
-    lastRun.end -= lineState.lastRunTrailingWhitespaceLength;
-    if (lastRun.start == lastRun.end)
-        lineRuns.removeLast();
-    lineState.removeTrailingWhitespace();
</del><ins>+    lineState.removeTrailingWhitespace(runs);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void updateLineConstrains(const RenderBlockFlow&amp; flow, float&amp; availableWidth, float&amp; logicalLeftOffset)
</del><ins>+static void updateLineConstrains(const RenderBlockFlow&amp; flow, LineState&amp; line)
</ins><span class="cx"> {
</span><span class="cx">     LayoutUnit height = flow.logicalHeight();
</span><span class="cx">     LayoutUnit logicalHeight = flow.minLineHeightForReplacedRenderer(false, 0);
</span><span class="cx">     float logicalRightOffset = flow.logicalRightOffsetForLine(height, false, logicalHeight);
</span><del>-    logicalLeftOffset = flow.logicalLeftOffsetForLine(height, false, logicalHeight);
-    availableWidth = std::max&lt;float&gt;(0, logicalRightOffset - logicalLeftOffset);
</del><ins>+    line.setLogicalLeftOffset(flow.logicalLeftOffsetForLine(height, false, logicalHeight));
+    line.setAvailableWidth(std::max&lt;float&gt;(0, logicalRightOffset - line.logicalLeftOffset()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static FlowContentsIterator::TextFragment splitFragmentToFitLine(FlowContentsIterator::TextFragment&amp; fragmentToSplit, float availableWidth, bool keepAtLeastOneCharacter, const FlowContentsIterator&amp; flowContentsIterator)
</span><span class="lines">@@ -390,7 +372,7 @@
</span><span class="cx"> static FlowContentsIterator::TextFragment firstFragment(FlowContentsIterator&amp; flowContentsIterator, const LineState&amp; previousLine)
</span><span class="cx"> {
</span><span class="cx">     // Handle overflowed fragment from previous line.
</span><del>-    FlowContentsIterator::TextFragment firstFragment = previousLine.overflowedFragment;
</del><ins>+    FlowContentsIterator::TextFragment firstFragment = previousLine.overflowedFragment();
</ins><span class="cx">     const auto&amp; style = flowContentsIterator.style();
</span><span class="cx"> 
</span><span class="cx">     if (firstFragment.isEmpty())
</span><span class="lines">@@ -412,7 +394,7 @@
</span><span class="cx">     return firstFragment;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool createLineRuns(LineState&amp; line, const LineState&amp; previousLine, Layout::RunVector&amp; lineRuns, FlowContentsIterator&amp; flowContentsIterator)
</del><ins>+static bool createLineRuns(LineState&amp; line, const LineState&amp; previousLine, Layout::RunVector&amp; runs, FlowContentsIterator&amp; flowContentsIterator)
</ins><span class="cx"> {
</span><span class="cx">     const auto&amp; style = flowContentsIterator.style();
</span><span class="cx">     bool lineCanBeWrapped = style.wrapLines || style.breakWordOnOverflow;
</span><span class="lines">@@ -422,7 +404,7 @@
</span><span class="cx">         if (fragment.type == FlowContentsIterator::TextFragment::LineBreak) {
</span><span class="cx">             // Add the new line fragment only if there's nothing on the line. (otherwise the extra new line character would show up at the end of the content.)
</span><span class="cx">             if (!line.width())
</span><del>-                line.addFragment(fragment);
</del><ins>+                line.appendFragment(fragment, runs);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         if (lineCanBeWrapped &amp;&amp; !line.fits(fragment.width)) {
</span><span class="lines">@@ -436,8 +418,8 @@
</span><span class="cx">             if (fragment.type == FlowContentsIterator::TextFragment::Whitespace) {
</span><span class="cx">                 if (!style.collapseWhitespace) {
</span><span class="cx">                     // Split the fragment; (modified)fragment stays on this line, overflowedFragment is pushed to next line.
</span><del>-                    line.overflowedFragment = splitFragmentToFitLine(fragment, line.availableWidth - line.width(), emptyLine, flowContentsIterator);
-                    line.addFragment(fragment);
</del><ins>+                    line.setOverflowedFragment(splitFragmentToFitLine(fragment, line.availableWidth() - line.width(), emptyLine, flowContentsIterator));
+                    line.appendFragment(fragment, runs);
</ins><span class="cx">                 }
</span><span class="cx">                 // When whitespace collapse is on, whitespace that doesn't fit is simply skipped.
</span><span class="cx">                 break;
</span><span class="lines">@@ -445,31 +427,24 @@
</span><span class="cx">             // Non-whitespace fragment. (!style.wrapLines: bug138102(preserve existing behavior)
</span><span class="cx">             if ((emptyLine &amp;&amp; style.breakWordOnOverflow) || !style.wrapLines) {
</span><span class="cx">                 // Split the fragment; (modified)fragment stays on this line, overflowedFragment is pushed to next line.
</span><del>-                line.overflowedFragment = splitFragmentToFitLine(fragment, line.availableWidth - line.width(), emptyLine, flowContentsIterator);
-                line.addFragment(fragment);
</del><ins>+                line.setOverflowedFragment(splitFragmentToFitLine(fragment, line.availableWidth() - line.width(), emptyLine, flowContentsIterator));
+                line.appendFragment(fragment, runs);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             // Non-breakable non-whitespace first fragment. Add it to the current line. -it overflows though.
</span><span class="cx">             if (emptyLine) {
</span><del>-                line.addFragment(fragment);
</del><ins>+                line.appendFragment(fragment, runs);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             // Non-breakable non-whitespace fragment when there's already content on the line. Push it to the next line.
</span><del>-            line.overflowedFragment = fragment;
</del><ins>+            line.setOverflowedFragment(fragment);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        // When the current fragment is collapsed whitespace, we need to create a run for what we've processed so far.
-        if (fragment.isCollapsed) {
-            // One trailing whitespace to preserve.
-            line.addWhitespace(style.spaceWidth);
-            line.createRun(lineRuns);
-        } else
-            line.addFragment(fragment);
</del><ins>+        line.appendFragment(fragment, runs);
</ins><span class="cx">         // Find the next text fragment.
</span><span class="cx">         fragment = flowContentsIterator.nextTextFragment(line.width());
</span><span class="cx">     }
</span><del>-    line.createRun(lineRuns);
-    return fragment.isEmpty() &amp;&amp; line.overflowedFragment.isEmpty();
</del><ins>+    return fragment.isEmpty() &amp;&amp; line.overflowedFragment().isEmpty();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void closeLineEndingAndAdjustRuns(LineState&amp; line, Layout::RunVector&amp; runs, unsigned previousRunCount, unsigned&amp; lineCount, const FlowContentsIterator&amp; flowContentsIterator)
</span><span class="lines">@@ -481,7 +456,7 @@
</span><span class="cx">     if (!runs.size())
</span><span class="cx">         return;
</span><span class="cx">     // Adjust runs' position by taking line's alignment into account.
</span><del>-    if (float lineLogicalLeft = computeLineLeft(flowContentsIterator.style().textAlign, line.availableWidth, line.runsWidth, line.logicalLeftOffset)) {
</del><ins>+    if (float lineLogicalLeft = computeLineLeft(flowContentsIterator.style().textAlign, line.availableWidth(), line.width(), line.logicalLeftOffset())) {
</ins><span class="cx">         for (unsigned i = previousRunCount; i &lt; runs.size(); ++i) {
</span><span class="cx">             runs[i].logicalLeft += lineLogicalLeft;
</span><span class="cx">             runs[i].logicalRight += lineLogicalLeft;
</span><span class="lines">@@ -526,7 +501,7 @@
</span><span class="cx">         LineState previousLine = line;
</span><span class="cx">         unsigned previousRunCount = runs.size();
</span><span class="cx">         line = LineState();
</span><del>-        updateLineConstrains(flow, line.availableWidth, line.logicalLeftOffset);
</del><ins>+        updateLineConstrains(flow, line);
</ins><span class="cx">         isEndOfContent = createLineRuns(line, previousLine, runs, flowContentsIterator);
</span><span class="cx">         closeLineEndingAndAdjustRuns(line, runs, previousRunCount, lineCount, flowContentsIterator);
</span><span class="cx">     } while (!isEndOfContent);
</span></span></pre>
</div>
</div>

</body>
</html>