<!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>[176396] trunk</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/176396">176396</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2014-11-20 07:22:02 -0800 (Thu, 20 Nov 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Simple line layout: Introduce text fragment continuation.
https://bugs.webkit.org/show_bug.cgi?id=138274

Source/WebCore:

This patch extends simple line layout coverage to multiple text renderers.
When a particular render flow has multiple text renderers (but not any other type)
then we use simple line layout to process and paint the content. -other, existing requirements still apply
so that for example if the content requires decoration, we bail out of simple line layout.

FlowContent now supports multiple renderes. It continuously reads content from sibling renderers
so that the simple line layout parser sees it as one monolithic block of content. Run positions
are all relative to the block and they get resolved to renderer's positions on demand.
(painting, computing bounding rects etc)

Reviewed by Antti Koivisto.

Performance test already been added for the multiple rendere use case,
correctness is covered by existing test cases.
Test: fast/text/simple-lines-mutliple-renderers.html

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::canUseFor): Check if children are all 8bit RenderTexts.
(WebCore::SimpleLineLayout::removeTrailingWhitespace): Move the endofline check right before where we might overflow using end position.
(WebCore::SimpleLineLayout::initializeNewLine):
(WebCore::SimpleLineLayout::closeLineEndingAndAdjustRuns):
(WebCore::SimpleLineLayout::splitRunsAtRendererBoundary): Split runs at renderers' boundary to be in sync with inline text renderering.
(WebCore::SimpleLineLayout::createTextRuns):
(WebCore::SimpleLineLayout::create):
* rendering/SimpleLineLayoutFlowContents.cpp:
(WebCore::SimpleLineLayout::FlowContents::FlowContents):
(WebCore::SimpleLineLayout::FlowContents::findNextBreakablePosition):
(WebCore::SimpleLineLayout::FlowContents::findNextNonWhitespacePosition):
(WebCore::SimpleLineLayout::FlowContents::textWidth): Do not measure text across renderers. It could produce different width value due to
ligature which later can produce unexpected line breaks and out sync renderering in general.
(WebCore::SimpleLineLayout::FlowContents::renderer):
(WebCore::SimpleLineLayout::FlowContents::resolveRendererPositions):
(WebCore::SimpleLineLayout::FlowContents::appendNextRendererContentIfNeeded): Read the next renderer content if needed.
(WebCore::SimpleLineLayout::FlowContents::nextNonWhitespacePosition):
(WebCore::SimpleLineLayout::FlowContents::runWidth):
* rendering/SimpleLineLayoutFlowContents.h:
(WebCore::SimpleLineLayout::FlowContents::isNewlineCharacter):
(WebCore::SimpleLineLayout::FlowContents::isEndOfContent):
* rendering/SimpleLineLayoutResolver.cpp:
(WebCore::SimpleLineLayout::RunResolver::Run::text):

LayoutTests:

Rebaseline for simple line layout's multiple rendere support.

Reviewed by Antti Koivisto.

