<!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>[181171] 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/181171">181171</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2015-03-06 11:06:30 -0800 (Fri, 06 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Rename BreakingContextInlineHeaders.h to BreakingContext.h
https://bugs.webkit.org/show_bug.cgi?id=142404

Reviewed by Simon Fraser.

No point naming it &quot;InlineHeaders&quot; when there are no non-inline-headers files.

No new tests because this is just a rename of a file.

* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
* rendering/RenderBlockLineLayout.cpp:
* rendering/line/BreakingContext.h: Renamed from Source/WebCore/rendering/line/BreakingContextInlineHeaders.h.
(WebCore::WordMeasurement::WordMeasurement):
(WebCore::BreakingContext::BreakingContext):
(WebCore::BreakingContext::currentObject):
(WebCore::BreakingContext::lineBreak):
(WebCore::BreakingContext::lineWidth):
(WebCore::BreakingContext::atEnd):
(WebCore::BreakingContext::clearLineBreakIfFitsOnLine):
(WebCore::BreakingContext::commitLineBreakAtCurrentWidth):
(WebCore::BreakingContext::InlineIteratorHistory::InlineIteratorHistory):
(WebCore::BreakingContext::InlineIteratorHistory::push):
(WebCore::BreakingContext::InlineIteratorHistory::update):
(WebCore::BreakingContext::InlineIteratorHistory::renderer):
(WebCore::BreakingContext::InlineIteratorHistory::offset):
(WebCore::BreakingContext::InlineIteratorHistory::atTextParagraphSeparator):
(WebCore::BreakingContext::InlineIteratorHistory::previousInSameNode):
(WebCore::BreakingContext::InlineIteratorHistory::get):
(WebCore::BreakingContext::InlineIteratorHistory::current):
(WebCore::BreakingContext::InlineIteratorHistory::historyLength):
(WebCore::BreakingContext::InlineIteratorHistory::moveTo):
(WebCore::BreakingContext::InlineIteratorHistory::increment):
(WebCore::BreakingContext::InlineIteratorHistory::clear):
(WebCore::BreakingContext::initializeForCurrentObject):
(WebCore::BreakingContext::increment):
(WebCore::BreakingContext::handleBR):
(WebCore::borderPaddingMarginStart):
(WebCore::borderPaddingMarginEnd):
(WebCore::shouldAddBorderPaddingMargin):
(WebCore::previousInFlowSibling):
(WebCore::inlineLogicalWidth):
(WebCore::BreakingContext::handleOutOfFlowPositioned):
(WebCore::BreakingContext::handleFloat):
(WebCore::shouldSkipWhitespaceAfterStartObject):
(WebCore::BreakingContext::handleEmptyInline):
(WebCore::BreakingContext::handleReplaced):
(WebCore::firstPositiveWidth):
(WebCore::iteratorIsBeyondEndOfRenderCombineText):
(WebCore::nextCharacter):
(WebCore::updateCounterIfNeeded):
(WebCore::measureHyphenWidth):
(WebCore::textWidth):
(WebCore::ensureCharacterGetsLineBox):
(WebCore::tryHyphenating):
(WebCore::BreakingContext::handleText):
(WebCore::textBeginsWithBreakablePosition):
(WebCore::BreakingContext::canBreakAtThisPosition):
(WebCore::BreakingContext::commitAndUpdateLineBreakIfNeeded):
(WebCore::checkMidpoints):
(WebCore::BreakingContext::handleEndOfLine):
(WebCore::BreakingContext::optimalLineBreakLocationForTrailingWord):
* rendering/line/LineBreaker.cpp:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockLineLayoutcpp">trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderinglineLineBreakercpp">trunk/Source/WebCore/rendering/line/LineBreaker.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorerenderinglineBreakingContexth">trunk/Source/WebCore/rendering/line/BreakingContext.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorerenderinglineBreakingContextInlineHeadersh">trunk/Source/WebCore/rendering/line/BreakingContextInlineHeaders.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (181170 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-06 18:47:28 UTC (rev 181170)
+++ trunk/Source/WebCore/ChangeLog        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -1,3 +1,70 @@
</span><ins>+2015-03-06  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Rename BreakingContextInlineHeaders.h to BreakingContext.h
+        https://bugs.webkit.org/show_bug.cgi?id=142404
+
+        Reviewed by Simon Fraser.
+
+        No point naming it &quot;InlineHeaders&quot; when there are no non-inline-headers files.
+
+        No new tests because this is just a rename of a file.
+
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/RenderBlockLineLayout.cpp:
+        * rendering/line/BreakingContext.h: Renamed from Source/WebCore/rendering/line/BreakingContextInlineHeaders.h.
+        (WebCore::WordMeasurement::WordMeasurement):
+        (WebCore::BreakingContext::BreakingContext):
+        (WebCore::BreakingContext::currentObject):
+        (WebCore::BreakingContext::lineBreak):
+        (WebCore::BreakingContext::lineWidth):
+        (WebCore::BreakingContext::atEnd):
+        (WebCore::BreakingContext::clearLineBreakIfFitsOnLine):
+        (WebCore::BreakingContext::commitLineBreakAtCurrentWidth):
+        (WebCore::BreakingContext::InlineIteratorHistory::InlineIteratorHistory):
+        (WebCore::BreakingContext::InlineIteratorHistory::push):
+        (WebCore::BreakingContext::InlineIteratorHistory::update):
+        (WebCore::BreakingContext::InlineIteratorHistory::renderer):
+        (WebCore::BreakingContext::InlineIteratorHistory::offset):
+        (WebCore::BreakingContext::InlineIteratorHistory::atTextParagraphSeparator):
+        (WebCore::BreakingContext::InlineIteratorHistory::previousInSameNode):
+        (WebCore::BreakingContext::InlineIteratorHistory::get):
+        (WebCore::BreakingContext::InlineIteratorHistory::current):
+        (WebCore::BreakingContext::InlineIteratorHistory::historyLength):
+        (WebCore::BreakingContext::InlineIteratorHistory::moveTo):
+        (WebCore::BreakingContext::InlineIteratorHistory::increment):
+        (WebCore::BreakingContext::InlineIteratorHistory::clear):
+        (WebCore::BreakingContext::initializeForCurrentObject):
+        (WebCore::BreakingContext::increment):
+        (WebCore::BreakingContext::handleBR):
+        (WebCore::borderPaddingMarginStart):
+        (WebCore::borderPaddingMarginEnd):
+        (WebCore::shouldAddBorderPaddingMargin):
+        (WebCore::previousInFlowSibling):
+        (WebCore::inlineLogicalWidth):
+        (WebCore::BreakingContext::handleOutOfFlowPositioned):
+        (WebCore::BreakingContext::handleFloat):
+        (WebCore::shouldSkipWhitespaceAfterStartObject):
+        (WebCore::BreakingContext::handleEmptyInline):
+        (WebCore::BreakingContext::handleReplaced):
+        (WebCore::firstPositiveWidth):
+        (WebCore::iteratorIsBeyondEndOfRenderCombineText):
+        (WebCore::nextCharacter):
+        (WebCore::updateCounterIfNeeded):
+        (WebCore::measureHyphenWidth):
+        (WebCore::textWidth):
+        (WebCore::ensureCharacterGetsLineBox):
+        (WebCore::tryHyphenating):
+        (WebCore::BreakingContext::handleText):
+        (WebCore::textBeginsWithBreakablePosition):
+        (WebCore::BreakingContext::canBreakAtThisPosition):
+        (WebCore::BreakingContext::commitAndUpdateLineBreakIfNeeded):
+        (WebCore::checkMidpoints):
+        (WebCore::BreakingContext::handleEndOfLine):
+        (WebCore::BreakingContext::optimalLineBreakLocationForTrailingWord):
+        * rendering/line/LineBreaker.cpp:
+
</ins><span class="cx"> 2015-03-06  Dan Bernstein  &lt;mitz@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Expose some of the functionality of extract-localizable-strings.pl as a module
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (181170 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-03-06 18:47:28 UTC (rev 181170)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -20345,7 +20345,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\RenderSelectionInfo.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\RenderSlider.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\RenderSnapshottedPlugIn.h&quot; /&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\rendering\line\BreakingContextInlineHeaders.h&quot; /&gt;
</del><ins>+    &lt;ClInclude Include=&quot;..\rendering\line\BreakingContext.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\line\LineBreaker.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\line\LineInfo.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\line\LineInlineHeaders.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (181170 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2015-03-06 18:47:28 UTC (rev 181170)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -14408,7 +14408,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\BorderEdge.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;rendering&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><del>-    &lt;ClInclude Include=&quot;..\rendering\line\BreakingContextInlineHeaders.h&quot;&gt;
</del><ins>+    &lt;ClInclude Include=&quot;..\rendering\line\BreakingContext.h&quot;&gt;
</ins><span class="cx">       &lt;Filter&gt;rendering\line&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\page\ContextMenuContext.h&quot;&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (181170 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-03-06 18:47:28 UTC (rev 181170)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -14363,7 +14363,7 @@
</span><span class="cx">                 FF945ECA161F7F3600971BC8 /* PseudoElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FFAC30FC184FB145008C4F1E /* TrailingObjects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrailingObjects.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FFAC30FD184FB145008C4F1E /* TrailingObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrailingObjects.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                FFB698C91832F10B00158A31 /* BreakingContextInlineHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BreakingContextInlineHeaders.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><ins>+                FFB698C91832F10B00158A31 /* BreakingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BreakingContext.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 FFB698CA1833EC3800158A31 /* LineBreaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineBreaker.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FFB698CB1833EC3800158A31 /* LineBreaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineBreaker.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FFB698CD1833F17600158A31 /* LineInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineInfo.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -23453,7 +23453,7 @@
</span><span class="cx">                 FFB698C81832F10B00158A31 /* line */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                FFB698C91832F10B00158A31 /* BreakingContextInlineHeaders.h */,
</del><ins>+                                FFB698C91832F10B00158A31 /* BreakingContext.h */,
</ins><span class="cx">                                 FFB698CA1833EC3800158A31 /* LineBreaker.cpp */,
</span><span class="cx">                                 FFB698CB1833EC3800158A31 /* LineBreaker.h */,
</span><span class="cx">                                 FFB698CD1833F17600158A31 /* LineInfo.cpp */,
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockLineLayoutcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (181170 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2015-03-06 18:47:28 UTC (rev 181170)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AXObjectCache.h&quot;
</span><span class="cx"> #include &quot;BidiResolver.h&quot;
</span><del>-#include &quot;BreakingContextInlineHeaders.h&quot;
</del><ins>+#include &quot;BreakingContext.h&quot;
</ins><span class="cx"> #include &quot;FloatingObjects.h&quot;
</span><span class="cx"> #include &quot;InlineElementBox.h&quot;
</span><span class="cx"> #include &quot;InlineIterator.h&quot;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderinglineBreakingContexthfromrev181170trunkSourceWebCorerenderinglineBreakingContextInlineHeadersh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/rendering/line/BreakingContext.h (from rev 181170, trunk/Source/WebCore/rendering/line/BreakingContextInlineHeaders.h) (0 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/line/BreakingContext.h                                (rev 0)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -0,0 +1,1202 @@
</span><ins>+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2013 ChangSeok Oh &lt;shivamidow@gmail.com&gt;
+ * Copyright (C) 2013 Adobe Systems Inc. All right reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BreakingContext_h
+#define BreakingContext_h
+
+#include &quot;Hyphenation.h&quot;
+#include &quot;LineBreaker.h&quot;
+#include &quot;LineInfo.h&quot;
+#include &quot;LineWidth.h&quot;
+#include &quot;RenderCombineText.h&quot;
+#include &quot;RenderCounter.h&quot;
+#include &quot;RenderInline.h&quot;
+#include &quot;RenderLineBreak.h&quot;
+#include &quot;RenderListMarker.h&quot;
+#include &quot;RenderRubyRun.h&quot;
+#include &quot;RenderSVGInlineText.h&quot;
+#include &quot;TrailingObjects.h&quot;
+#include &quot;break_lines.h&quot;
+#include &lt;wtf/text/StringView.h&gt;
+#include &lt;wtf/unicode/CharacterNames.h&gt;
+
+namespace WebCore {
+
+// We don't let our line box tree for a single line get any deeper than this.
+const unsigned cMaxLineDepth = 200;
+
+struct WordMeasurement {
+    WordMeasurement()
+        : renderer(0)
+        , width(0)
+        , startOffset(0)
+        , endOffset(0)
+    {
+    }
+
+    RenderText* renderer;
+    float width;
+    int startOffset;
+    int endOffset;
+    HashSet&lt;const Font*&gt; fallbackFonts;
+};
+
+class BreakingContext {
+public:
+    BreakingContext(LineBreaker&amp; lineBreaker, InlineBidiResolver&amp; resolver, LineInfo&amp; inLineInfo, LineWidth&amp; lineWidth, RenderTextInfo&amp; inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderBlockFlow&amp; block)
+        : m_lineBreaker(lineBreaker)
+        , m_resolver(resolver)
+        , m_current(resolver.position())
+#if ENABLE(CSS_TRAILING_WORD)
+        , m_lineBreakHistory(InlineIterator(resolver.position()), block.style().trailingWord() == TrailingWord::PartiallyBalanced ? 5 : 1)
+#else
+        , m_lineBreakHistory(InlineIterator(resolver.position()), 1)
+#endif
+        , m_block(block)
+        , m_lastObject(m_current.renderer())
+        , m_nextObject(nullptr)
+        , m_currentStyle(nullptr)
+        , m_blockStyle(block.style())
+        , m_lineInfo(inLineInfo)
+        , m_renderTextInfo(inRenderTextInfo)
+        , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine)
+        , m_width(lineWidth)
+        , m_currWS(NORMAL)
+        , m_lastWS(NORMAL)
+        , m_preservesNewline(false)
+        , m_atStart(true)
+        , m_ignoringSpaces(false)
+        , m_currentCharacterIsSpace(false)
+        , m_currentCharacterIsWS(false)
+        , m_appliedStartWidth(appliedStartWidth)
+        , m_includeEndWidth(true)
+        , m_autoWrap(false)
+        , m_autoWrapWasEverTrueOnLine(false)
+        , m_floatsFitOnLine(true)
+        , m_collapseWhiteSpace(false)
+        , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly())
+        , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTableCell() || !m_blockStyle.logicalWidth().isIntrinsicOrAuto())
+        , m_atEnd(false)
+        , m_hadUncommittedWidthBeforeCurrent(false)
+        , m_lineMidpointState(resolver.midpointState())
+    {
+        m_lineInfo.setPreviousLineBrokeCleanly(false);
+    }
+
+    RenderObject* currentObject() { return m_current.renderer(); }
+    InlineIterator lineBreak() { return m_lineBreakHistory.current(); }
+    LineWidth&amp; lineWidth() { return m_width; }
+    bool atEnd() { return m_atEnd; }
+
+    void initializeForCurrentObject();
+
+    void increment();
+
+    void handleBR(EClear&amp;);
+    void handleOutOfFlowPositioned(Vector&lt;RenderBox*&gt;&amp; positionedObjects);
+    void handleFloat();
+    void handleEmptyInline();
+    void handleReplaced();
+    bool handleText(WordMeasurements&amp;, bool&amp; hyphenated, unsigned&amp; consecutiveHyphenatedLines);
+    bool canBreakAtThisPosition();
+    void commitAndUpdateLineBreakIfNeeded();
+    InlineIterator handleEndOfLine();
+#if ENABLE(CSS_TRAILING_WORD)
+    InlineIterator optimalLineBreakLocationForTrailingWord();
+#endif
+
+    void clearLineBreakIfFitsOnLine(bool ignoringTrailingSpace = false)
+    {
+        if (m_width.fitsOnLine(ignoringTrailingSpace) || m_lastWS == NOWRAP)
+            m_lineBreakHistory.clear();
+    }
+
+    void commitLineBreakAtCurrentWidth(RenderObject&amp; object, unsigned offset = 0, int nextBreak = -1)
+    {
+        m_width.commit();
+        m_lineBreakHistory.moveTo(&amp;object, offset, nextBreak);
+    }
+
+private:
+    // This class keeps a sliding window of the past n locations for an InlineIterator.
+    class InlineIteratorHistory : private Vector&lt;InlineIterator, 1&gt; {
+    public:
+        InlineIteratorHistory() = delete;
+        InlineIteratorHistory(const InlineIterator&amp; initial, size_t capacity)
+            : m_capacity(capacity)
+        {
+            ASSERT(capacity &gt; 0);
+            this-&gt;append(initial);
+        }
+
+        void push(std::function&lt;void(InlineIterator&amp; modifyMe)&gt; updater)
+        {
+            ASSERT(!this-&gt;isEmpty());
+            if (m_capacity != 1)
+                this-&gt;insert(0, InlineIterator(this-&gt;at(0)));
+            updater(this-&gt;at(0));
+            if (m_capacity != 1)
+                this-&gt;resize(m_capacity);
+        }
+
+        void update(std::function&lt;void(InlineIterator&amp; modifyMe)&gt; updater)
+        {
+            ASSERT(!this-&gt;isEmpty());
+            updater(this-&gt;at(0));
+        }
+
+        RenderObject* renderer() const { return this-&gt;at(0).renderer(); }
+        unsigned offset() const { return this-&gt;at(0).offset(); }
+        bool atTextParagraphSeparator() const { return this-&gt;at(0).atTextParagraphSeparator(); }
+        UChar previousInSameNode() const { return this-&gt;at(0).previousInSameNode(); }
+        const InlineIterator&amp; get(size_t i) const { return this-&gt;at(i); };
+        const InlineIterator&amp; current() const { return get(0); }
+        size_t historyLength() const { return this-&gt;size(); }
+
+        void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1)
+        {
+            push([&amp;](InlineIterator&amp; modifyMe) {
+                modifyMe.moveTo(object, offset, nextBreak);
+            });
+        }
+
+        void increment()
+        {
+            update([](InlineIterator&amp; modifyMe) {
+                modifyMe.increment();
+            });
+        }
+
+        void clear()
+        {
+            push([](InlineIterator&amp; modifyMe) {
+                modifyMe.clear();
+            });
+        }
+
+    private:
+        const size_t m_capacity;
+    };
+
+    LineBreaker&amp; m_lineBreaker;
+    InlineBidiResolver&amp; m_resolver;
+
+    InlineIterator m_current;
+    InlineIteratorHistory m_lineBreakHistory;
+    InlineIterator m_startOfIgnoredSpaces;
+
+    RenderBlockFlow&amp; m_block;
+    RenderObject* m_lastObject;
+    RenderObject* m_nextObject;
+
+    const RenderStyle* m_currentStyle;
+
+    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
+    // very specific circumstances (in order to match common WinIE renderings).
+    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
+    RenderStyle&amp; m_blockStyle;
+
+    LineInfo&amp; m_lineInfo;
+
+    RenderTextInfo&amp; m_renderTextInfo;
+
+    FloatingObject* m_lastFloatFromPreviousLine;
+
+    LineWidth m_width;
+
+    EWhiteSpace m_currWS;
+    EWhiteSpace m_lastWS;
+
+    bool m_preservesNewline;
+    bool m_atStart;
+
+    // This variable is used only if whitespace isn't set to PRE, and it tells us whether
+    // or not we are currently ignoring whitespace.
+    bool m_ignoringSpaces;
+
+    // This variable tracks whether the very last character we saw was a space. We use
+    // this to detect when we encounter a second space so we know we have to terminate
+    // a run.
+    bool m_currentCharacterIsSpace;
+    bool m_currentCharacterIsWS;
+    bool m_appliedStartWidth;
+    bool m_includeEndWidth;
+    bool m_autoWrap;
+    bool m_autoWrapWasEverTrueOnLine;
+    bool m_floatsFitOnLine;
+    bool m_collapseWhiteSpace;
+    bool m_startingNewParagraph;
+    bool m_allowImagesToBreak;
+    bool m_atEnd;
+    bool m_hadUncommittedWidthBeforeCurrent;
+
+    LineMidpointState&amp; m_lineMidpointState;
+
+    TrailingObjects m_trailingObjects;
+};
+
+inline void BreakingContext::initializeForCurrentObject()
+{
+    m_hadUncommittedWidthBeforeCurrent = !!m_width.uncommittedWidth();
+
+    m_currentStyle = &amp;m_current.renderer()-&gt;style(); // FIXME: Should this be &amp;lineStyle(*m_current.renderer(), m_lineInfo); ?
+
+    ASSERT(m_currentStyle);
+
+    m_nextObject = bidiNextSkippingEmptyInlines(m_block, m_current.renderer());
+    if (m_nextObject &amp;&amp; m_nextObject-&gt;parent() &amp;&amp; !m_nextObject-&gt;parent()-&gt;isDescendantOf(m_current.renderer()-&gt;parent()))
+        m_includeEndWidth = true;
+
+    m_currWS = m_current.renderer()-&gt;isReplaced() ? m_current.renderer()-&gt;parent()-&gt;style().whiteSpace() : m_currentStyle-&gt;whiteSpace();
+    m_lastWS = m_lastObject-&gt;isReplaced() ? m_lastObject-&gt;parent()-&gt;style().whiteSpace() : m_lastObject-&gt;style().whiteSpace();
+
+    m_autoWrap = RenderStyle::autoWrap(m_currWS);
+    m_autoWrapWasEverTrueOnLine = m_autoWrapWasEverTrueOnLine || m_autoWrap;
+
+    m_preservesNewline = m_current.renderer()-&gt;isSVGInlineText() ? false : RenderStyle::preserveNewline(m_currWS);
+
+    m_collapseWhiteSpace = RenderStyle::collapseWhiteSpace(m_currWS);
+}
+
+inline void BreakingContext::increment()
+{
+    // Clear out our character space bool, since inline &lt;pre&gt;s don't collapse whitespace
+    // with adjacent inline normal/nowrap spans.
+    if (!m_collapseWhiteSpace)
+        m_currentCharacterIsSpace = false;
+
+    m_current.moveToStartOf(m_nextObject);
+    m_atStart = false;
+}
+
+inline void BreakingContext::handleBR(EClear&amp; clear)
+{
+    if (m_width.fitsOnLine()) {
+        RenderObject* br = m_current.renderer();
+        m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
+            modifyMe.moveToStartOf(br);
+            modifyMe.increment();
+        });
+
+        // A &lt;br&gt; always breaks a line, so don't let the line be collapsed
+        // away. Also, the space at the end of a line with a &lt;br&gt; does not
+        // get collapsed away. It only does this if the previous line broke
+        // cleanly. Otherwise the &lt;br&gt; has no effect on whether the line is
+        // empty or not.
+        if (m_startingNewParagraph)
+            m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
+        m_trailingObjects.clear();
+        m_lineInfo.setPreviousLineBrokeCleanly(true);
+
+        // A &lt;br&gt; with clearance always needs a linebox in case the lines below it get dirtied later and
+        // need to check for floats to clear - so if we're ignoring spaces, stop ignoring them and add a
+        // run for this object.
+        if (m_ignoringSpaces &amp;&amp; m_currentStyle-&gt;clear() != CNONE)
+            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(br);
+        // If we were preceded by collapsing space and are in a right-aligned container we need to ensure the space gets
+        // collapsed away so that it doesn't push the text out from the container's right-hand edge.
+        // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results.
+        else if (m_ignoringSpaces &amp;&amp; (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT))
+            m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
+
+        if (!m_lineInfo.isEmpty())
+            clear = m_currentStyle-&gt;clear();
+    }
+    m_atEnd = true;
+}
+
+inline LayoutUnit borderPaddingMarginStart(const RenderInline&amp; child)
+{
+    return child.marginStart() + child.paddingStart() + child.borderStart();
+}
+
+inline LayoutUnit borderPaddingMarginEnd(const RenderInline&amp; child)
+{
+    return child.marginEnd() + child.paddingEnd() + child.borderEnd();
+}
+
+inline bool shouldAddBorderPaddingMargin(RenderObject* child)
+{
+    if (!child)
+        return true;
+    // When deciding whether we're at the edge of an inline, adjacent collapsed whitespace is the same as no sibling at all.
+    if (is&lt;RenderText&gt;(*child) &amp;&amp; !downcast&lt;RenderText&gt;(*child).textLength())
+        return true;
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
+    if (is&lt;RenderLineBreak&gt;(*child) &amp;&amp; child-&gt;parent()-&gt;style().boxDecorationBreak() == DCLONE)
+        return true;
+#endif
+    return false;
+}
+
+inline RenderObject* previousInFlowSibling(RenderObject* child)
+{
+    do {
+        child = child-&gt;previousSibling();
+    } while (child &amp;&amp; child-&gt;isOutOfFlowPositioned());
+    return child;
+}
+
+inline LayoutUnit inlineLogicalWidth(RenderObject* child, bool checkStartEdge = true, bool checkEndEdge = true)
+{
+    unsigned lineDepth = 1;
+    LayoutUnit extraWidth = 0;
+    RenderElement* parent = child-&gt;parent();
+    while (is&lt;RenderInline&gt;(*parent) &amp;&amp; lineDepth++ &lt; cMaxLineDepth) {
+        const auto&amp; parentAsRenderInline = downcast&lt;RenderInline&gt;(*parent);
+        if (!isEmptyInline(parentAsRenderInline)) {
+            checkStartEdge = checkStartEdge &amp;&amp; shouldAddBorderPaddingMargin(previousInFlowSibling(child));
+            if (checkStartEdge)
+                extraWidth += borderPaddingMarginStart(parentAsRenderInline);
+            checkEndEdge = checkEndEdge &amp;&amp; shouldAddBorderPaddingMargin(child-&gt;nextSibling());
+            if (checkEndEdge)
+                extraWidth += borderPaddingMarginEnd(parentAsRenderInline);
+            if (!checkStartEdge &amp;&amp; !checkEndEdge)
+                return extraWidth;
+        }
+        child = parent;
+        parent = child-&gt;parent();
+    }
+    return extraWidth;
+}
+
+inline void BreakingContext::handleOutOfFlowPositioned(Vector&lt;RenderBox*&gt;&amp; positionedObjects)
+{
+    // If our original display wasn't an inline type, then we can
+    // go ahead and determine our static inline position now.
+    auto&amp; box = downcast&lt;RenderBox&gt;(*m_current.renderer());
+    bool isInlineType = box.style().isOriginalDisplayInlineType();
+    if (!isInlineType)
+        m_block.setStaticInlinePositionForChild(box, m_block.logicalHeight(), m_block.startOffsetForContent(m_block.logicalHeight()));
+    else {
+        // If our original display was an INLINE type, then we can go ahead
+        // and determine our static y position now.
+        box.layer()-&gt;setStaticBlockPosition(m_block.logicalHeight());
+    }
+
+    // If we're ignoring spaces, we have to stop and include this object and
+    // then start ignoring spaces again.
+    if (isInlineType || box.container()-&gt;isRenderInline()) {
+        if (m_ignoringSpaces)
+            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(&amp;box);
+        m_trailingObjects.appendBoxIfNeeded(&amp;box);
+    } else
+        positionedObjects.append(&amp;box);
+
+    m_width.addUncommittedWidth(inlineLogicalWidth(&amp;box));
+    // Reset prior line break context characters.
+    m_renderTextInfo.m_lineBreakIterator.resetPriorContext();
+}
+
+inline void BreakingContext::handleFloat()
+{
+    auto&amp; floatBox = downcast&lt;RenderBox&gt;(*m_current.renderer());
+    FloatingObject* floatingObject = m_lineBreaker.insertFloatingObject(floatBox);
+    // check if it fits in the current line.
+    // If it does, position it now, otherwise, position
+    // it after moving to next line (in clearFloats() func)
+    if (m_floatsFitOnLine &amp;&amp; m_width.fitsOnLineExcludingTrailingWhitespace(m_block.logicalWidthForFloat(floatingObject))) {
+        m_lineBreaker.positionNewFloatOnLine(floatingObject, m_lastFloatFromPreviousLine, m_lineInfo, m_width);
+        if (m_lineBreakHistory.renderer() == m_current.renderer()) {
+            ASSERT(!m_lineBreakHistory.offset());
+            m_lineBreakHistory.increment();
+        }
+    } else
+        m_floatsFitOnLine = false;
+    // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for floating element.
+    m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter);
+}
+
+// This is currently just used for list markers and inline flows that have line boxes. Neither should
+// have an effect on whitespace at the start of the line.
+inline bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow&amp; block, RenderObject* o, LineMidpointState&amp; lineMidpointState)
+{
+    RenderObject* next = bidiNextSkippingEmptyInlines(block, o);
+    while (next &amp;&amp; next-&gt;isFloatingOrOutOfFlowPositioned())
+        next = bidiNextSkippingEmptyInlines(block, next);
+
+    if (is&lt;RenderText&gt;(next) &amp;&amp; downcast&lt;RenderText&gt;(*next).textLength() &gt; 0) {
+        RenderText&amp; nextText = downcast&lt;RenderText&gt;(*next);
+        UChar nextChar = nextText.characterAt(0);
+        if (nextText.style().isCollapsibleWhiteSpace(nextChar)) {
+            lineMidpointState.startIgnoringSpaces(InlineIterator(nullptr, o, 0));
+            return true;
+        }
+    }
+
+    return false;
+}
+
+inline void BreakingContext::handleEmptyInline()
+{
+    RenderInline&amp; flowBox = downcast&lt;RenderInline&gt;(*m_current.renderer());
+
+    // This should only end up being called on empty inlines
+    ASSERT(isEmptyInline(flowBox));
+
+    // Now that some inline flows have line boxes, if we are already ignoring spaces, we need
+    // to make sure that we stop to include this object and then start ignoring spaces again.
+    // If this object is at the start of the line, we need to behave like list markers and
+    // start ignoring spaces.
+    bool requiresLineBox = alwaysRequiresLineBox(flowBox);
+    if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) {
+        // An empty inline that only has line-height, vertical-align or font-metrics will only get a
+        // line box to affect the height of the line if the rest of the line is not empty.
+        if (requiresLineBox)
+            m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
+        if (m_ignoringSpaces) {
+            m_trailingObjects.clear();
+            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_current.renderer());
+        } else if (m_blockStyle.collapseWhiteSpace() &amp;&amp; m_resolver.position().renderer() == m_current.renderer()
+            &amp;&amp; shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineMidpointState)) {
+            // Like with list markers, we start ignoring spaces to make sure that any
+            // additional spaces we see will be discarded.
+            m_currentCharacterIsSpace = true;
+            m_currentCharacterIsWS = true;
+            m_ignoringSpaces = true;
+        } else
+            m_trailingObjects.appendBoxIfNeeded(&amp;flowBox);
+    }
+
+    m_width.addUncommittedWidth(inlineLogicalWidth(m_current.renderer()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
+}
+
+inline void BreakingContext::handleReplaced()
+{
+    auto&amp; replacedBox = downcast&lt;RenderBox&gt;(*m_current.renderer());
+
+    if (m_atStart)
+        m_width.updateAvailableWidth(replacedBox.logicalHeight());
+
+    // Break on replaced elements if either has normal white-space.
+    if ((m_autoWrap || RenderStyle::autoWrap(m_lastWS)) &amp;&amp; (!m_current.renderer()-&gt;isImage() || m_allowImagesToBreak)
+        &amp;&amp; (!m_current.renderer()-&gt;isRubyRun() || downcast&lt;RenderRubyRun&gt;(m_current.renderer())-&gt;canBreakBefore(m_renderTextInfo.m_lineBreakIterator))) {
+        commitLineBreakAtCurrentWidth(*m_current.renderer());
+    }
+
+    if (m_ignoringSpaces)
+        m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), 0));
+
+    m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
+    m_ignoringSpaces = false;
+    m_currentCharacterIsSpace = false;
+    m_currentCharacterIsWS = false;
+    m_trailingObjects.clear();
+
+    // Optimize for a common case. If we can't find whitespace after the list
+    // item, then this is all moot.
+    LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox) + m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedBox) + inlineLogicalWidth(m_current.renderer());
+    if (is&lt;RenderListMarker&gt;(*m_current.renderer())) {
+        if (m_blockStyle.collapseWhiteSpace() &amp;&amp; shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineMidpointState)) {
+            // Like with inline flows, we start ignoring spaces to make sure that any
+            // additional spaces we see will be discarded.
+            m_currentCharacterIsSpace = true;
+            m_currentCharacterIsWS = false;
+            m_ignoringSpaces = true;
+        }
+        if (downcast&lt;RenderListMarker&gt;(*m_current.renderer()).isInside())
+            m_width.addUncommittedWidth(replacedLogicalWidth);
+    } else
+        m_width.addUncommittedWidth(replacedLogicalWidth);
+    if (is&lt;RenderRubyRun&gt;(*m_current.renderer())) {
+        m_width.applyOverhang(downcast&lt;RenderRubyRun&gt;(m_current.renderer()), m_lastObject, m_nextObject);
+        downcast&lt;RenderRubyRun&gt;(m_current.renderer())-&gt;updatePriorContextFromCachedBreakIterator(m_renderTextInfo.m_lineBreakIterator);
+    } else {
+        // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element.
+        m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter);
+    }
+}
+
+inline float firstPositiveWidth(const WordMeasurements&amp; wordMeasurements)
+{
+    for (size_t i = 0; i &lt; wordMeasurements.size(); ++i) {
+        if (wordMeasurements[i].width &gt; 0)
+            return wordMeasurements[i].width;
+    }
+    return 0;
+}
+
+inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator&amp; iter, RenderCombineText&amp; renderer)
+{
+    return iter.renderer() == &amp;renderer &amp;&amp; iter.offset() &gt;= renderer.textLength();
+}
+
+inline void nextCharacter(UChar&amp; currentCharacter, UChar&amp; lastCharacter, UChar&amp; secondToLastCharacter)
+{
+    secondToLastCharacter = lastCharacter;
+    lastCharacter = currentCharacter;
+}
+
+// FIXME: Don't let counters mark themselves as needing pref width recalcs during layout
+// so we don't need this hack.
+inline void updateCounterIfNeeded(RenderText&amp; renderText)
+{
+    if (!renderText.preferredLogicalWidthsDirty() || !is&lt;RenderCounter&gt;(renderText))
+        return;
+    downcast&lt;RenderCounter&gt;(renderText).updateCounter();
+}
+
+inline float measureHyphenWidth(RenderText&amp; renderer, const FontCascade&amp; font, HashSet&lt;const Font*&gt;* fallbackFonts = 0)
+{
+    const RenderStyle&amp; style = renderer.style();
+    return font.width(RenderBlock::constructTextRun(&amp;renderer, font, style.hyphenString().string(), style), fallbackFonts);
+}
+
+ALWAYS_INLINE float textWidth(RenderText&amp; text, unsigned from, unsigned len, const FontCascade&amp; font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet&lt;const Font*&gt;&amp; fallbackFonts, TextLayout* layout = nullptr)
+{
+    const RenderStyle&amp; style = text.style();
+
+    GlyphOverflow glyphOverflow;
+    if (isFixedPitch || (!from &amp;&amp; len == text.textLength()) || style.hasTextCombine())
+        return text.width(from, len, font, xPos, &amp;fallbackFonts, &amp;glyphOverflow);
+
+    if (layout)
+        return FontCascade::width(*layout, from, len, &amp;fallbackFonts);
+
+    TextRun run = RenderBlock::constructTextRun(&amp;text, font, &amp;text, from, len, style);
+    run.setCharactersLength(text.textLength() - from);
+    ASSERT(run.charactersLength() &gt;= run.length());
+
+    run.setCharacterScanForCodePath(!text.canUseSimpleFontCodePath());
+    run.setTabSize(!collapseWhiteSpace, style.tabSize());
+    run.setXPos(xPos);
+    return font.width(run, &amp;fallbackFonts, &amp;glyphOverflow);
+}
+
+// Adding a pair of midpoints before a character will split it out into a new line box.
+inline void ensureCharacterGetsLineBox(LineMidpointState&amp; lineMidpointState, InlineIterator&amp; textParagraphSeparator)
+{
+    InlineIterator midpoint(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset());
+    lineMidpointState.startIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset() - 1));
+    lineMidpointState.stopIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset()));
+}
+
+inline void tryHyphenating(RenderText&amp; text, const FontCascade&amp; font, const AtomicString&amp; localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator&amp; lineBreak, int nextBreakable, bool&amp; hyphenated)
+{
+    // Map 'hyphenate-limit-{before,after}: auto;' to 2.
+    unsigned minimumPrefixLength;
+    unsigned minimumSuffixLength;
+
+    if (minimumPrefixLimit &lt; 0)
+        minimumPrefixLength = 2;
+    else
+        minimumPrefixLength = static_cast&lt;unsigned&gt;(minimumPrefixLimit);
+
+    if (minimumSuffixLimit &lt; 0)
+        minimumSuffixLength = 2;
+    else
+        minimumSuffixLength = static_cast&lt;unsigned&gt;(minimumSuffixLimit);
+
+    if (pos - lastSpace &lt;= minimumSuffixLength)
+        return;
+
+    if (consecutiveHyphenatedLinesLimit &gt;= 0 &amp;&amp; consecutiveHyphenatedLines &gt;= static_cast&lt;unsigned&gt;(consecutiveHyphenatedLinesLimit))
+        return;
+
+    int hyphenWidth = measureHyphenWidth(text, font);
+
+    float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
+    // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
+    // that an hyphenation opportunity exists, so do not bother to look for it.
+    if (maxPrefixWidth &lt;= font.pixelSize() * 5 / 4)
+        return;
+
+    const RenderStyle&amp; style = text.style();
+    TextRun run = RenderBlock::constructTextRun(&amp;text, font, &amp;text, lastSpace, pos - lastSpace, style);
+    run.setCharactersLength(text.textLength() - lastSpace);
+    ASSERT(run.charactersLength() &gt;= run.length());
+
+    run.setTabSize(!collapseWhiteSpace, style.tabSize());
+    run.setXPos(xPos + lastSpaceWordSpacing);
+
+    unsigned prefixLength = font.offsetForPosition(run, maxPrefixWidth, false);
+    if (prefixLength &lt; minimumPrefixLength)
+        return;
+
+    prefixLength = lastHyphenLocation(StringView(text.text()).substring(lastSpace, pos - lastSpace), std::min(prefixLength, pos - lastSpace - minimumSuffixLength) + 1, localeIdentifier);
+    if (!prefixLength || prefixLength &lt; minimumPrefixLength)
+        return;
+
+    // When lastSpace is a space, which it always is except sometimes at the beginning of a line or after collapsed
+    // space, it should not count towards hyphenate-limit-before.
+    if (prefixLength == minimumPrefixLength) {
+        UChar characterAtLastSpace = text.characterAt(lastSpace);
+        if (characterAtLastSpace == ' ' || characterAtLastSpace == '\n' || characterAtLastSpace == '\t' || characterAtLastSpace == noBreakSpace)
+            return;
+    }
+
+    ASSERT(pos - lastSpace - prefixLength &gt;= minimumSuffixLength);
+
+#if !ASSERT_DISABLED
+    HashSet&lt;const Font*&gt; fallbackFonts;
+    float prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace, fallbackFonts) + lastSpaceWordSpacing;
+    ASSERT(xPos + prefixWidth &lt;= availableWidth);
+#else
+    UNUSED_PARAM(isFixedPitch);
+#endif
+
+    lineBreak.moveTo(&amp;text, lastSpace + prefixLength, nextBreakable);
+    hyphenated = true;
+}
+
+inline bool BreakingContext::handleText(WordMeasurements&amp; wordMeasurements, bool&amp; hyphenated,  unsigned&amp; consecutiveHyphenatedLines)
+{
+    if (!m_current.offset())
+        m_appliedStartWidth = false;
+
+    RenderText&amp; renderText = downcast&lt;RenderText&gt;(*m_current.renderer());
+
+    bool isSVGText = renderText.isSVGInlineText();
+
+    // If we have left a no-wrap inline and entered an autowrap inline while ignoring spaces
+    // then we need to mark the start of the autowrap inline as a potential linebreak now.
+    if (m_autoWrap &amp;&amp; !RenderStyle::autoWrap(m_lastWS) &amp;&amp; m_ignoringSpaces)
+        commitLineBreakAtCurrentWidth(renderText);
+
+    if (renderText.style().hasTextCombine() &amp;&amp; is&lt;RenderCombineText&gt;(*m_current.renderer()) &amp;&amp; !downcast&lt;RenderCombineText&gt;(*m_current.renderer()).isCombined()) {
+        auto&amp; combineRenderer = downcast&lt;RenderCombineText&gt;(*m_current.renderer());
+        combineRenderer.combineText();
+        // The length of the renderer's text may have changed. Increment stale iterator positions
+        if (iteratorIsBeyondEndOfRenderCombineText(m_lineBreakHistory.current(), combineRenderer)) {
+            ASSERT(iteratorIsBeyondEndOfRenderCombineText(m_resolver.position(), combineRenderer));
+            m_lineBreakHistory.increment();
+            m_resolver.increment();
+        }
+    }
+
+    const RenderStyle&amp; style = lineStyle(renderText, m_lineInfo);
+    const FontCascade&amp; font = style.fontCascade();
+    bool isFixedPitch = font.isFixedPitch();
+    bool canHyphenate = style.hyphens() == HyphensAuto &amp;&amp; WebCore::canHyphenate(style.locale());
+
+    unsigned lastSpace = m_current.offset();
+    float wordSpacing = m_currentStyle-&gt;fontCascade().wordSpacing();
+    float lastSpaceWordSpacing = 0;
+    float wordSpacingForWordMeasurement = 0;
+
+    float wrapW = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, true);
+    float charWidth = 0;
+    bool breakNBSP = m_autoWrap &amp;&amp; m_currentStyle-&gt;nbspMode() == SPACE;
+    // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
+    // which is only possible if the word is the first thing on the line, that is, if |w| is zero.
+    bool breakWords = m_currentStyle-&gt;breakWords() &amp;&amp; ((m_autoWrap &amp;&amp; !m_width.committedWidth()) || m_currWS == PRE);
+    bool midWordBreak = false;
+    bool breakAll = m_currentStyle-&gt;wordBreak() == BreakAllWordBreak &amp;&amp; m_autoWrap;
+    float hyphenWidth = 0;
+    bool isLooseCJKMode = false;
+
+    if (isSVGText) {
+        breakWords = false;
+        breakAll = false;
+    }
+
+    if (m_renderTextInfo.m_text != &amp;renderText) {
+        updateCounterIfNeeded(renderText);
+        m_renderTextInfo.m_text = &amp;renderText;
+        m_renderTextInfo.m_font = &amp;font;
+        m_renderTextInfo.m_layout = font.createLayout(&amp;renderText, m_width.currentWidth(), m_collapseWhiteSpace);
+        m_renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(renderText.text(), style.locale(), mapLineBreakToIteratorMode(m_blockStyle.lineBreak()));
+        isLooseCJKMode = m_renderTextInfo.m_lineBreakIterator.isLooseCJKMode();
+    } else if (m_renderTextInfo.m_layout &amp;&amp; m_renderTextInfo.m_font != &amp;font) {
+        m_renderTextInfo.m_font = &amp;font;
+        m_renderTextInfo.m_layout = font.createLayout(&amp;renderText, m_width.currentWidth(), m_collapseWhiteSpace);
+    }
+
+    TextLayout* textLayout = m_renderTextInfo.m_layout.get();
+
+    // Non-zero only when kerning is enabled and TextLayout isn't used, in which case we measure
+    // words with their trailing space, then subtract its width.
+    HashSet&lt;const Font*&gt; fallbackFonts;
+    float wordTrailingSpaceWidth = (font.typesettingFeatures() &amp; Kerning) &amp;&amp; !textLayout ? font.width(RenderBlock::constructTextRun(&amp;renderText, font, &amp;space, 1, style), &amp;fallbackFonts) + wordSpacing : 0;
+
+    UChar lastCharacter = m_renderTextInfo.m_lineBreakIterator.lastCharacter();
+    UChar secondToLastCharacter = m_renderTextInfo.m_lineBreakIterator.secondToLastCharacter();
+    for (; m_current.offset() &lt; renderText.textLength(); m_current.fastIncrementInTextNode()) {
+        bool previousCharacterIsSpace = m_currentCharacterIsSpace;
+        bool previousCharacterIsWS = m_currentCharacterIsWS;
+        UChar c = m_current.current();
+        m_currentCharacterIsSpace = c == ' ' || c == '\t' || (!m_preservesNewline &amp;&amp; (c == '\n'));
+
+        if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace)
+            m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
+
+        if (c == softHyphen &amp;&amp; m_autoWrap &amp;&amp; !hyphenWidth &amp;&amp; style.hyphens() != HyphensNone) {
+            hyphenWidth = measureHyphenWidth(renderText, font, &amp;fallbackFonts);
+            m_width.addUncommittedWidth(hyphenWidth);
+        }
+
+        bool applyWordSpacing = false;
+
+        m_currentCharacterIsWS = m_currentCharacterIsSpace || (breakNBSP &amp;&amp; c == noBreakSpace);
+
+        if ((breakAll || breakWords) &amp;&amp; !midWordBreak &amp;&amp; (!m_currentCharacterIsSpace || style.whiteSpace() != PRE_WRAP)) {
+            wrapW += charWidth;
+            bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) &amp;&amp; m_current.offset() + 1 &lt; renderText.textLength() &amp;&amp; U16_IS_TRAIL(renderText[m_current.offset() + 1]);
+            charWidth = textWidth(renderText, m_current.offset(), midWordBreakIsBeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch, m_collapseWhiteSpace, fallbackFonts, textLayout);
+            midWordBreak = m_width.committedWidth() + wrapW + charWidth &gt; m_width.availableWidth();
+        }
+
+        int nextBreakablePosition = m_current.nextBreakablePosition();
+        bool betweenWords = c == '\n' || (m_currWS != PRE &amp;&amp; !m_atStart &amp;&amp; isBreakable(m_renderTextInfo.m_lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP, isLooseCJKMode)
+            &amp;&amp; (style.hyphens() != HyphensNone || (m_current.previousInSameNode() != softHyphen)));
+        m_current.setNextBreakablePosition(nextBreakablePosition);
+
+        if (betweenWords || midWordBreak) {
+            bool stoppedIgnoringSpaces = false;
+            if (m_ignoringSpaces) {
+                lastSpaceWordSpacing = 0;
+                if (!m_currentCharacterIsSpace) {
+                    // Stop ignoring spaces and begin at this
+                    // new point.
+                    m_ignoringSpaces = false;
+                    wordSpacingForWordMeasurement = 0;
+                    lastSpace = m_current.offset(); // e.g., &quot;Foo    goo&quot;, don't add in any of the ignored spaces.
+                    m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
+                    stoppedIgnoringSpaces = true;
+                } else {
+                    // Just keep ignoring these spaces.
+                    nextCharacter(c, lastCharacter, secondToLastCharacter);
+                    continue;
+                }
+            }
+
+            wordMeasurements.grow(wordMeasurements.size() + 1);
+            WordMeasurement&amp; wordMeasurement = wordMeasurements.last();
+
+            wordMeasurement.renderer = &amp;renderText;
+            wordMeasurement.endOffset = m_current.offset();
+            wordMeasurement.startOffset = lastSpace;
+
+            float additionalTempWidth;
+            if (wordTrailingSpaceWidth &amp;&amp; c == ' ')
+                additionalTempWidth = textWidth(renderText, lastSpace, m_current.offset() + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth;
+            else
+                additionalTempWidth = textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout);
+
+            if (wordMeasurement.fallbackFonts.isEmpty() &amp;&amp; !fallbackFonts.isEmpty())
+                wordMeasurement.fallbackFonts.swap(fallbackFonts);
+            fallbackFonts.clear();
+
+            wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeasurement;
+            additionalTempWidth += lastSpaceWordSpacing;
+            m_width.addUncommittedWidth(additionalTempWidth);
+
+            if (m_collapseWhiteSpace &amp;&amp; previousCharacterIsSpace &amp;&amp; m_currentCharacterIsSpace &amp;&amp; additionalTempWidth)
+                m_width.setTrailingWhitespaceWidth(additionalTempWidth);
+
+            if (!m_appliedStartWidth) {
+                m_width.addUncommittedWidth(inlineLogicalWidth(m_current.renderer(), true, false));
+                m_appliedStartWidth = true;
+            }
+
+            applyWordSpacing = wordSpacing &amp;&amp; m_currentCharacterIsSpace;
+
+            if (!m_width.committedWidth() &amp;&amp; m_autoWrap &amp;&amp; !m_width.fitsOnLine())
+                m_width.fitBelowFloats(m_lineInfo.isFirstLine());
+
+            if (m_autoWrap || breakWords) {
+                // If we break only after white-space, consider the current character
+                // as candidate width for this line.
+                bool lineWasTooWide = false;
+                if (m_width.fitsOnLine() &amp;&amp; m_currentCharacterIsWS &amp;&amp; m_currentStyle-&gt;breakOnlyAfterWhiteSpace() &amp;&amp; !midWordBreak) {
+                    float charWidth = textWidth(renderText, m_current.offset(), 1, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0);
+                    // Check if line is too big even without the extra space
+                    // at the end of the line. If it is not, do nothing.
+                    // If the line needs the extra whitespace to be too long,
+                    // then move the line break to the space and skip all
+                    // additional whitespace.
+                    if (!m_width.fitsOnLineIncludingExtraWidth(charWidth)) {
+                        lineWasTooWide = true;
+                        m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
+                            modifyMe.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                            m_lineBreaker.skipTrailingWhitespace(modifyMe, m_lineInfo);
+                        });
+                    }
+                }
+                if (lineWasTooWide || !m_width.fitsOnLine()) {
+                    if (canHyphenate &amp;&amp; !m_width.fitsOnLine()) {
+                        m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
+                            tryHyphenating(renderText, font, style.locale(), consecutiveHyphenatedLines, m_blockStyle.hyphenationLimitLines(), style.hyphenationLimitBefore(), style.hyphenationLimitAfter(), lastSpace, m_current.offset(), m_width.currentWidth() - additionalTempWidth, m_width.availableWidth(), isFixedPitch, m_collapseWhiteSpace, lastSpaceWordSpacing, modifyMe, m_current.nextBreakablePosition(), m_lineBreaker.m_hyphenated);
+                        });
+                        if (m_lineBreaker.m_hyphenated) {
+                            m_atEnd = true;
+                            return false;
+                        }
+                    }
+                    if (m_lineBreakHistory.atTextParagraphSeparator()) {
+                        if (!stoppedIgnoringSpaces &amp;&amp; m_current.offset() &gt; 0)
+                            ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
+                        m_lineBreakHistory.increment();
+                        m_lineInfo.setPreviousLineBrokeCleanly(true);
+                        wordMeasurement.endOffset = m_lineBreakHistory.offset();
+                    }
+                    if (m_lineBreakHistory.offset() &amp;&amp; downcast&lt;RenderText&gt;(m_lineBreakHistory.renderer()) &amp;&amp; downcast&lt;RenderText&gt;(*m_lineBreakHistory.renderer()).textLength() &amp;&amp; downcast&lt;RenderText&gt;(*m_lineBreakHistory.renderer()).characterAt(m_lineBreakHistory.offset() - 1) == softHyphen &amp;&amp; style.hyphens() != HyphensNone)
+                        hyphenated = true;
+                    if (m_lineBreakHistory.offset() &amp;&amp; m_lineBreakHistory.offset() != (unsigned)wordMeasurement.endOffset &amp;&amp; !wordMeasurement.width) {
+                        if (charWidth) {
+                            wordMeasurement.endOffset = m_lineBreakHistory.offset();
+                            wordMeasurement.width = charWidth;
+                        }
+                    }
+                    // Didn't fit. Jump to the end unless there's still an opportunity to collapse whitespace.
+                    if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSpace || !previousCharacterIsSpace) {
+                        m_atEnd = true;
+                        return false;
+                    }
+                } else {
+                    if (!betweenWords || (midWordBreak &amp;&amp; !m_autoWrap))
+                        m_width.addUncommittedWidth(-additionalTempWidth);
+                    if (hyphenWidth) {
+                        // Subtract the width of the soft hyphen out since we fit on a line.
+                        m_width.addUncommittedWidth(-hyphenWidth);
+                        hyphenWidth = 0;
+                    }
+                }
+            }
+
+            if (c == '\n' &amp;&amp; m_preservesNewline) {
+                if (!stoppedIgnoringSpaces &amp;&amp; m_current.offset())
+                    ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
+                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                m_lineBreakHistory.increment();
+                m_lineInfo.setPreviousLineBrokeCleanly(true);
+                return true;
+            }
+
+            if (m_autoWrap &amp;&amp; betweenWords) {
+                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                wrapW = 0;
+                // 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;
+            }
+
+            if (midWordBreak &amp;&amp; !U16_IS_TRAIL(c) &amp;&amp; !(U_GET_GC_MASK(c) &amp; U_GC_M_MASK)) {
+                // Remember this as a breakable position in case
+                // adding the end width forces a break.
+                m_lineBreakHistory.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+                midWordBreak &amp;= (breakWords || breakAll);
+            }
+
+            if (betweenWords) {
+                lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
+                wordSpacingForWordMeasurement = (applyWordSpacing &amp;&amp; wordMeasurement.width) ? wordSpacing : 0;
+                lastSpace = m_current.offset();
+            }
+
+            if (!m_ignoringSpaces &amp;&amp; m_currentStyle-&gt;collapseWhiteSpace()) {
+                // If we encounter a newline, or if we encounter a
+                // second space, we need to go ahead and break up this
+                // run and enter a mode where we start collapsing spaces.
+                if (m_currentCharacterIsSpace &amp;&amp; previousCharacterIsSpace) {
+                    m_ignoringSpaces = true;
+
+                    // We just entered a mode where we are ignoring
+                    // spaces. Create a midpoint to terminate the run
+                    // before the second space.
+                    m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
+                    m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
+                }
+            }
+        } else if (m_ignoringSpaces) {
+            // Stop ignoring spaces and begin at this
+            // new point.
+            m_ignoringSpaces = false;
+            lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
+            wordSpacingForWordMeasurement = (applyWordSpacing &amp;&amp; wordMeasurements.last().width) ? wordSpacing : 0;
+            lastSpace = m_current.offset(); // e.g., &quot;Foo    goo&quot;, don't add in any of the ignored spaces.
+            m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
+        }
+
+        if (isSVGText &amp;&amp; m_current.offset()) {
+            // Force creation of new InlineBoxes for each absolute positioned character (those that start new text chunks).
+            if (downcast&lt;RenderSVGInlineText&gt;(renderText).characterStartsNewTextChunk(m_current.offset()))
+                ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
+        }
+
+        if (m_currentCharacterIsSpace &amp;&amp; !previousCharacterIsSpace) {
+            m_startOfIgnoredSpaces.setRenderer(m_current.renderer());
+            m_startOfIgnoredSpaces.setOffset(m_current.offset());
+            // Spaces after right-aligned text and before a line-break get collapsed away completely so that the trailing
+            // space doesn't seem to push the text out from the right-hand edge.
+            // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results.
+            if (m_nextObject &amp;&amp; m_startOfIgnoredSpaces.offset() &amp;&amp; m_nextObject-&gt;isBR() &amp;&amp; (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT)) {
+                m_startOfIgnoredSpaces.setOffset(m_startOfIgnoredSpaces.offset() - 1);
+                // If there's just a single trailing space start ignoring it now so it collapses away.
+                if (m_current.offset() == renderText.textLength() - 1)
+                    m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
+            }
+        }
+
+        if (!m_currentCharacterIsWS &amp;&amp; previousCharacterIsWS) {
+            if (m_autoWrap &amp;&amp; m_currentStyle-&gt;breakOnlyAfterWhiteSpace())
+                m_lineBreakHistory.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
+        }
+
+        if (m_collapseWhiteSpace &amp;&amp; m_currentCharacterIsSpace &amp;&amp; !m_ignoringSpaces)
+            m_trailingObjects.setTrailingWhitespace(downcast&lt;RenderText&gt;(m_current.renderer()));
+        else if (!m_currentStyle-&gt;collapseWhiteSpace() || !m_currentCharacterIsSpace)
+            m_trailingObjects.clear();
+
+        m_atStart = false;
+        nextCharacter(c, lastCharacter, secondToLastCharacter);
+    }
+
+    m_renderTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondToLastCharacter);
+
+    wordMeasurements.grow(wordMeasurements.size() + 1);
+    WordMeasurement&amp; wordMeasurement = wordMeasurements.last();
+    wordMeasurement.renderer = &amp;renderText;
+
+    // IMPORTANT: current.m_pos is &gt; length here!
+    float additionalTempWidth = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout);
+    wordMeasurement.startOffset = lastSpace;
+    wordMeasurement.endOffset = m_current.offset();
+    wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTempWidth + wordSpacingForWordMeasurement;
+    additionalTempWidth += lastSpaceWordSpacing;
+
+    float inlineLogicalTempWidth = inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, m_includeEndWidth);
+    m_width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth);
+
+    if (wordMeasurement.fallbackFonts.isEmpty() &amp;&amp; !fallbackFonts.isEmpty())
+        wordMeasurement.fallbackFonts.swap(fallbackFonts);
+    fallbackFonts.clear();
+
+    if (m_collapseWhiteSpace &amp;&amp; m_currentCharacterIsSpace &amp;&amp; additionalTempWidth)
+        m_width.setTrailingWhitespaceWidth(additionalTempWidth, inlineLogicalTempWidth);
+
+    m_includeEndWidth = false;
+
+    if (!m_width.fitsOnLine()) {
+        if (canHyphenate) {
+            m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
+                tryHyphenating(renderText, font, style.locale(), consecutiveHyphenatedLines, m_blockStyle.hyphenationLimitLines(), style.hyphenationLimitBefore(), style.hyphenationLimitAfter(), lastSpace, m_current.offset(), m_width.currentWidth() - additionalTempWidth, m_width.availableWidth(), isFixedPitch, m_collapseWhiteSpace, lastSpaceWordSpacing, modifyMe, m_current.nextBreakablePosition(), m_lineBreaker.m_hyphenated);
+            });
+        }
+
+        if (!hyphenated &amp;&amp; m_lineBreakHistory.previousInSameNode() == softHyphen &amp;&amp; style.hyphens() != HyphensNone) {
+            hyphenated = true;
+            m_atEnd = true;
+        }
+    }
+    return false;
+}
+
+inline bool textBeginsWithBreakablePosition(RenderText&amp; nextText)
+{
+    UChar c = nextText.characterAt(0);
+    return c == ' ' || c == '\t' || (c == '\n' &amp;&amp; !nextText.preservesNewline());
+}
+
+inline bool BreakingContext::canBreakAtThisPosition()
+{
+    // If we are no-wrap and have found a line-breaking opportunity already then we should take it.
+    if (m_width.committedWidth() &amp;&amp; !m_width.fitsOnLine(m_currentCharacterIsSpace) &amp;&amp; m_currWS == NOWRAP)
+        return true;
+
+    // Avoid breaking on empty inlines.
+    if (is&lt;RenderInline&gt;(*m_current.renderer()) &amp;&amp; isEmptyInline(downcast&lt;RenderInline&gt;(*m_current.renderer())))
+        return false;
+
+    // Avoid breaking before empty inlines (as long as the current object isn't replaced).
+    if (!m_current.renderer()-&gt;isReplaced() &amp;&amp; is&lt;RenderInline&gt;(m_nextObject) &amp;&amp; isEmptyInline(downcast&lt;RenderInline&gt;(*m_nextObject)))
+        return false;
+
+    // Return early if we autowrap and the current character is a space as we will always want to break at such a position.
+    if (m_autoWrap &amp;&amp; m_currentCharacterIsSpace)
+        return true;
+
+    if (m_nextObject &amp;&amp; m_nextObject-&gt;isLineBreakOpportunity())
+        return m_autoWrap;
+
+    bool nextIsAutoWrappingText = is&lt;RenderText&gt;(m_nextObject) &amp;&amp; (m_autoWrap || m_nextObject-&gt;style().autoWrap());
+    if (!nextIsAutoWrappingText)
+        return m_autoWrap;
+    RenderText&amp; nextRenderText = downcast&lt;RenderText&gt;(*m_nextObject);
+    bool currentIsTextOrEmptyInline = is&lt;RenderText&gt;(*m_current.renderer()) || (is&lt;RenderInline&gt;(*m_current.renderer()) &amp;&amp; isEmptyInline(downcast&lt;RenderInline&gt;(*m_current.renderer())));
+    if (!currentIsTextOrEmptyInline)
+        return m_autoWrap &amp;&amp; !m_current.renderer()-&gt;isRubyRun();
+
+    bool canBreakHere = !m_currentCharacterIsSpace &amp;&amp; textBeginsWithBreakablePosition(nextRenderText);
+
+    // See if attempting to fit below floats creates more available width on the line.
+    if (!m_width.fitsOnLine() &amp;&amp; !m_width.committedWidth())
+        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
+
+    bool canPlaceOnLine = m_width.fitsOnLine() || !m_autoWrapWasEverTrueOnLine;
+
+    if (canPlaceOnLine &amp;&amp; canBreakHere)
+        commitLineBreakAtCurrentWidth(nextRenderText);
+
+    return canBreakHere;
+}
+
+inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
+{
+    bool checkForBreak = canBreakAtThisPosition();
+
+    if (checkForBreak &amp;&amp; !m_width.fitsOnLine(m_ignoringSpaces)) {
+        // if we have floats, try to get below them.
+        if (m_currentCharacterIsSpace &amp;&amp; !m_ignoringSpaces &amp;&amp; m_currentStyle-&gt;collapseWhiteSpace())
+            m_trailingObjects.clear();
+
+        if (m_width.committedWidth()) {
+            m_atEnd = true;
+            return;
+        }
+
+        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
+
+        // |width| may have been adjusted because we got shoved down past a float (thus
+        // giving us more room), so we need to retest, and only jump to
+        // the end label if we still don't fit on the line. -dwh
+        if (!m_width.fitsOnLine(m_ignoringSpaces)) {
+            m_atEnd = true;
+            return;
+        }
+    } else if (m_blockStyle.autoWrap() &amp;&amp; !m_width.fitsOnLine() &amp;&amp; !m_width.committedWidth()) {
+        // If the container autowraps but the current child does not then we still need to ensure that it
+        // wraps and moves below any floats.
+        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
+    }
+
+    if (!m_current.renderer()-&gt;isFloatingOrOutOfFlowPositioned()) {
+        m_lastObject = m_current.renderer();
+        if (m_lastObject-&gt;isReplaced() &amp;&amp; m_autoWrap &amp;&amp; !m_lastObject-&gt;isRubyRun() &amp;&amp; (!m_lastObject-&gt;isImage() || m_allowImagesToBreak) &amp;&amp; (!is&lt;RenderListMarker&gt;(*m_lastObject) || downcast&lt;RenderListMarker&gt;(*m_lastObject).isInside()))
+            commitLineBreakAtCurrentWidth(*m_nextObject);
+    }
+}
+
+inline TrailingObjects::CollapseFirstSpaceOrNot checkMidpoints(LineMidpointState&amp; lineMidpointState, const InlineIterator&amp; lBreak)
+{
+    // Check to see if our last midpoint is a start point beyond the line break. If so,
+    // shave it off the list, and shave off a trailing space if the previous end point doesn't
+    // preserve whitespace.
+    if (lBreak.renderer() &amp;&amp; lineMidpointState.numMidpoints() &amp;&amp; !(lineMidpointState.numMidpoints() % 2)) {
+        InlineIterator* midpoints = lineMidpointState.midpoints().data();
+        InlineIterator&amp; endpoint = midpoints[lineMidpointState.numMidpoints() - 2];
+        const InlineIterator&amp; startpoint = midpoints[lineMidpointState.numMidpoints() - 1];
+        InlineIterator currpoint = endpoint;
+        while (!currpoint.atEnd() &amp;&amp; currpoint != startpoint &amp;&amp; currpoint != lBreak)
+            currpoint.increment();
+        if (currpoint == lBreak) {
+            // We hit the line break before the start point. Shave off the start point.
+            lineMidpointState.decreaseNumMidpoints();
+            if (endpoint.renderer()-&gt;style().collapseWhiteSpace() &amp;&amp; endpoint.renderer()-&gt;isText()) {
+                endpoint.fastDecrement();
+                return TrailingObjects::DoNotCollapseFirstSpace;
+            }
+        }
+    }
+    return TrailingObjects::CollapseFirstSpace;
+}
+
+inline InlineIterator BreakingContext::handleEndOfLine()
+{
+    if (m_lineBreakHistory.current() == m_resolver.position()) {
+        if (!m_lineBreakHistory.renderer() || !m_lineBreakHistory.renderer()-&gt;isBR()) {
+            // we just add as much as possible
+            if (m_blockStyle.whiteSpace() == PRE &amp;&amp; !m_current.offset())
+                commitLineBreakAtCurrentWidth(*m_lastObject, m_lastObject-&gt;isText() ? m_lastObject-&gt;length() : 0);
+            else if (m_lineBreakHistory.renderer()) {
+                // Don't ever break in the middle of a word if we can help it.
+                // There's no room at all. We just have to be on this line,
+                // even though we'll spill out.
+                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset());
+            }
+        }
+        // make sure we consume at least one char/object.
+        if (m_lineBreakHistory.current() == m_resolver.position())
+            m_lineBreakHistory.increment();
+    } else if (!m_current.offset() &amp;&amp; !m_width.committedWidth() &amp;&amp; m_width.uncommittedWidth() &amp;&amp; !m_hadUncommittedWidthBeforeCurrent) {
+        // Do not push the current object to the next line, when this line has some content, but it is still considered empty.
+        // Empty inline elements like &lt;span&gt;&lt;/span&gt; can produce such lines and now we just ignore these break opportunities
+        // at the start of a line, if no width has been committed yet.
+        // Behave as if it was actually empty and consume at least one object.
+        m_lineBreakHistory.increment();
+    }
+
+    // Sanity check our midpoints.
+    TrailingObjects::CollapseFirstSpaceOrNot collapsed = checkMidpoints(m_lineMidpointState, m_lineBreakHistory.current());
+
+    m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lineBreakHistory.current(), collapsed);
+
+    // We might have made lineBreak an iterator that points past the end
+    // of the object. Do this adjustment to make it point to the start
+    // of the next object instead to avoid confusing the rest of the
+    // code.
+    if (m_lineBreakHistory.offset()) {
+        m_lineBreakHistory.update([](InlineIterator&amp; modifyMe) {
+            modifyMe.setOffset(modifyMe.offset() - 1);
+            modifyMe.increment();
+        });
+    }
+
+#if ENABLE(CSS_TRAILING_WORD)
+    if (m_blockStyle.trailingWord() == TrailingWord::PartiallyBalanced)
+        return optimalLineBreakLocationForTrailingWord();
+#endif
+    return m_lineBreakHistory.current();
+}
+
+#if ENABLE(CSS_TRAILING_WORD)
+inline InlineIterator BreakingContext::optimalLineBreakLocationForTrailingWord()
+{
+    const unsigned longTrailingWordLength = 20;
+    const float optimalTrailingLineRatio = 0.1;
+    InlineIterator lineBreak = m_lineBreakHistory.current();
+    if (!lineBreak.renderer() || !m_lineInfo.isFirstLine() || bidiNextSkippingEmptyInlines(*lineBreak.root(), lineBreak.renderer()) || !is&lt;RenderText&gt;(lineBreak.renderer()))
+        return lineBreak;
+    RenderText&amp; renderText = downcast&lt;RenderText&gt;(*lineBreak.renderer());
+    // Don't even bother measuring if our remaining line has many characters
+    if (renderText.textLength() == lineBreak.offset() || renderText.textLength() - lineBreak.offset() &gt; longTrailingWordLength)
+        return lineBreak;
+    bool isLooseCJKMode = m_renderTextInfo.m_text != &amp;renderText &amp;&amp; m_renderTextInfo.m_lineBreakIterator.isLooseCJKMode();
+    bool breakNBSP = m_autoWrap &amp;&amp; m_currentStyle-&gt;nbspMode() == SPACE;
+    int nextBreakablePosition = lineBreak.nextBreakablePosition();
+    isBreakable(m_renderTextInfo.m_lineBreakIterator, lineBreak.offset() + 1, nextBreakablePosition, breakNBSP, isLooseCJKMode);
+    if (nextBreakablePosition &lt; 0 || static_cast&lt;unsigned&gt;(nextBreakablePosition) != renderText.textLength())
+        return lineBreak;
+    const RenderStyle&amp; style = lineStyle(renderText, m_lineInfo);
+    const FontCascade&amp; font = style.fontCascade();
+    HashSet&lt;const Font*&gt; dummyFonts;
+    InlineIterator best = lineBreak;
+    for (size_t i = 1; i &lt; m_lineBreakHistory.historyLength(); ++i) {
+        const InlineIterator&amp; candidate = m_lineBreakHistory.get(i);
+        if (candidate.renderer() != lineBreak.renderer())
+            return best;
+        float width = textWidth(renderText, candidate.offset(), renderText.textLength() - candidate.offset(), font, 0, font.isFixedPitch(), m_collapseWhiteSpace, dummyFonts);
+        if (width &gt; m_width.availableWidth())
+            return best;
+        if (width / m_width.availableWidth() &gt; optimalTrailingLineRatio) // Subsequent line is long enough
+            return candidate;
+        best = candidate;
+    }
+    return best;
+}
+#endif
+
+}
+
+#endif // BreakingContext_h
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderinglineBreakingContextInlineHeadersh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/rendering/line/BreakingContextInlineHeaders.h (181170 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/line/BreakingContextInlineHeaders.h        2015-03-06 18:47:28 UTC (rev 181170)
+++ trunk/Source/WebCore/rendering/line/BreakingContextInlineHeaders.h        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -1,1202 +0,0 @@
</span><del>-/*
- * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
- * Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2013 ChangSeok Oh &lt;shivamidow@gmail.com&gt;
- * Copyright (C) 2013 Adobe Systems Inc. All right reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef BreakingContextInlineHeaders_h
-#define BreakingContextInlineHeaders_h
-
-#include &quot;Hyphenation.h&quot;
-#include &quot;LineBreaker.h&quot;
-#include &quot;LineInfo.h&quot;
-#include &quot;LineWidth.h&quot;
-#include &quot;RenderCombineText.h&quot;
-#include &quot;RenderCounter.h&quot;
-#include &quot;RenderInline.h&quot;
-#include &quot;RenderLineBreak.h&quot;
-#include &quot;RenderListMarker.h&quot;
-#include &quot;RenderRubyRun.h&quot;
-#include &quot;RenderSVGInlineText.h&quot;
-#include &quot;TrailingObjects.h&quot;
-#include &quot;break_lines.h&quot;
-#include &lt;wtf/text/StringView.h&gt;
-#include &lt;wtf/unicode/CharacterNames.h&gt;
-
-namespace WebCore {
-
-// We don't let our line box tree for a single line get any deeper than this.
-const unsigned cMaxLineDepth = 200;
-
-struct WordMeasurement {
-    WordMeasurement()
-        : renderer(0)
-        , width(0)
-        , startOffset(0)
-        , endOffset(0)
-    {
-    }
-
-    RenderText* renderer;
-    float width;
-    int startOffset;
-    int endOffset;
-    HashSet&lt;const Font*&gt; fallbackFonts;
-};
-
-class BreakingContext {
-public:
-    BreakingContext(LineBreaker&amp; lineBreaker, InlineBidiResolver&amp; resolver, LineInfo&amp; inLineInfo, LineWidth&amp; lineWidth, RenderTextInfo&amp; inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderBlockFlow&amp; block)
-        : m_lineBreaker(lineBreaker)
-        , m_resolver(resolver)
-        , m_current(resolver.position())
-#if ENABLE(CSS_TRAILING_WORD)
-        , m_lineBreakHistory(InlineIterator(resolver.position()), block.style().trailingWord() == TrailingWord::PartiallyBalanced ? 5 : 1)
-#else
-        , m_lineBreakHistory(InlineIterator(resolver.position()), 1)
-#endif
-        , m_block(block)
-        , m_lastObject(m_current.renderer())
-        , m_nextObject(nullptr)
-        , m_currentStyle(nullptr)
-        , m_blockStyle(block.style())
-        , m_lineInfo(inLineInfo)
-        , m_renderTextInfo(inRenderTextInfo)
-        , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine)
-        , m_width(lineWidth)
-        , m_currWS(NORMAL)
-        , m_lastWS(NORMAL)
-        , m_preservesNewline(false)
-        , m_atStart(true)
-        , m_ignoringSpaces(false)
-        , m_currentCharacterIsSpace(false)
-        , m_currentCharacterIsWS(false)
-        , m_appliedStartWidth(appliedStartWidth)
-        , m_includeEndWidth(true)
-        , m_autoWrap(false)
-        , m_autoWrapWasEverTrueOnLine(false)
-        , m_floatsFitOnLine(true)
-        , m_collapseWhiteSpace(false)
-        , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly())
-        , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTableCell() || !m_blockStyle.logicalWidth().isIntrinsicOrAuto())
-        , m_atEnd(false)
-        , m_hadUncommittedWidthBeforeCurrent(false)
-        , m_lineMidpointState(resolver.midpointState())
-    {
-        m_lineInfo.setPreviousLineBrokeCleanly(false);
-    }
-
-    RenderObject* currentObject() { return m_current.renderer(); }
-    InlineIterator lineBreak() { return m_lineBreakHistory.current(); }
-    LineWidth&amp; lineWidth() { return m_width; }
-    bool atEnd() { return m_atEnd; }
-
-    void initializeForCurrentObject();
-
-    void increment();
-
-    void handleBR(EClear&amp;);
-    void handleOutOfFlowPositioned(Vector&lt;RenderBox*&gt;&amp; positionedObjects);
-    void handleFloat();
-    void handleEmptyInline();
-    void handleReplaced();
-    bool handleText(WordMeasurements&amp;, bool&amp; hyphenated, unsigned&amp; consecutiveHyphenatedLines);
-    bool canBreakAtThisPosition();
-    void commitAndUpdateLineBreakIfNeeded();
-    InlineIterator handleEndOfLine();
-#if ENABLE(CSS_TRAILING_WORD)
-    InlineIterator optimalLineBreakLocationForTrailingWord();
-#endif
-
-    void clearLineBreakIfFitsOnLine(bool ignoringTrailingSpace = false)
-    {
-        if (m_width.fitsOnLine(ignoringTrailingSpace) || m_lastWS == NOWRAP)
-            m_lineBreakHistory.clear();
-    }
-
-    void commitLineBreakAtCurrentWidth(RenderObject&amp; object, unsigned offset = 0, int nextBreak = -1)
-    {
-        m_width.commit();
-        m_lineBreakHistory.moveTo(&amp;object, offset, nextBreak);
-    }
-
-private:
-    // This class keeps a sliding window of the past n locations for an InlineIterator.
-    class InlineIteratorHistory : private Vector&lt;InlineIterator, 1&gt; {
-    public:
-        InlineIteratorHistory() = delete;
-        InlineIteratorHistory(const InlineIterator&amp; initial, size_t capacity)
-            : m_capacity(capacity)
-        {
-            ASSERT(capacity &gt; 0);
-            this-&gt;append(initial);
-        }
-
-        void push(std::function&lt;void(InlineIterator&amp; modifyMe)&gt; updater)
-        {
-            ASSERT(!this-&gt;isEmpty());
-            if (m_capacity != 1)
-                this-&gt;insert(0, InlineIterator(this-&gt;at(0)));
-            updater(this-&gt;at(0));
-            if (m_capacity != 1)
-                this-&gt;resize(m_capacity);
-        }
-
-        void update(std::function&lt;void(InlineIterator&amp; modifyMe)&gt; updater)
-        {
-            ASSERT(!this-&gt;isEmpty());
-            updater(this-&gt;at(0));
-        }
-
-        RenderObject* renderer() const { return this-&gt;at(0).renderer(); }
-        unsigned offset() const { return this-&gt;at(0).offset(); }
-        bool atTextParagraphSeparator() const { return this-&gt;at(0).atTextParagraphSeparator(); }
-        UChar previousInSameNode() const { return this-&gt;at(0).previousInSameNode(); }
-        const InlineIterator&amp; get(size_t i) const { return this-&gt;at(i); };
-        const InlineIterator&amp; current() const { return get(0); }
-        size_t historyLength() const { return this-&gt;size(); }
-
-        void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1)
-        {
-            push([&amp;](InlineIterator&amp; modifyMe) {
-                modifyMe.moveTo(object, offset, nextBreak);
-            });
-        }
-
-        void increment()
-        {
-            update([](InlineIterator&amp; modifyMe) {
-                modifyMe.increment();
-            });
-        }
-
-        void clear()
-        {
-            push([](InlineIterator&amp; modifyMe) {
-                modifyMe.clear();
-            });
-        }
-
-    private:
-        const size_t m_capacity;
-    };
-
-    LineBreaker&amp; m_lineBreaker;
-    InlineBidiResolver&amp; m_resolver;
-
-    InlineIterator m_current;
-    InlineIteratorHistory m_lineBreakHistory;
-    InlineIterator m_startOfIgnoredSpaces;
-
-    RenderBlockFlow&amp; m_block;
-    RenderObject* m_lastObject;
-    RenderObject* m_nextObject;
-
-    const RenderStyle* m_currentStyle;
-
-    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
-    // very specific circumstances (in order to match common WinIE renderings).
-    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
-    RenderStyle&amp; m_blockStyle;
-
-    LineInfo&amp; m_lineInfo;
-
-    RenderTextInfo&amp; m_renderTextInfo;
-
-    FloatingObject* m_lastFloatFromPreviousLine;
-
-    LineWidth m_width;
-
-    EWhiteSpace m_currWS;
-    EWhiteSpace m_lastWS;
-
-    bool m_preservesNewline;
-    bool m_atStart;
-
-    // This variable is used only if whitespace isn't set to PRE, and it tells us whether
-    // or not we are currently ignoring whitespace.
-    bool m_ignoringSpaces;
-
-    // This variable tracks whether the very last character we saw was a space. We use
-    // this to detect when we encounter a second space so we know we have to terminate
-    // a run.
-    bool m_currentCharacterIsSpace;
-    bool m_currentCharacterIsWS;
-    bool m_appliedStartWidth;
-    bool m_includeEndWidth;
-    bool m_autoWrap;
-    bool m_autoWrapWasEverTrueOnLine;
-    bool m_floatsFitOnLine;
-    bool m_collapseWhiteSpace;
-    bool m_startingNewParagraph;
-    bool m_allowImagesToBreak;
-    bool m_atEnd;
-    bool m_hadUncommittedWidthBeforeCurrent;
-
-    LineMidpointState&amp; m_lineMidpointState;
-
-    TrailingObjects m_trailingObjects;
-};
-
-inline void BreakingContext::initializeForCurrentObject()
-{
-    m_hadUncommittedWidthBeforeCurrent = !!m_width.uncommittedWidth();
-
-    m_currentStyle = &amp;m_current.renderer()-&gt;style(); // FIXME: Should this be &amp;lineStyle(*m_current.renderer(), m_lineInfo); ?
-
-    ASSERT(m_currentStyle);
-
-    m_nextObject = bidiNextSkippingEmptyInlines(m_block, m_current.renderer());
-    if (m_nextObject &amp;&amp; m_nextObject-&gt;parent() &amp;&amp; !m_nextObject-&gt;parent()-&gt;isDescendantOf(m_current.renderer()-&gt;parent()))
-        m_includeEndWidth = true;
-
-    m_currWS = m_current.renderer()-&gt;isReplaced() ? m_current.renderer()-&gt;parent()-&gt;style().whiteSpace() : m_currentStyle-&gt;whiteSpace();
-    m_lastWS = m_lastObject-&gt;isReplaced() ? m_lastObject-&gt;parent()-&gt;style().whiteSpace() : m_lastObject-&gt;style().whiteSpace();
-
-    m_autoWrap = RenderStyle::autoWrap(m_currWS);
-    m_autoWrapWasEverTrueOnLine = m_autoWrapWasEverTrueOnLine || m_autoWrap;
-
-    m_preservesNewline = m_current.renderer()-&gt;isSVGInlineText() ? false : RenderStyle::preserveNewline(m_currWS);
-
-    m_collapseWhiteSpace = RenderStyle::collapseWhiteSpace(m_currWS);
-}
-
-inline void BreakingContext::increment()
-{
-    // Clear out our character space bool, since inline &lt;pre&gt;s don't collapse whitespace
-    // with adjacent inline normal/nowrap spans.
-    if (!m_collapseWhiteSpace)
-        m_currentCharacterIsSpace = false;
-
-    m_current.moveToStartOf(m_nextObject);
-    m_atStart = false;
-}
-
-inline void BreakingContext::handleBR(EClear&amp; clear)
-{
-    if (m_width.fitsOnLine()) {
-        RenderObject* br = m_current.renderer();
-        m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
-            modifyMe.moveToStartOf(br);
-            modifyMe.increment();
-        });
-
-        // A &lt;br&gt; always breaks a line, so don't let the line be collapsed
-        // away. Also, the space at the end of a line with a &lt;br&gt; does not
-        // get collapsed away. It only does this if the previous line broke
-        // cleanly. Otherwise the &lt;br&gt; has no effect on whether the line is
-        // empty or not.
-        if (m_startingNewParagraph)
-            m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
-        m_trailingObjects.clear();
-        m_lineInfo.setPreviousLineBrokeCleanly(true);
-
-        // A &lt;br&gt; with clearance always needs a linebox in case the lines below it get dirtied later and
-        // need to check for floats to clear - so if we're ignoring spaces, stop ignoring them and add a
-        // run for this object.
-        if (m_ignoringSpaces &amp;&amp; m_currentStyle-&gt;clear() != CNONE)
-            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(br);
-        // If we were preceded by collapsing space and are in a right-aligned container we need to ensure the space gets
-        // collapsed away so that it doesn't push the text out from the container's right-hand edge.
-        // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results.
-        else if (m_ignoringSpaces &amp;&amp; (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT))
-            m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
-
-        if (!m_lineInfo.isEmpty())
-            clear = m_currentStyle-&gt;clear();
-    }
-    m_atEnd = true;
-}
-
-inline LayoutUnit borderPaddingMarginStart(const RenderInline&amp; child)
-{
-    return child.marginStart() + child.paddingStart() + child.borderStart();
-}
-
-inline LayoutUnit borderPaddingMarginEnd(const RenderInline&amp; child)
-{
-    return child.marginEnd() + child.paddingEnd() + child.borderEnd();
-}
-
-inline bool shouldAddBorderPaddingMargin(RenderObject* child)
-{
-    if (!child)
-        return true;
-    // When deciding whether we're at the edge of an inline, adjacent collapsed whitespace is the same as no sibling at all.
-    if (is&lt;RenderText&gt;(*child) &amp;&amp; !downcast&lt;RenderText&gt;(*child).textLength())
-        return true;
-#if ENABLE(CSS_BOX_DECORATION_BREAK)
-    if (is&lt;RenderLineBreak&gt;(*child) &amp;&amp; child-&gt;parent()-&gt;style().boxDecorationBreak() == DCLONE)
-        return true;
-#endif
-    return false;
-}
-
-inline RenderObject* previousInFlowSibling(RenderObject* child)
-{
-    do {
-        child = child-&gt;previousSibling();
-    } while (child &amp;&amp; child-&gt;isOutOfFlowPositioned());
-    return child;
-}
-
-inline LayoutUnit inlineLogicalWidth(RenderObject* child, bool checkStartEdge = true, bool checkEndEdge = true)
-{
-    unsigned lineDepth = 1;
-    LayoutUnit extraWidth = 0;
-    RenderElement* parent = child-&gt;parent();
-    while (is&lt;RenderInline&gt;(*parent) &amp;&amp; lineDepth++ &lt; cMaxLineDepth) {
-        const auto&amp; parentAsRenderInline = downcast&lt;RenderInline&gt;(*parent);
-        if (!isEmptyInline(parentAsRenderInline)) {
-            checkStartEdge = checkStartEdge &amp;&amp; shouldAddBorderPaddingMargin(previousInFlowSibling(child));
-            if (checkStartEdge)
-                extraWidth += borderPaddingMarginStart(parentAsRenderInline);
-            checkEndEdge = checkEndEdge &amp;&amp; shouldAddBorderPaddingMargin(child-&gt;nextSibling());
-            if (checkEndEdge)
-                extraWidth += borderPaddingMarginEnd(parentAsRenderInline);
-            if (!checkStartEdge &amp;&amp; !checkEndEdge)
-                return extraWidth;
-        }
-        child = parent;
-        parent = child-&gt;parent();
-    }
-    return extraWidth;
-}
-
-inline void BreakingContext::handleOutOfFlowPositioned(Vector&lt;RenderBox*&gt;&amp; positionedObjects)
-{
-    // If our original display wasn't an inline type, then we can
-    // go ahead and determine our static inline position now.
-    auto&amp; box = downcast&lt;RenderBox&gt;(*m_current.renderer());
-    bool isInlineType = box.style().isOriginalDisplayInlineType();
-    if (!isInlineType)
-        m_block.setStaticInlinePositionForChild(box, m_block.logicalHeight(), m_block.startOffsetForContent(m_block.logicalHeight()));
-    else {
-        // If our original display was an INLINE type, then we can go ahead
-        // and determine our static y position now.
-        box.layer()-&gt;setStaticBlockPosition(m_block.logicalHeight());
-    }
-
-    // If we're ignoring spaces, we have to stop and include this object and
-    // then start ignoring spaces again.
-    if (isInlineType || box.container()-&gt;isRenderInline()) {
-        if (m_ignoringSpaces)
-            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(&amp;box);
-        m_trailingObjects.appendBoxIfNeeded(&amp;box);
-    } else
-        positionedObjects.append(&amp;box);
-
-    m_width.addUncommittedWidth(inlineLogicalWidth(&amp;box));
-    // Reset prior line break context characters.
-    m_renderTextInfo.m_lineBreakIterator.resetPriorContext();
-}
-
-inline void BreakingContext::handleFloat()
-{
-    auto&amp; floatBox = downcast&lt;RenderBox&gt;(*m_current.renderer());
-    FloatingObject* floatingObject = m_lineBreaker.insertFloatingObject(floatBox);
-    // check if it fits in the current line.
-    // If it does, position it now, otherwise, position
-    // it after moving to next line (in clearFloats() func)
-    if (m_floatsFitOnLine &amp;&amp; m_width.fitsOnLineExcludingTrailingWhitespace(m_block.logicalWidthForFloat(floatingObject))) {
-        m_lineBreaker.positionNewFloatOnLine(floatingObject, m_lastFloatFromPreviousLine, m_lineInfo, m_width);
-        if (m_lineBreakHistory.renderer() == m_current.renderer()) {
-            ASSERT(!m_lineBreakHistory.offset());
-            m_lineBreakHistory.increment();
-        }
-    } else
-        m_floatsFitOnLine = false;
-    // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for floating element.
-    m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter);
-}
-
-// This is currently just used for list markers and inline flows that have line boxes. Neither should
-// have an effect on whitespace at the start of the line.
-inline bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow&amp; block, RenderObject* o, LineMidpointState&amp; lineMidpointState)
-{
-    RenderObject* next = bidiNextSkippingEmptyInlines(block, o);
-    while (next &amp;&amp; next-&gt;isFloatingOrOutOfFlowPositioned())
-        next = bidiNextSkippingEmptyInlines(block, next);
-
-    if (is&lt;RenderText&gt;(next) &amp;&amp; downcast&lt;RenderText&gt;(*next).textLength() &gt; 0) {
-        RenderText&amp; nextText = downcast&lt;RenderText&gt;(*next);
-        UChar nextChar = nextText.characterAt(0);
-        if (nextText.style().isCollapsibleWhiteSpace(nextChar)) {
-            lineMidpointState.startIgnoringSpaces(InlineIterator(nullptr, o, 0));
-            return true;
-        }
-    }
-
-    return false;
-}
-
-inline void BreakingContext::handleEmptyInline()
-{
-    RenderInline&amp; flowBox = downcast&lt;RenderInline&gt;(*m_current.renderer());
-
-    // This should only end up being called on empty inlines
-    ASSERT(isEmptyInline(flowBox));
-
-    // Now that some inline flows have line boxes, if we are already ignoring spaces, we need
-    // to make sure that we stop to include this object and then start ignoring spaces again.
-    // If this object is at the start of the line, we need to behave like list markers and
-    // start ignoring spaces.
-    bool requiresLineBox = alwaysRequiresLineBox(flowBox);
-    if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) {
-        // An empty inline that only has line-height, vertical-align or font-metrics will only get a
-        // line box to affect the height of the line if the rest of the line is not empty.
-        if (requiresLineBox)
-            m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
-        if (m_ignoringSpaces) {
-            m_trailingObjects.clear();
-            m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_current.renderer());
-        } else if (m_blockStyle.collapseWhiteSpace() &amp;&amp; m_resolver.position().renderer() == m_current.renderer()
-            &amp;&amp; shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineMidpointState)) {
-            // Like with list markers, we start ignoring spaces to make sure that any
-            // additional spaces we see will be discarded.
-            m_currentCharacterIsSpace = true;
-            m_currentCharacterIsWS = true;
-            m_ignoringSpaces = true;
-        } else
-            m_trailingObjects.appendBoxIfNeeded(&amp;flowBox);
-    }
-
-    m_width.addUncommittedWidth(inlineLogicalWidth(m_current.renderer()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
-}
-
-inline void BreakingContext::handleReplaced()
-{
-    auto&amp; replacedBox = downcast&lt;RenderBox&gt;(*m_current.renderer());
-
-    if (m_atStart)
-        m_width.updateAvailableWidth(replacedBox.logicalHeight());
-
-    // Break on replaced elements if either has normal white-space.
-    if ((m_autoWrap || RenderStyle::autoWrap(m_lastWS)) &amp;&amp; (!m_current.renderer()-&gt;isImage() || m_allowImagesToBreak)
-        &amp;&amp; (!m_current.renderer()-&gt;isRubyRun() || downcast&lt;RenderRubyRun&gt;(m_current.renderer())-&gt;canBreakBefore(m_renderTextInfo.m_lineBreakIterator))) {
-        commitLineBreakAtCurrentWidth(*m_current.renderer());
-    }
-
-    if (m_ignoringSpaces)
-        m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), 0));
-
-    m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
-    m_ignoringSpaces = false;
-    m_currentCharacterIsSpace = false;
-    m_currentCharacterIsWS = false;
-    m_trailingObjects.clear();
-
-    // Optimize for a common case. If we can't find whitespace after the list
-    // item, then this is all moot.
-    LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox) + m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedBox) + inlineLogicalWidth(m_current.renderer());
-    if (is&lt;RenderListMarker&gt;(*m_current.renderer())) {
-        if (m_blockStyle.collapseWhiteSpace() &amp;&amp; shouldSkipWhitespaceAfterStartObject(m_block, m_current.renderer(), m_lineMidpointState)) {
-            // Like with inline flows, we start ignoring spaces to make sure that any
-            // additional spaces we see will be discarded.
-            m_currentCharacterIsSpace = true;
-            m_currentCharacterIsWS = false;
-            m_ignoringSpaces = true;
-        }
-        if (downcast&lt;RenderListMarker&gt;(*m_current.renderer()).isInside())
-            m_width.addUncommittedWidth(replacedLogicalWidth);
-    } else
-        m_width.addUncommittedWidth(replacedLogicalWidth);
-    if (is&lt;RenderRubyRun&gt;(*m_current.renderer())) {
-        m_width.applyOverhang(downcast&lt;RenderRubyRun&gt;(m_current.renderer()), m_lastObject, m_nextObject);
-        downcast&lt;RenderRubyRun&gt;(m_current.renderer())-&gt;updatePriorContextFromCachedBreakIterator(m_renderTextInfo.m_lineBreakIterator);
-    } else {
-        // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element.
-        m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter);
-    }
-}
-
-inline float firstPositiveWidth(const WordMeasurements&amp; wordMeasurements)
-{
-    for (size_t i = 0; i &lt; wordMeasurements.size(); ++i) {
-        if (wordMeasurements[i].width &gt; 0)
-            return wordMeasurements[i].width;
-    }
-    return 0;
-}
-
-inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator&amp; iter, RenderCombineText&amp; renderer)
-{
-    return iter.renderer() == &amp;renderer &amp;&amp; iter.offset() &gt;= renderer.textLength();
-}
-
-inline void nextCharacter(UChar&amp; currentCharacter, UChar&amp; lastCharacter, UChar&amp; secondToLastCharacter)
-{
-    secondToLastCharacter = lastCharacter;
-    lastCharacter = currentCharacter;
-}
-
-// FIXME: Don't let counters mark themselves as needing pref width recalcs during layout
-// so we don't need this hack.
-inline void updateCounterIfNeeded(RenderText&amp; renderText)
-{
-    if (!renderText.preferredLogicalWidthsDirty() || !is&lt;RenderCounter&gt;(renderText))
-        return;
-    downcast&lt;RenderCounter&gt;(renderText).updateCounter();
-}
-
-inline float measureHyphenWidth(RenderText&amp; renderer, const FontCascade&amp; font, HashSet&lt;const Font*&gt;* fallbackFonts = 0)
-{
-    const RenderStyle&amp; style = renderer.style();
-    return font.width(RenderBlock::constructTextRun(&amp;renderer, font, style.hyphenString().string(), style), fallbackFonts);
-}
-
-ALWAYS_INLINE float textWidth(RenderText&amp; text, unsigned from, unsigned len, const FontCascade&amp; font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet&lt;const Font*&gt;&amp; fallbackFonts, TextLayout* layout = nullptr)
-{
-    const RenderStyle&amp; style = text.style();
-
-    GlyphOverflow glyphOverflow;
-    if (isFixedPitch || (!from &amp;&amp; len == text.textLength()) || style.hasTextCombine())
-        return text.width(from, len, font, xPos, &amp;fallbackFonts, &amp;glyphOverflow);
-
-    if (layout)
-        return FontCascade::width(*layout, from, len, &amp;fallbackFonts);
-
-    TextRun run = RenderBlock::constructTextRun(&amp;text, font, &amp;text, from, len, style);
-    run.setCharactersLength(text.textLength() - from);
-    ASSERT(run.charactersLength() &gt;= run.length());
-
-    run.setCharacterScanForCodePath(!text.canUseSimpleFontCodePath());
-    run.setTabSize(!collapseWhiteSpace, style.tabSize());
-    run.setXPos(xPos);
-    return font.width(run, &amp;fallbackFonts, &amp;glyphOverflow);
-}
-
-// Adding a pair of midpoints before a character will split it out into a new line box.
-inline void ensureCharacterGetsLineBox(LineMidpointState&amp; lineMidpointState, InlineIterator&amp; textParagraphSeparator)
-{
-    InlineIterator midpoint(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset());
-    lineMidpointState.startIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset() - 1));
-    lineMidpointState.stopIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset()));
-}
-
-inline void tryHyphenating(RenderText&amp; text, const FontCascade&amp; font, const AtomicString&amp; localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator&amp; lineBreak, int nextBreakable, bool&amp; hyphenated)
-{
-    // Map 'hyphenate-limit-{before,after}: auto;' to 2.
-    unsigned minimumPrefixLength;
-    unsigned minimumSuffixLength;
-
-    if (minimumPrefixLimit &lt; 0)
-        minimumPrefixLength = 2;
-    else
-        minimumPrefixLength = static_cast&lt;unsigned&gt;(minimumPrefixLimit);
-
-    if (minimumSuffixLimit &lt; 0)
-        minimumSuffixLength = 2;
-    else
-        minimumSuffixLength = static_cast&lt;unsigned&gt;(minimumSuffixLimit);
-
-    if (pos - lastSpace &lt;= minimumSuffixLength)
-        return;
-
-    if (consecutiveHyphenatedLinesLimit &gt;= 0 &amp;&amp; consecutiveHyphenatedLines &gt;= static_cast&lt;unsigned&gt;(consecutiveHyphenatedLinesLimit))
-        return;
-
-    int hyphenWidth = measureHyphenWidth(text, font);
-
-    float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
-    // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
-    // that an hyphenation opportunity exists, so do not bother to look for it.
-    if (maxPrefixWidth &lt;= font.pixelSize() * 5 / 4)
-        return;
-
-    const RenderStyle&amp; style = text.style();
-    TextRun run = RenderBlock::constructTextRun(&amp;text, font, &amp;text, lastSpace, pos - lastSpace, style);
-    run.setCharactersLength(text.textLength() - lastSpace);
-    ASSERT(run.charactersLength() &gt;= run.length());
-
-    run.setTabSize(!collapseWhiteSpace, style.tabSize());
-    run.setXPos(xPos + lastSpaceWordSpacing);
-
-    unsigned prefixLength = font.offsetForPosition(run, maxPrefixWidth, false);
-    if (prefixLength &lt; minimumPrefixLength)
-        return;
-
-    prefixLength = lastHyphenLocation(StringView(text.text()).substring(lastSpace, pos - lastSpace), std::min(prefixLength, pos - lastSpace - minimumSuffixLength) + 1, localeIdentifier);
-    if (!prefixLength || prefixLength &lt; minimumPrefixLength)
-        return;
-
-    // When lastSpace is a space, which it always is except sometimes at the beginning of a line or after collapsed
-    // space, it should not count towards hyphenate-limit-before.
-    if (prefixLength == minimumPrefixLength) {
-        UChar characterAtLastSpace = text.characterAt(lastSpace);
-        if (characterAtLastSpace == ' ' || characterAtLastSpace == '\n' || characterAtLastSpace == '\t' || characterAtLastSpace == noBreakSpace)
-            return;
-    }
-
-    ASSERT(pos - lastSpace - prefixLength &gt;= minimumSuffixLength);
-
-#if !ASSERT_DISABLED
-    HashSet&lt;const Font*&gt; fallbackFonts;
-    float prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace, fallbackFonts) + lastSpaceWordSpacing;
-    ASSERT(xPos + prefixWidth &lt;= availableWidth);
-#else
-    UNUSED_PARAM(isFixedPitch);
-#endif
-
-    lineBreak.moveTo(&amp;text, lastSpace + prefixLength, nextBreakable);
-    hyphenated = true;
-}
-
-inline bool BreakingContext::handleText(WordMeasurements&amp; wordMeasurements, bool&amp; hyphenated,  unsigned&amp; consecutiveHyphenatedLines)
-{
-    if (!m_current.offset())
-        m_appliedStartWidth = false;
-
-    RenderText&amp; renderText = downcast&lt;RenderText&gt;(*m_current.renderer());
-
-    bool isSVGText = renderText.isSVGInlineText();
-
-    // If we have left a no-wrap inline and entered an autowrap inline while ignoring spaces
-    // then we need to mark the start of the autowrap inline as a potential linebreak now.
-    if (m_autoWrap &amp;&amp; !RenderStyle::autoWrap(m_lastWS) &amp;&amp; m_ignoringSpaces)
-        commitLineBreakAtCurrentWidth(renderText);
-
-    if (renderText.style().hasTextCombine() &amp;&amp; is&lt;RenderCombineText&gt;(*m_current.renderer()) &amp;&amp; !downcast&lt;RenderCombineText&gt;(*m_current.renderer()).isCombined()) {
-        auto&amp; combineRenderer = downcast&lt;RenderCombineText&gt;(*m_current.renderer());
-        combineRenderer.combineText();
-        // The length of the renderer's text may have changed. Increment stale iterator positions
-        if (iteratorIsBeyondEndOfRenderCombineText(m_lineBreakHistory.current(), combineRenderer)) {
-            ASSERT(iteratorIsBeyondEndOfRenderCombineText(m_resolver.position(), combineRenderer));
-            m_lineBreakHistory.increment();
-            m_resolver.increment();
-        }
-    }
-
-    const RenderStyle&amp; style = lineStyle(renderText, m_lineInfo);
-    const FontCascade&amp; font = style.fontCascade();
-    bool isFixedPitch = font.isFixedPitch();
-    bool canHyphenate = style.hyphens() == HyphensAuto &amp;&amp; WebCore::canHyphenate(style.locale());
-
-    unsigned lastSpace = m_current.offset();
-    float wordSpacing = m_currentStyle-&gt;fontCascade().wordSpacing();
-    float lastSpaceWordSpacing = 0;
-    float wordSpacingForWordMeasurement = 0;
-
-    float wrapW = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, true);
-    float charWidth = 0;
-    bool breakNBSP = m_autoWrap &amp;&amp; m_currentStyle-&gt;nbspMode() == SPACE;
-    // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
-    // which is only possible if the word is the first thing on the line, that is, if |w| is zero.
-    bool breakWords = m_currentStyle-&gt;breakWords() &amp;&amp; ((m_autoWrap &amp;&amp; !m_width.committedWidth()) || m_currWS == PRE);
-    bool midWordBreak = false;
-    bool breakAll = m_currentStyle-&gt;wordBreak() == BreakAllWordBreak &amp;&amp; m_autoWrap;
-    float hyphenWidth = 0;
-    bool isLooseCJKMode = false;
-
-    if (isSVGText) {
-        breakWords = false;
-        breakAll = false;
-    }
-
-    if (m_renderTextInfo.m_text != &amp;renderText) {
-        updateCounterIfNeeded(renderText);
-        m_renderTextInfo.m_text = &amp;renderText;
-        m_renderTextInfo.m_font = &amp;font;
-        m_renderTextInfo.m_layout = font.createLayout(&amp;renderText, m_width.currentWidth(), m_collapseWhiteSpace);
-        m_renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(renderText.text(), style.locale(), mapLineBreakToIteratorMode(m_blockStyle.lineBreak()));
-        isLooseCJKMode = m_renderTextInfo.m_lineBreakIterator.isLooseCJKMode();
-    } else if (m_renderTextInfo.m_layout &amp;&amp; m_renderTextInfo.m_font != &amp;font) {
-        m_renderTextInfo.m_font = &amp;font;
-        m_renderTextInfo.m_layout = font.createLayout(&amp;renderText, m_width.currentWidth(), m_collapseWhiteSpace);
-    }
-
-    TextLayout* textLayout = m_renderTextInfo.m_layout.get();
-
-    // Non-zero only when kerning is enabled and TextLayout isn't used, in which case we measure
-    // words with their trailing space, then subtract its width.
-    HashSet&lt;const Font*&gt; fallbackFonts;
-    float wordTrailingSpaceWidth = (font.typesettingFeatures() &amp; Kerning) &amp;&amp; !textLayout ? font.width(RenderBlock::constructTextRun(&amp;renderText, font, &amp;space, 1, style), &amp;fallbackFonts) + wordSpacing : 0;
-
-    UChar lastCharacter = m_renderTextInfo.m_lineBreakIterator.lastCharacter();
-    UChar secondToLastCharacter = m_renderTextInfo.m_lineBreakIterator.secondToLastCharacter();
-    for (; m_current.offset() &lt; renderText.textLength(); m_current.fastIncrementInTextNode()) {
-        bool previousCharacterIsSpace = m_currentCharacterIsSpace;
-        bool previousCharacterIsWS = m_currentCharacterIsWS;
-        UChar c = m_current.current();
-        m_currentCharacterIsSpace = c == ' ' || c == '\t' || (!m_preservesNewline &amp;&amp; (c == '\n'));
-
-        if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace)
-            m_lineInfo.setEmpty(false, &amp;m_block, &amp;m_width);
-
-        if (c == softHyphen &amp;&amp; m_autoWrap &amp;&amp; !hyphenWidth &amp;&amp; style.hyphens() != HyphensNone) {
-            hyphenWidth = measureHyphenWidth(renderText, font, &amp;fallbackFonts);
-            m_width.addUncommittedWidth(hyphenWidth);
-        }
-
-        bool applyWordSpacing = false;
-
-        m_currentCharacterIsWS = m_currentCharacterIsSpace || (breakNBSP &amp;&amp; c == noBreakSpace);
-
-        if ((breakAll || breakWords) &amp;&amp; !midWordBreak &amp;&amp; (!m_currentCharacterIsSpace || style.whiteSpace() != PRE_WRAP)) {
-            wrapW += charWidth;
-            bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) &amp;&amp; m_current.offset() + 1 &lt; renderText.textLength() &amp;&amp; U16_IS_TRAIL(renderText[m_current.offset() + 1]);
-            charWidth = textWidth(renderText, m_current.offset(), midWordBreakIsBeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch, m_collapseWhiteSpace, fallbackFonts, textLayout);
-            midWordBreak = m_width.committedWidth() + wrapW + charWidth &gt; m_width.availableWidth();
-        }
-
-        int nextBreakablePosition = m_current.nextBreakablePosition();
-        bool betweenWords = c == '\n' || (m_currWS != PRE &amp;&amp; !m_atStart &amp;&amp; isBreakable(m_renderTextInfo.m_lineBreakIterator, m_current.offset(), nextBreakablePosition, breakNBSP, isLooseCJKMode)
-            &amp;&amp; (style.hyphens() != HyphensNone || (m_current.previousInSameNode() != softHyphen)));
-        m_current.setNextBreakablePosition(nextBreakablePosition);
-
-        if (betweenWords || midWordBreak) {
-            bool stoppedIgnoringSpaces = false;
-            if (m_ignoringSpaces) {
-                lastSpaceWordSpacing = 0;
-                if (!m_currentCharacterIsSpace) {
-                    // Stop ignoring spaces and begin at this
-                    // new point.
-                    m_ignoringSpaces = false;
-                    wordSpacingForWordMeasurement = 0;
-                    lastSpace = m_current.offset(); // e.g., &quot;Foo    goo&quot;, don't add in any of the ignored spaces.
-                    m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
-                    stoppedIgnoringSpaces = true;
-                } else {
-                    // Just keep ignoring these spaces.
-                    nextCharacter(c, lastCharacter, secondToLastCharacter);
-                    continue;
-                }
-            }
-
-            wordMeasurements.grow(wordMeasurements.size() + 1);
-            WordMeasurement&amp; wordMeasurement = wordMeasurements.last();
-
-            wordMeasurement.renderer = &amp;renderText;
-            wordMeasurement.endOffset = m_current.offset();
-            wordMeasurement.startOffset = lastSpace;
-
-            float additionalTempWidth;
-            if (wordTrailingSpaceWidth &amp;&amp; c == ' ')
-                additionalTempWidth = textWidth(renderText, lastSpace, m_current.offset() + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth;
-            else
-                additionalTempWidth = textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout);
-
-            if (wordMeasurement.fallbackFonts.isEmpty() &amp;&amp; !fallbackFonts.isEmpty())
-                wordMeasurement.fallbackFonts.swap(fallbackFonts);
-            fallbackFonts.clear();
-
-            wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeasurement;
-            additionalTempWidth += lastSpaceWordSpacing;
-            m_width.addUncommittedWidth(additionalTempWidth);
-
-            if (m_collapseWhiteSpace &amp;&amp; previousCharacterIsSpace &amp;&amp; m_currentCharacterIsSpace &amp;&amp; additionalTempWidth)
-                m_width.setTrailingWhitespaceWidth(additionalTempWidth);
-
-            if (!m_appliedStartWidth) {
-                m_width.addUncommittedWidth(inlineLogicalWidth(m_current.renderer(), true, false));
-                m_appliedStartWidth = true;
-            }
-
-            applyWordSpacing = wordSpacing &amp;&amp; m_currentCharacterIsSpace;
-
-            if (!m_width.committedWidth() &amp;&amp; m_autoWrap &amp;&amp; !m_width.fitsOnLine())
-                m_width.fitBelowFloats(m_lineInfo.isFirstLine());
-
-            if (m_autoWrap || breakWords) {
-                // If we break only after white-space, consider the current character
-                // as candidate width for this line.
-                bool lineWasTooWide = false;
-                if (m_width.fitsOnLine() &amp;&amp; m_currentCharacterIsWS &amp;&amp; m_currentStyle-&gt;breakOnlyAfterWhiteSpace() &amp;&amp; !midWordBreak) {
-                    float charWidth = textWidth(renderText, m_current.offset(), 1, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0);
-                    // Check if line is too big even without the extra space
-                    // at the end of the line. If it is not, do nothing.
-                    // If the line needs the extra whitespace to be too long,
-                    // then move the line break to the space and skip all
-                    // additional whitespace.
-                    if (!m_width.fitsOnLineIncludingExtraWidth(charWidth)) {
-                        lineWasTooWide = true;
-                        m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
-                            modifyMe.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
-                            m_lineBreaker.skipTrailingWhitespace(modifyMe, m_lineInfo);
-                        });
-                    }
-                }
-                if (lineWasTooWide || !m_width.fitsOnLine()) {
-                    if (canHyphenate &amp;&amp; !m_width.fitsOnLine()) {
-                        m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
-                            tryHyphenating(renderText, font, style.locale(), consecutiveHyphenatedLines, m_blockStyle.hyphenationLimitLines(), style.hyphenationLimitBefore(), style.hyphenationLimitAfter(), lastSpace, m_current.offset(), m_width.currentWidth() - additionalTempWidth, m_width.availableWidth(), isFixedPitch, m_collapseWhiteSpace, lastSpaceWordSpacing, modifyMe, m_current.nextBreakablePosition(), m_lineBreaker.m_hyphenated);
-                        });
-                        if (m_lineBreaker.m_hyphenated) {
-                            m_atEnd = true;
-                            return false;
-                        }
-                    }
-                    if (m_lineBreakHistory.atTextParagraphSeparator()) {
-                        if (!stoppedIgnoringSpaces &amp;&amp; m_current.offset() &gt; 0)
-                            ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
-                        m_lineBreakHistory.increment();
-                        m_lineInfo.setPreviousLineBrokeCleanly(true);
-                        wordMeasurement.endOffset = m_lineBreakHistory.offset();
-                    }
-                    if (m_lineBreakHistory.offset() &amp;&amp; downcast&lt;RenderText&gt;(m_lineBreakHistory.renderer()) &amp;&amp; downcast&lt;RenderText&gt;(*m_lineBreakHistory.renderer()).textLength() &amp;&amp; downcast&lt;RenderText&gt;(*m_lineBreakHistory.renderer()).characterAt(m_lineBreakHistory.offset() - 1) == softHyphen &amp;&amp; style.hyphens() != HyphensNone)
-                        hyphenated = true;
-                    if (m_lineBreakHistory.offset() &amp;&amp; m_lineBreakHistory.offset() != (unsigned)wordMeasurement.endOffset &amp;&amp; !wordMeasurement.width) {
-                        if (charWidth) {
-                            wordMeasurement.endOffset = m_lineBreakHistory.offset();
-                            wordMeasurement.width = charWidth;
-                        }
-                    }
-                    // Didn't fit. Jump to the end unless there's still an opportunity to collapse whitespace.
-                    if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSpace || !previousCharacterIsSpace) {
-                        m_atEnd = true;
-                        return false;
-                    }
-                } else {
-                    if (!betweenWords || (midWordBreak &amp;&amp; !m_autoWrap))
-                        m_width.addUncommittedWidth(-additionalTempWidth);
-                    if (hyphenWidth) {
-                        // Subtract the width of the soft hyphen out since we fit on a line.
-                        m_width.addUncommittedWidth(-hyphenWidth);
-                        hyphenWidth = 0;
-                    }
-                }
-            }
-
-            if (c == '\n' &amp;&amp; m_preservesNewline) {
-                if (!stoppedIgnoringSpaces &amp;&amp; m_current.offset())
-                    ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
-                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
-                m_lineBreakHistory.increment();
-                m_lineInfo.setPreviousLineBrokeCleanly(true);
-                return true;
-            }
-
-            if (m_autoWrap &amp;&amp; betweenWords) {
-                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
-                wrapW = 0;
-                // 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;
-            }
-
-            if (midWordBreak &amp;&amp; !U16_IS_TRAIL(c) &amp;&amp; !(U_GET_GC_MASK(c) &amp; U_GC_M_MASK)) {
-                // Remember this as a breakable position in case
-                // adding the end width forces a break.
-                m_lineBreakHistory.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
-                midWordBreak &amp;= (breakWords || breakAll);
-            }
-
-            if (betweenWords) {
-                lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
-                wordSpacingForWordMeasurement = (applyWordSpacing &amp;&amp; wordMeasurement.width) ? wordSpacing : 0;
-                lastSpace = m_current.offset();
-            }
-
-            if (!m_ignoringSpaces &amp;&amp; m_currentStyle-&gt;collapseWhiteSpace()) {
-                // If we encounter a newline, or if we encounter a
-                // second space, we need to go ahead and break up this
-                // run and enter a mode where we start collapsing spaces.
-                if (m_currentCharacterIsSpace &amp;&amp; previousCharacterIsSpace) {
-                    m_ignoringSpaces = true;
-
-                    // We just entered a mode where we are ignoring
-                    // spaces. Create a midpoint to terminate the run
-                    // before the second space.
-                    m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
-                    m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
-                }
-            }
-        } else if (m_ignoringSpaces) {
-            // Stop ignoring spaces and begin at this
-            // new point.
-            m_ignoringSpaces = false;
-            lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
-            wordSpacingForWordMeasurement = (applyWordSpacing &amp;&amp; wordMeasurements.last().width) ? wordSpacing : 0;
-            lastSpace = m_current.offset(); // e.g., &quot;Foo    goo&quot;, don't add in any of the ignored spaces.
-            m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), m_current.offset()));
-        }
-
-        if (isSVGText &amp;&amp; m_current.offset()) {
-            // Force creation of new InlineBoxes for each absolute positioned character (those that start new text chunks).
-            if (downcast&lt;RenderSVGInlineText&gt;(renderText).characterStartsNewTextChunk(m_current.offset()))
-                ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
-        }
-
-        if (m_currentCharacterIsSpace &amp;&amp; !previousCharacterIsSpace) {
-            m_startOfIgnoredSpaces.setRenderer(m_current.renderer());
-            m_startOfIgnoredSpaces.setOffset(m_current.offset());
-            // Spaces after right-aligned text and before a line-break get collapsed away completely so that the trailing
-            // space doesn't seem to push the text out from the right-hand edge.
-            // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results.
-            if (m_nextObject &amp;&amp; m_startOfIgnoredSpaces.offset() &amp;&amp; m_nextObject-&gt;isBR() &amp;&amp; (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT)) {
-                m_startOfIgnoredSpaces.setOffset(m_startOfIgnoredSpaces.offset() - 1);
-                // If there's just a single trailing space start ignoring it now so it collapses away.
-                if (m_current.offset() == renderText.textLength() - 1)
-                    m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
-            }
-        }
-
-        if (!m_currentCharacterIsWS &amp;&amp; previousCharacterIsWS) {
-            if (m_autoWrap &amp;&amp; m_currentStyle-&gt;breakOnlyAfterWhiteSpace())
-                m_lineBreakHistory.moveTo(m_current.renderer(), m_current.offset(), m_current.nextBreakablePosition());
-        }
-
-        if (m_collapseWhiteSpace &amp;&amp; m_currentCharacterIsSpace &amp;&amp; !m_ignoringSpaces)
-            m_trailingObjects.setTrailingWhitespace(downcast&lt;RenderText&gt;(m_current.renderer()));
-        else if (!m_currentStyle-&gt;collapseWhiteSpace() || !m_currentCharacterIsSpace)
-            m_trailingObjects.clear();
-
-        m_atStart = false;
-        nextCharacter(c, lastCharacter, secondToLastCharacter);
-    }
-
-    m_renderTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondToLastCharacter);
-
-    wordMeasurements.grow(wordMeasurements.size() + 1);
-    WordMeasurement&amp; wordMeasurement = wordMeasurements.last();
-    wordMeasurement.renderer = &amp;renderText;
-
-    // IMPORTANT: current.m_pos is &gt; length here!
-    float additionalTempWidth = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout);
-    wordMeasurement.startOffset = lastSpace;
-    wordMeasurement.endOffset = m_current.offset();
-    wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTempWidth + wordSpacingForWordMeasurement;
-    additionalTempWidth += lastSpaceWordSpacing;
-
-    float inlineLogicalTempWidth = inlineLogicalWidth(m_current.renderer(), !m_appliedStartWidth, m_includeEndWidth);
-    m_width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth);
-
-    if (wordMeasurement.fallbackFonts.isEmpty() &amp;&amp; !fallbackFonts.isEmpty())
-        wordMeasurement.fallbackFonts.swap(fallbackFonts);
-    fallbackFonts.clear();
-
-    if (m_collapseWhiteSpace &amp;&amp; m_currentCharacterIsSpace &amp;&amp; additionalTempWidth)
-        m_width.setTrailingWhitespaceWidth(additionalTempWidth, inlineLogicalTempWidth);
-
-    m_includeEndWidth = false;
-
-    if (!m_width.fitsOnLine()) {
-        if (canHyphenate) {
-            m_lineBreakHistory.push([&amp;](InlineIterator&amp; modifyMe) {
-                tryHyphenating(renderText, font, style.locale(), consecutiveHyphenatedLines, m_blockStyle.hyphenationLimitLines(), style.hyphenationLimitBefore(), style.hyphenationLimitAfter(), lastSpace, m_current.offset(), m_width.currentWidth() - additionalTempWidth, m_width.availableWidth(), isFixedPitch, m_collapseWhiteSpace, lastSpaceWordSpacing, modifyMe, m_current.nextBreakablePosition(), m_lineBreaker.m_hyphenated);
-            });
-        }
-
-        if (!hyphenated &amp;&amp; m_lineBreakHistory.previousInSameNode() == softHyphen &amp;&amp; style.hyphens() != HyphensNone) {
-            hyphenated = true;
-            m_atEnd = true;
-        }
-    }
-    return false;
-}
-
-inline bool textBeginsWithBreakablePosition(RenderText&amp; nextText)
-{
-    UChar c = nextText.characterAt(0);
-    return c == ' ' || c == '\t' || (c == '\n' &amp;&amp; !nextText.preservesNewline());
-}
-
-inline bool BreakingContext::canBreakAtThisPosition()
-{
-    // If we are no-wrap and have found a line-breaking opportunity already then we should take it.
-    if (m_width.committedWidth() &amp;&amp; !m_width.fitsOnLine(m_currentCharacterIsSpace) &amp;&amp; m_currWS == NOWRAP)
-        return true;
-
-    // Avoid breaking on empty inlines.
-    if (is&lt;RenderInline&gt;(*m_current.renderer()) &amp;&amp; isEmptyInline(downcast&lt;RenderInline&gt;(*m_current.renderer())))
-        return false;
-
-    // Avoid breaking before empty inlines (as long as the current object isn't replaced).
-    if (!m_current.renderer()-&gt;isReplaced() &amp;&amp; is&lt;RenderInline&gt;(m_nextObject) &amp;&amp; isEmptyInline(downcast&lt;RenderInline&gt;(*m_nextObject)))
-        return false;
-
-    // Return early if we autowrap and the current character is a space as we will always want to break at such a position.
-    if (m_autoWrap &amp;&amp; m_currentCharacterIsSpace)
-        return true;
-
-    if (m_nextObject &amp;&amp; m_nextObject-&gt;isLineBreakOpportunity())
-        return m_autoWrap;
-
-    bool nextIsAutoWrappingText = is&lt;RenderText&gt;(m_nextObject) &amp;&amp; (m_autoWrap || m_nextObject-&gt;style().autoWrap());
-    if (!nextIsAutoWrappingText)
-        return m_autoWrap;
-    RenderText&amp; nextRenderText = downcast&lt;RenderText&gt;(*m_nextObject);
-    bool currentIsTextOrEmptyInline = is&lt;RenderText&gt;(*m_current.renderer()) || (is&lt;RenderInline&gt;(*m_current.renderer()) &amp;&amp; isEmptyInline(downcast&lt;RenderInline&gt;(*m_current.renderer())));
-    if (!currentIsTextOrEmptyInline)
-        return m_autoWrap &amp;&amp; !m_current.renderer()-&gt;isRubyRun();
-
-    bool canBreakHere = !m_currentCharacterIsSpace &amp;&amp; textBeginsWithBreakablePosition(nextRenderText);
-
-    // See if attempting to fit below floats creates more available width on the line.
-    if (!m_width.fitsOnLine() &amp;&amp; !m_width.committedWidth())
-        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
-
-    bool canPlaceOnLine = m_width.fitsOnLine() || !m_autoWrapWasEverTrueOnLine;
-
-    if (canPlaceOnLine &amp;&amp; canBreakHere)
-        commitLineBreakAtCurrentWidth(nextRenderText);
-
-    return canBreakHere;
-}
-
-inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
-{
-    bool checkForBreak = canBreakAtThisPosition();
-
-    if (checkForBreak &amp;&amp; !m_width.fitsOnLine(m_ignoringSpaces)) {
-        // if we have floats, try to get below them.
-        if (m_currentCharacterIsSpace &amp;&amp; !m_ignoringSpaces &amp;&amp; m_currentStyle-&gt;collapseWhiteSpace())
-            m_trailingObjects.clear();
-
-        if (m_width.committedWidth()) {
-            m_atEnd = true;
-            return;
-        }
-
-        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
-
-        // |width| may have been adjusted because we got shoved down past a float (thus
-        // giving us more room), so we need to retest, and only jump to
-        // the end label if we still don't fit on the line. -dwh
-        if (!m_width.fitsOnLine(m_ignoringSpaces)) {
-            m_atEnd = true;
-            return;
-        }
-    } else if (m_blockStyle.autoWrap() &amp;&amp; !m_width.fitsOnLine() &amp;&amp; !m_width.committedWidth()) {
-        // If the container autowraps but the current child does not then we still need to ensure that it
-        // wraps and moves below any floats.
-        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
-    }
-
-    if (!m_current.renderer()-&gt;isFloatingOrOutOfFlowPositioned()) {
-        m_lastObject = m_current.renderer();
-        if (m_lastObject-&gt;isReplaced() &amp;&amp; m_autoWrap &amp;&amp; !m_lastObject-&gt;isRubyRun() &amp;&amp; (!m_lastObject-&gt;isImage() || m_allowImagesToBreak) &amp;&amp; (!is&lt;RenderListMarker&gt;(*m_lastObject) || downcast&lt;RenderListMarker&gt;(*m_lastObject).isInside()))
-            commitLineBreakAtCurrentWidth(*m_nextObject);
-    }
-}
-
-inline TrailingObjects::CollapseFirstSpaceOrNot checkMidpoints(LineMidpointState&amp; lineMidpointState, const InlineIterator&amp; lBreak)
-{
-    // Check to see if our last midpoint is a start point beyond the line break. If so,
-    // shave it off the list, and shave off a trailing space if the previous end point doesn't
-    // preserve whitespace.
-    if (lBreak.renderer() &amp;&amp; lineMidpointState.numMidpoints() &amp;&amp; !(lineMidpointState.numMidpoints() % 2)) {
-        InlineIterator* midpoints = lineMidpointState.midpoints().data();
-        InlineIterator&amp; endpoint = midpoints[lineMidpointState.numMidpoints() - 2];
-        const InlineIterator&amp; startpoint = midpoints[lineMidpointState.numMidpoints() - 1];
-        InlineIterator currpoint = endpoint;
-        while (!currpoint.atEnd() &amp;&amp; currpoint != startpoint &amp;&amp; currpoint != lBreak)
-            currpoint.increment();
-        if (currpoint == lBreak) {
-            // We hit the line break before the start point. Shave off the start point.
-            lineMidpointState.decreaseNumMidpoints();
-            if (endpoint.renderer()-&gt;style().collapseWhiteSpace() &amp;&amp; endpoint.renderer()-&gt;isText()) {
-                endpoint.fastDecrement();
-                return TrailingObjects::DoNotCollapseFirstSpace;
-            }
-        }
-    }
-    return TrailingObjects::CollapseFirstSpace;
-}
-
-inline InlineIterator BreakingContext::handleEndOfLine()
-{
-    if (m_lineBreakHistory.current() == m_resolver.position()) {
-        if (!m_lineBreakHistory.renderer() || !m_lineBreakHistory.renderer()-&gt;isBR()) {
-            // we just add as much as possible
-            if (m_blockStyle.whiteSpace() == PRE &amp;&amp; !m_current.offset())
-                commitLineBreakAtCurrentWidth(*m_lastObject, m_lastObject-&gt;isText() ? m_lastObject-&gt;length() : 0);
-            else if (m_lineBreakHistory.renderer()) {
-                // Don't ever break in the middle of a word if we can help it.
-                // There's no room at all. We just have to be on this line,
-                // even though we'll spill out.
-                commitLineBreakAtCurrentWidth(*m_current.renderer(), m_current.offset());
-            }
-        }
-        // make sure we consume at least one char/object.
-        if (m_lineBreakHistory.current() == m_resolver.position())
-            m_lineBreakHistory.increment();
-    } else if (!m_current.offset() &amp;&amp; !m_width.committedWidth() &amp;&amp; m_width.uncommittedWidth() &amp;&amp; !m_hadUncommittedWidthBeforeCurrent) {
-        // Do not push the current object to the next line, when this line has some content, but it is still considered empty.
-        // Empty inline elements like &lt;span&gt;&lt;/span&gt; can produce such lines and now we just ignore these break opportunities
-        // at the start of a line, if no width has been committed yet.
-        // Behave as if it was actually empty and consume at least one object.
-        m_lineBreakHistory.increment();
-    }
-
-    // Sanity check our midpoints.
-    TrailingObjects::CollapseFirstSpaceOrNot collapsed = checkMidpoints(m_lineMidpointState, m_lineBreakHistory.current());
-
-    m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lineBreakHistory.current(), collapsed);
-
-    // We might have made lineBreak an iterator that points past the end
-    // of the object. Do this adjustment to make it point to the start
-    // of the next object instead to avoid confusing the rest of the
-    // code.
-    if (m_lineBreakHistory.offset()) {
-        m_lineBreakHistory.update([](InlineIterator&amp; modifyMe) {
-            modifyMe.setOffset(modifyMe.offset() - 1);
-            modifyMe.increment();
-        });
-    }
-
-#if ENABLE(CSS_TRAILING_WORD)
-    if (m_blockStyle.trailingWord() == TrailingWord::PartiallyBalanced)
-        return optimalLineBreakLocationForTrailingWord();
-#endif
-    return m_lineBreakHistory.current();
-}
-
-#if ENABLE(CSS_TRAILING_WORD)
-inline InlineIterator BreakingContext::optimalLineBreakLocationForTrailingWord()
-{
-    const unsigned longTrailingWordLength = 20;
-    const float optimalTrailingLineRatio = 0.1;
-    InlineIterator lineBreak = m_lineBreakHistory.current();
-    if (!lineBreak.renderer() || !m_lineInfo.isFirstLine() || bidiNextSkippingEmptyInlines(*lineBreak.root(), lineBreak.renderer()) || !is&lt;RenderText&gt;(lineBreak.renderer()))
-        return lineBreak;
-    RenderText&amp; renderText = downcast&lt;RenderText&gt;(*lineBreak.renderer());
-    // Don't even bother measuring if our remaining line has many characters
-    if (renderText.textLength() == lineBreak.offset() || renderText.textLength() - lineBreak.offset() &gt; longTrailingWordLength)
-        return lineBreak;
-    bool isLooseCJKMode = m_renderTextInfo.m_text != &amp;renderText &amp;&amp; m_renderTextInfo.m_lineBreakIterator.isLooseCJKMode();
-    bool breakNBSP = m_autoWrap &amp;&amp; m_currentStyle-&gt;nbspMode() == SPACE;
-    int nextBreakablePosition = lineBreak.nextBreakablePosition();
-    isBreakable(m_renderTextInfo.m_lineBreakIterator, lineBreak.offset() + 1, nextBreakablePosition, breakNBSP, isLooseCJKMode);
-    if (nextBreakablePosition &lt; 0 || static_cast&lt;unsigned&gt;(nextBreakablePosition) != renderText.textLength())
-        return lineBreak;
-    const RenderStyle&amp; style = lineStyle(renderText, m_lineInfo);
-    const FontCascade&amp; font = style.fontCascade();
-    HashSet&lt;const Font*&gt; dummyFonts;
-    InlineIterator best = lineBreak;
-    for (size_t i = 1; i &lt; m_lineBreakHistory.historyLength(); ++i) {
-        const InlineIterator&amp; candidate = m_lineBreakHistory.get(i);
-        if (candidate.renderer() != lineBreak.renderer())
-            return best;
-        float width = textWidth(renderText, candidate.offset(), renderText.textLength() - candidate.offset(), font, 0, font.isFixedPitch(), m_collapseWhiteSpace, dummyFonts);
-        if (width &gt; m_width.availableWidth())
-            return best;
-        if (width / m_width.availableWidth() &gt; optimalTrailingLineRatio) // Subsequent line is long enough
-            return candidate;
-        best = candidate;
-    }
-    return best;
-}
-#endif
-
-}
-
-#endif // BreakingContextInlineHeaders_h
</del></span></pre></div>
<a id="trunkSourceWebCorerenderinglineLineBreakercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/line/LineBreaker.cpp (181170 => 181171)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/line/LineBreaker.cpp        2015-03-06 18:47:28 UTC (rev 181170)
+++ trunk/Source/WebCore/rendering/line/LineBreaker.cpp        2015-03-06 19:06:30 UTC (rev 181171)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;LineBreaker.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;BreakingContextInlineHeaders.h&quot;
</del><ins>+#include &quot;BreakingContext.h&quot;
</ins><span class="cx"> #include &quot;RenderCombineText.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span></span></pre>
</div>
</div>

</body>
</html>