* fast/text/simple-lines-multiple-renderers-expected.html: Added.
* fast/text/simple-lines-multiple-renderers.html: Added.
* fast/tokenizer/script_extra_close-expected.txt: Multiple tab characters should collapse into a single whitespace. This
needs fixing in complex line layout.
* tables/mozilla/bugs/bug157890-expected.txt: no-op endofline run is added by complex inline layout
when multiple text content is injected through JS into a &lt;pre&gt;. This requires fixing complex line layout.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfasttokenizerscript_extra_closeexpectedtxt">trunk/LayoutTests/fast/tokenizer/script_extra_close-expected.txt</a></li>
<li><a href="#trunkLayoutTeststablesmozillabugsbug157890expectedtxt">trunk/LayoutTests/tables/mozilla/bugs/bug157890-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutcpp">trunk/Source/WebCore/rendering/SimpleLineLayout.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutFlowContentscpp">trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutFlowContentsh">trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h</a></li>
<li><a href="#trunkSourceWebCorerenderingSimpleLineLayoutResolvercpp">trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasttextsimplelinesmultiplerenderersexpectedhtml">trunk/LayoutTests/fast/text/simple-lines-multiple-renderers-expected.html</a></li>
<li><a href="#trunkLayoutTestsfasttextsimplelinesmultiplerenderershtml">trunk/LayoutTests/fast/text/simple-lines-multiple-renderers.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/LayoutTests/ChangeLog        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2014-11-20  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Simple line layout: Introduce text fragment continuation.
+        https://bugs.webkit.org/show_bug.cgi?id=138274
+
+        Rebaseline for simple line layout's multiple rendere support.
+
+        Reviewed by Antti Koivisto.
+
+        * fast/text/simple-lines-multiple-renderers-expected.html: Added.
+        * fast/text/simple-lines-multiple-renderers.html: Added.
+        * fast/tokenizer/script_extra_close-expected.txt: Multiple tab characters should collapse into a single whitespace. This
+        needs fixing in complex line layout.
+        * tables/mozilla/bugs/bug157890-expected.txt: no-op endofline run is added by complex inline layout
+        when multiple text content is injected through JS into a &lt;pre&gt;. This requires fixing complex line layout.
+
</ins><span class="cx"> 2014-11-19  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [OS X] Upright vertical text is completely broken for multi-code-unit codepoints
</span></span></pre></div>
<a id="trunkLayoutTestsfasttextsimplelinesmultiplerenderersexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/simple-lines-multiple-renderers-expected.html (0 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/simple-lines-multiple-renderers-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/text/simple-lines-multiple-renderers-expected.html        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that simple line layout is applied on multiple sibling text renderers.&lt;/title&gt;
+&lt;script&gt;
+  if (window.internals)
+    internals.settings.setSimpleLineLayoutDebugBordersEnabled(true);
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div id=container&gt;
+&lt;/div&gt;
+&lt;script&gt;
+  var container = document.getElementById(&quot;container&quot;);
+  container.appendChild(document.createTextNode(&quot;Quo usque tandem abutere, Catilina, patientia nostra?  quam diu etiam\n&quot;));
+  container.appendChild(document.createTextNode(&quot;furor iste tuus nos eludet?  quem ad finem sese effrenata iactabit\n&quot;));
+  container.appendChild(document.createTextNode(&quot;audacia?  Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,\n&quot;));
+  container.appendChild(document.createTextNode(&quot;nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus\n&quot;));
+  container.appendChild(document.createTextNode(&quot;habendi senatus locus, nihil horum ora voltusque moverunt?  Patere tua\n&quot;));
+  container.appendChild(document.createTextNode(&quot;consilia non sentis, constrictam iam horum omnium scientia teneri\n&quot;));
+  container.appendChild(document.createTextNode(&quot;coniurationem tuam non vides?  Quid proxima, quid superiore nocte egeris,\n&quot;));
+  container.appendChild(document.createTextNode(&quot;ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum\n&quot;));
+  container.appendChild(document.createTextNode(&quot;ignorare arbitraris?  O tempora, o mores!\n&quot;));
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasttextsimplelinesmultiplerenderershtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/simple-lines-multiple-renderers.html (0 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/simple-lines-multiple-renderers.html                                (rev 0)
+++ trunk/LayoutTests/fast/text/simple-lines-multiple-renderers.html        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that simple line layout is applied on multiple sibling text renderers.&lt;/title&gt;
+&lt;script&gt;
+  if (window.internals)
+    internals.settings.setSimpleLineLayoutDebugBordersEnabled(true);
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div&gt;
+  Quo usque tandem abutere, Catilina, patientia nostra?  quam diu etiam
+  furor iste tuus nos eludet?  quem ad finem sese effrenata iactabit
+  audacia?  Nihilne te nocturnum praesidium Palati, nihil urbis vigiliae,
+  nihil timor populi, nihil concursus bonorum omnium, nihil hic munitissimus
+  habendi senatus locus, nihil horum ora voltusque moverunt?  Patere tua
+  consilia non sentis, constrictam iam horum omnium scientia teneri
+  coniurationem tuam non vides?  Quid proxima, quid superiore nocte egeris,
+  ubi fueris, quos convocaveris, quid consilii ceperis, quem nostrum
+  ignorare arbitraris?  O tempora, o mores!
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasttokenizerscript_extra_closeexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/tokenizer/script_extra_close-expected.txt (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/tokenizer/script_extra_close-expected.txt        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/LayoutTests/fast/tokenizer/script_extra_close-expected.txt        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -1 +1 @@
</span><del>-TEST...        PASSED. This text should show up.
</del><ins>+TEST... PASSED. This text should show up.
</ins></span></pre></div>
<a id="trunkLayoutTeststablesmozillabugsbug157890expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/tables/mozilla/bugs/bug157890-expected.txt (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tables/mozilla/bugs/bug157890-expected.txt        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/LayoutTests/tables/mozilla/bugs/bug157890-expected.txt        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -71,10 +71,8 @@
</span><span class="cx">       RenderBlock {PRE} at (0,13) size 784x450
</span><span class="cx">         RenderText {#text} at (0,0) size 216x15
</span><span class="cx">           text run at (0,0) width 216: &quot;Specified table width: 25px&quot;
</span><del>-          text run at (216,0) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,15) size 216x15
</span><span class="cx">           text run at (0,15) width 216: &quot;Actual table width:    25px&quot;
</span><del>-          text run at (216,15) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,30) size 168x15
</span><span class="cx">           text run at (0,30) width 168: &quot;Specified TD widths: &quot;
</span><span class="cx">         RenderText {#text} at (168,30) size 32x15
</span><span class="lines">@@ -111,8 +109,7 @@
</span><span class="cx">           text run at (648,30) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (680,30) size 32x15
</span><span class="cx">           text run at (680,30) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (712,30) size 0x15
-          text run at (712,30) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">         RenderText {#text} at (0,45) size 168x15
</span><span class="cx">           text run at (0,45) width 168: &quot;Actual TD widths:    &quot;
</span><span class="cx">         RenderText {#text} at (168,45) size 32x15
</span><span class="lines">@@ -149,15 +146,12 @@
</span><span class="cx">           text run at (648,45) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (680,45) size 32x15
</span><span class="cx">           text run at (680,45) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (712,45) size 712x30
-          text run at (712,45) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,60) size 0x15
</ins><span class="cx">           text run at (0,60) width 0: &quot; &quot;
</span><span class="cx">         RenderText {#text} at (0,75) size 216x15
</span><span class="cx">           text run at (0,75) width 216: &quot;Specified table width: 12px&quot;
</span><del>-          text run at (216,75) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,90) size 216x15
</span><span class="cx">           text run at (0,90) width 216: &quot;Actual table width:    12px&quot;
</span><del>-          text run at (216,90) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,105) size 168x15
</span><span class="cx">           text run at (0,105) width 168: &quot;Specified TD widths: &quot;
</span><span class="cx">         RenderText {#text} at (168,105) size 32x15
</span><span class="lines">@@ -170,8 +164,7 @@
</span><span class="cx">           text run at (264,105) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (296,105) size 32x15
</span><span class="cx">           text run at (296,105) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (328,105) size 0x15
-          text run at (328,105) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">         RenderText {#text} at (0,120) size 168x15
</span><span class="cx">           text run at (0,120) width 168: &quot;Actual TD widths:    &quot;
</span><span class="cx">         RenderText {#text} at (168,120) size 32x15
</span><span class="lines">@@ -184,15 +177,12 @@
</span><span class="cx">           text run at (264,120) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (296,120) size 32x15
</span><span class="cx">           text run at (296,120) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (328,120) size 328x30
-          text run at (328,120) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,135) size 0x15
</ins><span class="cx">           text run at (0,135) width 0: &quot; &quot;
</span><span class="cx">         RenderText {#text} at (0,150) size 216x15
</span><span class="cx">           text run at (0,150) width 216: &quot;Specified table width: 13px&quot;
</span><del>-          text run at (216,150) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,165) size 216x15
</span><span class="cx">           text run at (0,165) width 216: &quot;Actual table width:    13px&quot;
</span><del>-          text run at (216,165) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,180) size 168x15
</span><span class="cx">           text run at (0,180) width 168: &quot;Specified TD widths: &quot;
</span><span class="cx">         RenderText {#text} at (168,180) size 32x15
</span><span class="lines">@@ -205,8 +195,7 @@
</span><span class="cx">           text run at (264,180) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (296,180) size 32x15
</span><span class="cx">           text run at (296,180) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (328,180) size 0x15
-          text run at (328,180) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">         RenderText {#text} at (0,195) size 168x15
</span><span class="cx">           text run at (0,195) width 168: &quot;Actual TD widths:    &quot;
</span><span class="cx">         RenderText {#text} at (168,195) size 32x15
</span><span class="lines">@@ -219,15 +208,12 @@
</span><span class="cx">           text run at (264,195) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (296,195) size 32x15
</span><span class="cx">           text run at (296,195) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (328,195) size 328x30
-          text run at (328,195) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,210) size 0x15
</ins><span class="cx">           text run at (0,210) width 0: &quot; &quot;
</span><span class="cx">         RenderText {#text} at (0,225) size 216x15
</span><span class="cx">           text run at (0,225) width 216: &quot;Specified table width: 24px&quot;
</span><del>-          text run at (216,225) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,240) size 216x15
</span><span class="cx">           text run at (0,240) width 216: &quot;Actual table width:    24px&quot;
</span><del>-          text run at (216,240) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,255) size 168x15
</span><span class="cx">           text run at (0,255) width 168: &quot;Specified TD widths: &quot;
</span><span class="cx">         RenderText {#text} at (168,255) size 32x15
</span><span class="lines">@@ -240,8 +226,7 @@
</span><span class="cx">           text run at (264,255) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (296,255) size 32x15
</span><span class="cx">           text run at (296,255) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (328,255) size 0x15
-          text run at (328,255) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">         RenderText {#text} at (0,270) size 168x15
</span><span class="cx">           text run at (0,270) width 168: &quot;Actual TD widths:    &quot;
</span><span class="cx">         RenderText {#text} at (168,270) size 32x15
</span><span class="lines">@@ -254,15 +239,12 @@
</span><span class="cx">           text run at (264,270) width 32: &quot;2px &quot;
</span><span class="cx">         RenderText {#text} at (296,270) size 40x15
</span><span class="cx">           text run at (296,270) width 40: &quot;16px &quot;
</span><del>-        RenderText {#text} at (336,270) size 336x30
-          text run at (336,270) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,285) size 0x15
</ins><span class="cx">           text run at (0,285) width 0: &quot; &quot;
</span><span class="cx">         RenderText {#text} at (0,300) size 216x15
</span><span class="cx">           text run at (0,300) width 216: &quot;Specified table width: 25px&quot;
</span><del>-          text run at (216,300) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,315) size 216x15
</span><span class="cx">           text run at (0,315) width 216: &quot;Actual table width:    25px&quot;
</span><del>-          text run at (216,315) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,330) size 168x15
</span><span class="cx">           text run at (0,330) width 168: &quot;Specified TD widths: &quot;
</span><span class="cx">         RenderText {#text} at (168,330) size 32x15
</span><span class="lines">@@ -275,8 +257,7 @@
</span><span class="cx">           text run at (264,330) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (296,330) size 32x15
</span><span class="cx">           text run at (296,330) width 32: &quot;8px &quot;
</span><del>-        RenderText {#text} at (328,330) size 0x15
-          text run at (328,330) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">         RenderText {#text} at (0,345) size 168x15
</span><span class="cx">           text run at (0,345) width 168: &quot;Actual TD widths:    &quot;
</span><span class="cx">         RenderText {#text} at (168,345) size 32x15
</span><span class="lines">@@ -289,15 +270,12 @@
</span><span class="cx">           text run at (264,345) width 32: &quot;2px &quot;
</span><span class="cx">         RenderText {#text} at (296,345) size 40x15
</span><span class="cx">           text run at (296,345) width 40: &quot;16px &quot;
</span><del>-        RenderText {#text} at (336,345) size 336x30
-          text run at (336,345) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,360) size 0x15
</ins><span class="cx">           text run at (0,360) width 0: &quot; &quot;
</span><span class="cx">         RenderText {#text} at (0,375) size 216x15
</span><span class="cx">           text run at (0,375) width 216: &quot;Specified table width: 17px&quot;
</span><del>-          text run at (216,375) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,390) size 216x15
</span><span class="cx">           text run at (0,390) width 216: &quot;Actual table width:    17px&quot;
</span><del>-          text run at (216,390) width 0: &quot; &quot;
</del><span class="cx">         RenderText {#text} at (0,405) size 168x15
</span><span class="cx">           text run at (0,405) width 168: &quot;Specified TD widths: &quot;
</span><span class="cx">         RenderText {#text} at (168,405) size 32x15
</span><span class="lines">@@ -320,8 +298,7 @@
</span><span class="cx">           text run at (424,405) width 32: &quot;10% &quot;
</span><span class="cx">         RenderText {#text} at (456,405) size 32x15
</span><span class="cx">           text run at (456,405) width 32: &quot;10% &quot;
</span><del>-        RenderText {#text} at (488,405) size 0x15
-          text run at (488,405) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,0) size 0x0
</ins><span class="cx">         RenderText {#text} at (0,420) size 168x15
</span><span class="cx">           text run at (0,420) width 168: &quot;Actual TD widths:    &quot;
</span><span class="cx">         RenderText {#text} at (168,420) size 32x15
</span><span class="lines">@@ -344,6 +321,5 @@
</span><span class="cx">           text run at (424,420) width 32: &quot;1px &quot;
</span><span class="cx">         RenderText {#text} at (456,420) size 32x15
</span><span class="cx">           text run at (456,420) width 32: &quot;1px &quot;
</span><del>-        RenderText {#text} at (488,420) size 488x30
-          text run at (488,420) width 0: &quot; &quot;
</del><ins>+        RenderText {#text} at (0,435) size 0x15
</ins><span class="cx">           text run at (0,435) width 0: &quot; &quot;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/Source/WebCore/ChangeLog        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2014-11-20  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Simple line layout: Introduce text fragment continuation.
+        https://bugs.webkit.org/show_bug.cgi?id=138274
+
+        This patch extends simple line layout coverage to multiple text renderers.
+        When a particular render flow has multiple text renderers (but not any other type)
+        then we use simple line layout to process and paint the content. -other, existing requirements still apply
+        so that for example if the content requires decoration, we bail out of simple line layout.
+
+        FlowContent now supports multiple renderes. It continuously reads content from sibling renderers
+        so that the simple line layout parser sees it as one monolithic block of content. Run positions
+        are all relative to the block and they get resolved to renderer's positions on demand.
+        (painting, computing bounding rects etc)
+
+        Reviewed by Antti Koivisto.
+
+        Performance test already been added for the multiple rendere use case,
+        correctness is covered by existing test cases.
+        Test: fast/text/simple-lines-mutliple-renderers.html
+
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::canUseFor): Check if children are all 8bit RenderTexts.
+        (WebCore::SimpleLineLayout::removeTrailingWhitespace): Move the endofline check right before where we might overflow using end position.
+        (WebCore::SimpleLineLayout::initializeNewLine):
+        (WebCore::SimpleLineLayout::closeLineEndingAndAdjustRuns):
+        (WebCore::SimpleLineLayout::splitRunsAtRendererBoundary): Split runs at renderers' boundary to be in sync with inline text renderering.
+        (WebCore::SimpleLineLayout::createTextRuns):
+        (WebCore::SimpleLineLayout::create):
+        * rendering/SimpleLineLayoutFlowContents.cpp:
+        (WebCore::SimpleLineLayout::FlowContents::FlowContents):
+        (WebCore::SimpleLineLayout::FlowContents::findNextBreakablePosition):
+        (WebCore::SimpleLineLayout::FlowContents::findNextNonWhitespacePosition):
+        (WebCore::SimpleLineLayout::FlowContents::textWidth): Do not measure text across renderers. It could produce different width value due to
+        ligature which later can produce unexpected line breaks and out sync renderering in general.
+        (WebCore::SimpleLineLayout::FlowContents::renderer): 
+        (WebCore::SimpleLineLayout::FlowContents::resolveRendererPositions):
+        (WebCore::SimpleLineLayout::FlowContents::appendNextRendererContentIfNeeded): Read the next renderer content if needed.
+        (WebCore::SimpleLineLayout::FlowContents::nextNonWhitespacePosition):
+        (WebCore::SimpleLineLayout::FlowContents::runWidth):
+        * rendering/SimpleLineLayoutFlowContents.h:
+        (WebCore::SimpleLineLayout::FlowContents::isNewlineCharacter):
+        (WebCore::SimpleLineLayout::FlowContents::isEndOfContent):
+        * rendering/SimpleLineLayoutResolver.cpp:
+        (WebCore::SimpleLineLayout::RunResolver::Run::text):
+
</ins><span class="cx"> 2014-11-20  peavo@outlook.com  &lt;peavo@outlook.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [WinCairo] Compile error when GStreamer is enabled.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;LineWidth.h&quot;
</span><span class="cx"> #include &quot;PaintInfo.h&quot;
</span><span class="cx"> #include &quot;RenderBlockFlow.h&quot;
</span><ins>+#include &quot;RenderChildIterator.h&quot;
</ins><span class="cx"> #include &quot;RenderStyle.h&quot;
</span><span class="cx"> #include &quot;RenderText.h&quot;
</span><span class="cx"> #include &quot;RenderTextControl.h&quot;
</span><span class="lines">@@ -93,14 +94,12 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!flow.firstChild())
</span><span class="cx">         return false;
</span><del>-    // This currently covers &lt;blockflow&gt;#text&lt;/blockflow&gt; case.
</del><ins>+    // This currently covers &lt;blockflow&gt;#text&lt;/blockflow&gt; and mutiple (sibling) RenderText cases.
</ins><span class="cx">     // The &lt;blockflow&gt;&lt;inline&gt;#text&lt;/inline&gt;&lt;/blockflow&gt; case is also popular and should be relatively easy to cover.
</span><del>-    if (flow.firstChild() != flow.lastChild())
-        return false;
-    if (!is&lt;RenderText&gt;(flow.firstChild()))
-        return false;
-    if (!downcast&lt;RenderText&gt;(*flow.firstChild()).text()-&gt;is8Bit())
-        return false;
</del><ins>+    for (const auto&amp; renderer : childrenOfType&lt;RenderObject&gt;(flow)) {
+        if (!is&lt;RenderText&gt;(renderer) || !downcast&lt;RenderText&gt;(renderer).text()-&gt;is8Bit())
+            return false;
+    }
</ins><span class="cx">     if (!flow.isHorizontalWritingMode())
</span><span class="cx">         return false;
</span><span class="cx">     if (flow.flowThreadState() != RenderObject::NotInsideFlowThread)
</span><span class="lines">@@ -406,10 +405,8 @@
</span><span class="cx">         lineState.removeCommittedTrailingWhitespace();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (flowContents.isEndOfContent(lineState.position))
-        return;
</del><span class="cx">     // If we skipped any whitespace and now the line end is a &quot;preserved&quot; newline, skip the newline too as we are wrapping the line here already.
</span><del>-    if (lastPosition != lineState.position &amp;&amp; style.preserveNewline &amp;&amp; flowContents.isNewlineCharacter(lineState.position))
</del><ins>+    if (lastPosition != lineState.position &amp;&amp; style.preserveNewline &amp;&amp; !flowContents.isEndOfContent(lineState.position) &amp;&amp; flowContents.isNewlineCharacter(lineState.position))
</ins><span class="cx">         ++lineState.position;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -471,7 +468,7 @@
</span><span class="cx">     return fragmentForNextLine;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static TextFragment nextFragment(unsigned previousFragmentEnd, FlowContents&amp; flowContents, float xPosition)
</del><ins>+static TextFragment nextFragment(unsigned previousFragmentEnd, const FlowContents&amp; flowContents, float xPosition)
</ins><span class="cx"> {
</span><span class="cx">     // A fragment can have
</span><span class="cx">     // 1. new line character when preserveNewline is on (not considered as whitespace) or
</span><span class="lines">@@ -510,7 +507,7 @@
</span><span class="cx">     return fragment;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool createLineRuns(LineState&amp; lineState, Layout::RunVector&amp; lineRuns, FlowContents&amp; flowContents)
</del><ins>+static bool createLineRuns(LineState&amp; lineState, Layout::RunVector&amp; lineRuns, const FlowContents&amp; flowContents)
</ins><span class="cx"> {
</span><span class="cx">     const auto&amp; style = flowContents.style();
</span><span class="cx">     bool lineCanBeWrapped = style.wrapLines || style.breakWordOnOverflow;
</span><span class="lines">@@ -586,6 +583,34 @@
</span><span class="cx">     ++lineCount;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void splitRunsAtRendererBoundary(Layout::RunVector&amp; lineRuns, const FlowContents&amp; flowContents)
+{
+    if (!lineRuns.size())
+        return;
+
+    unsigned runIndex = 0;
+    do {
+        const Run&amp; run = lineRuns.at(runIndex);
+        ASSERT(run.start != run.end);
+        const RenderText* startRenderer = flowContents.renderer(run.start);
+        const RenderText* endRenderer = flowContents.renderer(run.end - 1);
+        if (startRenderer == endRenderer)
+            continue;
+        // This run overlaps multiple renderers. Split it up.
+        unsigned rendererStartPosition = 0;
+        unsigned rendererEndPosition = 0;
+        bool found = flowContents.resolveRendererPositions(*startRenderer, rendererStartPosition, rendererEndPosition);
+        ASSERT_UNUSED(found, found);
+
+        // Split run at the renderer's boundary and create a new run for the left side, while use the current run as the right side.
+        float logicalRightOfLeftRun = run.logicalLeft + flowContents.textWidth(run.start, rendererEndPosition, run.logicalLeft);
+        lineRuns.insert(runIndex, Run(run.start, rendererEndPosition, run.logicalLeft, logicalRightOfLeftRun, false));
+        Run&amp; rightSideRun = lineRuns.at(runIndex + 1);
+        rightSideRun.start = rendererEndPosition;
+        rightSideRun.logicalLeft = logicalRightOfLeftRun;
+    } while (++runIndex &lt; lineRuns.size());
+}
+
</ins><span class="cx"> static void updateLineConstrains(const RenderBlockFlow&amp; flow, float&amp; availableWidth, float&amp; logicalLeftOffset)
</span><span class="cx"> {
</span><span class="cx">     LayoutUnit height = flow.logicalHeight();
</span><span class="lines">@@ -610,6 +635,9 @@
</span><span class="cx">         isEndOfContent = createLineRuns(lineState, runs, flowContents);
</span><span class="cx">         closeLineEndingAndAdjustRuns(lineState, runs, lineCount, flowContents);
</span><span class="cx">     } while (!isEndOfContent);
</span><ins>+
+    if (flow.firstChild() != flow.lastChild())
+        splitRunsAtRendererBoundary(runs, flowContents);
</ins><span class="cx">     ASSERT(!lineState.uncommittedWidth);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -617,11 +645,12 @@
</span><span class="cx"> {
</span><span class="cx">     unsigned lineCount = 0;
</span><span class="cx">     Layout::RunVector runs;
</span><del>-    RenderText&amp; textRenderer = downcast&lt;RenderText&gt;(*flow.firstChild());
-    ASSERT(!textRenderer.firstTextBox());
</del><span class="cx"> 
</span><span class="cx">     createTextRuns(runs, flow, lineCount);
</span><del>-    textRenderer.clearNeedsLayout();
</del><ins>+    for (auto&amp; renderer : childrenOfType&lt;RenderObject&gt;(flow)) {
+        ASSERT(is&lt;RenderText&gt;(renderer));
+        renderer.clearNeedsLayout();
+    }
</ins><span class="cx">     return Layout::create(runs, lineCount);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutFlowContentscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.cpp        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -27,6 +27,8 @@
</span><span class="cx"> #include &quot;SimpleLineLayoutFlowContents.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;RenderBlockFlow.h&quot;
</span><ins>+#include &quot;RenderChildIterator.h&quot;
+#include &quot;RenderText.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace SimpleLineLayout {
</span><span class="lines">@@ -35,21 +37,135 @@
</span><span class="cx">     : m_flow(flow)
</span><span class="cx">     , m_style(flow.style())
</span><span class="cx">     , m_lineBreakIterator(downcast&lt;RenderText&gt;(*flow.firstChild()).text(), flow.style().locale())
</span><ins>+    , m_lastRendererIndex(0)
</ins><span class="cx"> {
</span><ins>+    unsigned startPosition = 0;
+    for (const RenderText* textRenderer = downcast&lt;RenderText&gt;(m_flow.firstChild()); textRenderer; textRenderer = downcast&lt;RenderText&gt;(textRenderer-&gt;nextSibling())) {
+        unsigned contentLength = textRenderer-&gt;text()-&gt;length();
+        m_textRanges.append(std::make_pair(startPosition, textRenderer));
+        startPosition += contentLength;
+    }
+    // End item.
+    const RenderText* closingNullItem = nullptr;
+    m_textRanges.append(std::make_pair(startPosition, closingNullItem));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned FlowContents::findNextBreakablePosition(unsigned position)
</del><ins>+unsigned FlowContents::findNextBreakablePosition(unsigned position) const
</ins><span class="cx"> {
</span><span class="cx">     String string = m_lineBreakIterator.string();
</span><del>-    return nextBreakablePosition&lt;LChar, false&gt;(m_lineBreakIterator, string.characters8(), string.length(), position);
</del><ins>+    unsigned breakablePosition = nextBreakablePosition&lt;LChar, false&gt;(m_lineBreakIterator, string.characters8(), string.length(), position);
+    if (appendNextRendererContentIfNeeded(breakablePosition))
+        return findNextBreakablePosition(position);
+    ASSERT(breakablePosition &gt;= position);
+    return breakablePosition;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned FlowContents::findNextNonWhitespacePosition(unsigned position, unsigned&amp; spaceCount) const
</span><span class="cx"> {
</span><ins>+    unsigned nonWhitespacePosition = nextNonWhitespacePosition(position, spaceCount);
+    if (appendNextRendererContentIfNeeded(nonWhitespacePosition))
+        return findNextNonWhitespacePosition(position, spaceCount);
+    ASSERT(nonWhitespacePosition &gt;= position);
+    return nonWhitespacePosition;
+}
+
+float FlowContents::textWidth(unsigned from, unsigned to, float xPosition) const
+{
+    unsigned rendererStart = 0;
+    const RenderText* textRenderer = renderer(from, &amp;rendererStart);
+    ASSERT(textRenderer);
+    // Resolved positions are relative to the renderers.
+    unsigned absoluteStart = from - rendererStart;
+    unsigned absoluteEnd = to - rendererStart;
+    if ((m_style.font.isFixedPitch() &amp;&amp; textRenderer == renderer(to)) || (!absoluteStart &amp;&amp; absoluteEnd == textRenderer-&gt;text()-&gt;length()))
+        return textRenderer-&gt;width(absoluteStart, to - from, m_style.font, xPosition, nullptr, nullptr);
+
+    // We need to split up the text and measure renderers individually due to ligature.
+    float textWidth = 0;
+    unsigned fragmentEnd = 0;
+    do {
+        fragmentEnd = std::min(to, rendererStart + textRenderer-&gt;text()-&gt;length());
+        unsigned absoluteFragmentEnd = fragmentEnd - rendererStart;
+        absoluteStart = from - rendererStart;
+        textWidth += runWidth(*textRenderer, absoluteStart, absoluteFragmentEnd, xPosition + textWidth);
+        from = fragmentEnd;
+        if (fragmentEnd &lt; to)
+            textRenderer = renderer(fragmentEnd, &amp;rendererStart);
+    } while (fragmentEnd &lt; to &amp;&amp; textRenderer);
+    return textWidth;
+}
+
+const RenderText* FlowContents::renderer(unsigned position, unsigned* rendererStartPosition) const
+{
+    unsigned arraySize = m_textRanges.size();
+    // Take advantage of the usage pattern.
+    if (position &gt;= m_textRanges.at(m_lastRendererIndex).first &amp;&amp; m_lastRendererIndex + 1 &lt; arraySize &amp;&amp; position &lt; m_textRanges.at(m_lastRendererIndex + 1).first) {
+        if (rendererStartPosition)
+            *rendererStartPosition = m_textRanges.at(m_lastRendererIndex).first;
+        return m_textRanges.at(m_lastRendererIndex).second;
+    }
+    unsigned left = 0;
+    unsigned right = arraySize - 1;
+    ASSERT(arraySize);
+    ASSERT(position &gt;= 0);
+    while (left &lt; right) {
+        unsigned middle = (left + right) / 2;
+        unsigned endPosition = m_textRanges.at(middle + 1).first;
+        if (position &gt; endPosition)
+            left = middle + 1;
+        else if (position &lt; endPosition)
+            right = middle;
+        else {
+            right = middle + 1;
+            break;
+        }
+    }
+    if (rendererStartPosition)
+        *rendererStartPosition = m_textRanges.at(right).first;
+    return m_textRanges.at(right).second;
+}
+
+bool FlowContents::resolveRendererPositions(const RenderText&amp; renderer, unsigned&amp; startPosition, unsigned&amp; endPosition) const
+{
+    unsigned arraySize = m_textRanges.size();
+    if (!arraySize)
+        return false;
+
+    unsigned index = 0;
+    do {
+        auto range = m_textRanges.at(index);
+        if (range.second == &amp;renderer) {
+            startPosition = range.first;
+            ASSERT(index + 1 &lt; arraySize);
+            endPosition = m_textRanges.at(index + 1).first;
+            return true;
+        }
+    } while (++index &lt; arraySize);
+    return false;
+}
+
+bool FlowContents::appendNextRendererContentIfNeeded(unsigned position) const
+{
</ins><span class="cx">     String string = m_lineBreakIterator.string();
</span><ins>+    if (position &lt; string.length())
+        return false;
+
+    // Content needs to be requested sequentially.
+    ASSERT(position == string.length());
+    const RenderText* nextRenderer = renderer(position);
+    if (!nextRenderer)
+        return false;
+
+    ++m_lastRendererIndex;
+    m_lineBreakIterator.resetStringAndReleaseIterator(string + String(nextRenderer-&gt;text()), m_flow.style().locale());
+    return true;
+}
+
+unsigned FlowContents::nextNonWhitespacePosition(unsigned position, unsigned&amp; spaceCount) const
+{
+    String string = m_lineBreakIterator.string();
</ins><span class="cx">     unsigned length = string.length();
</span><span class="cx">     const LChar* text = string.characters8();
</span><del>-    spaceCount = 0;
</del><span class="cx">     for (; position &lt; length; ++position) {
</span><span class="cx">         bool isSpace = text[position] == ' ';
</span><span class="cx">         if (!(isSpace || text[position] == '\t' || (!m_style.preserveNewline &amp;&amp; text[position] == '\n')))
</span><span class="lines">@@ -60,35 +176,15 @@
</span><span class="cx">     return length;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-float FlowContents::textWidth(unsigned from, unsigned to, float xPosition) const
</del><ins>+float FlowContents::runWidth(const RenderText&amp; renderer, unsigned from, unsigned to, float xPosition) const
</ins><span class="cx"> {
</span><del>-    String string = m_lineBreakIterator.string();
-    unsigned length = string.length();
-    if (m_style.font.isFixedPitch() || (!from &amp;&amp; to == length)) {
-        const RenderText&amp; renderer = downcast&lt;RenderText&gt;(*m_flow.firstChild());
-        return renderer.width(from, to - from, m_style.font, xPosition, nullptr, nullptr);
-    }
-
</del><ins>+    ASSERT(from &lt; to);
+    String string = renderer.text();
</ins><span class="cx">     TextRun run(string.characters8() + from, to - from);
</span><span class="cx">     run.setXPos(xPosition);
</span><del>-    run.setCharactersLength(length - from);
</del><span class="cx">     run.setTabSize(!!m_style.tabWidth, m_style.tabWidth);
</span><del>-    ASSERT(run.charactersLength() &gt;= run.length());
</del><span class="cx">     return m_style.font.width(run);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool FlowContents::resolveRendererPositions(const RenderText&amp; renderer, unsigned&amp; startPosition, unsigned&amp; endPosition) const
-{
-    ASSERT(&amp;renderer == downcast&lt;RenderText&gt;(m_flow.firstChild()));
-    startPosition = 0;
-    endPosition = renderer.text()-&gt;length();
-    return true;
</del><span class="cx"> }
</span><del>-
-const RenderText&amp; FlowContents::renderer(unsigned) const
-{
-    return downcast&lt;RenderText&gt;(*m_flow.firstChild());
</del><span class="cx"> }
</span><del>-
-}
-}
</del></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutFlowContentsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> public:
</span><span class="cx">     FlowContents(const RenderBlockFlow&amp;);
</span><span class="cx"> 
</span><del>-    unsigned findNextBreakablePosition(unsigned position);
</del><ins>+    unsigned findNextBreakablePosition(unsigned position) const;
</ins><span class="cx">     unsigned findNextNonWhitespacePosition(unsigned position, unsigned&amp; spaceCount) const;
</span><span class="cx"> 
</span><span class="cx">     float textWidth(unsigned from, unsigned to, float xPosition) const;
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">     bool isEndOfContent(unsigned position) const;
</span><span class="cx"> 
</span><span class="cx">     bool resolveRendererPositions(const RenderText&amp;, unsigned&amp; startPosition, unsigned&amp; endPosition) const;
</span><del>-    const RenderText&amp; renderer(unsigned position) const;
</del><ins>+    const RenderText* renderer(unsigned position, unsigned* startPosition = nullptr) const;
</ins><span class="cx"> 
</span><span class="cx">     class Style {
</span><span class="cx">     public:
</span><span class="lines">@@ -77,23 +77,27 @@
</span><span class="cx">     const Style&amp; style() const { return m_style; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    bool appendNextRendererContentIfNeeded(unsigned position) const;
</ins><span class="cx">     unsigned nextNonWhitespacePosition(unsigned position, unsigned&amp; spaceCount) const;
</span><del>-    float runWidth(unsigned from, unsigned to, float xPosition) const;
</del><ins>+    float runWidth(const RenderText&amp;, unsigned from, unsigned to, float xPosition) const;
</ins><span class="cx"> 
</span><span class="cx">     const RenderBlockFlow&amp; m_flow;
</span><del>-    Style m_style;
-    LazyLineBreakIterator m_lineBreakIterator;
</del><ins>+    const Style m_style;
+    mutable LazyLineBreakIterator m_lineBreakIterator;
+    Vector&lt;std::pair&lt;unsigned, const RenderText*&gt;&gt; m_textRanges;
+    mutable unsigned m_lastRendererIndex;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline bool FlowContents::isNewlineCharacter(unsigned position) const
</span><span class="cx"> {
</span><del>-    ASSERT(m_lineBreakIterator.string().length() &gt; position);
</del><ins>+    appendNextRendererContentIfNeeded(position);
+    ASSERT(position &lt; m_lineBreakIterator.string().length());
</ins><span class="cx">     return m_lineBreakIterator.string().at(position) == '\n';
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool FlowContents::isEndOfContent(unsigned position) const
</span><span class="cx"> {
</span><del>-    return position &gt;= m_lineBreakIterator.string().length();
</del><ins>+    return position &gt;= m_lineBreakIterator.string().length() &amp;&amp; !renderer(position);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingSimpleLineLayoutResolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp (176395 => 176396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp        2014-11-20 15:20:37 UTC (rev 176395)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp        2014-11-20 15:22:02 UTC (rev 176396)
</span><span class="lines">@@ -76,9 +76,11 @@
</span><span class="cx"> {
</span><span class="cx">     auto&amp; resolver = m_iterator.resolver();
</span><span class="cx">     auto&amp; run = m_iterator.simpleRun();
</span><del>-    const auto&amp; renderer = resolver.m_flowContents.renderer(run.start);
-    ASSERT(renderer.is8Bit());
-    return StringView(renderer.characters8(), renderer.textLength()).substring(run.start, run.end - run.start);
</del><ins>+    unsigned rendererOffset = 0;
+    const auto* renderer = resolver.m_flowContents.renderer(run.start, &amp;rendererOffset);
+    ASSERT(renderer);
+    ASSERT(renderer-&gt;is8Bit());
+    return StringView(renderer-&gt;characters8(), renderer-&gt;textLength()).substring(run.start - rendererOffset, run.end - run.start);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RunResolver::Iterator::Iterator(const RunResolver&amp; resolver, unsigned runIndex, unsigned lineIndex)
</span></span></pre>
</div>
</div>

</body>
</html>