<!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>[162366] 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/162366">162366</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-01-20 11:55:59 -0800 (Mon, 20 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Region based multicol: support explicit column breaks
https://bugs.webkit.org/show_bug.cgi?id=123993

Patch by Morten Stenshorne &lt;mstensho@opera.com&gt; on 2014-01-20
Reviewed by David Hyatt.

Source/WebCore:

Merely supporting insertion of explicit (forced) column breaks in
the region based multicol implementation is really simple: just
hook up with what the CSS regions code is already doing.

However, there is one complication: column balancing. In order to
balance columns as nicely as possible when there are explicit
breaks, we need to figure out between which explicit breaks the
implicit breaks will occur (if there's room for any at all).

Tests: fast/multicol/newmulticol/break-after.html
       fast/multicol/newmulticol/break-before.html
       fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html
       fast/multicol/newmulticol/breaks-2-columns-3.html
       fast/multicol/newmulticol/breaks-3-columns-3.html
       fast/multicol/newmulticol/fixed-height-fill-balance-2.html

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::applyBeforeBreak):
(WebCore::RenderBlockFlow::applyAfterBreak): Use the already
existing region breaking code when inserting breaks in region
based multicol.
* rendering/RenderFlowThread.h:
* rendering/RenderMultiColumnBlock.cpp:
(WebCore::RenderMultiColumnBlock::RenderMultiColumnBlock):
(WebCore::RenderMultiColumnBlock::relayoutForPagination): Avoid
re-balancing if the multicol's contents were not laid out. Apart
from being good for performance, this is now necessary because of
how explicit breaks are implemented.
(WebCore::RenderMultiColumnBlock::layoutSpecialExcludedChild):
Detect if the contents are going to be laid out, or skipped, so
that we can tell if we need to (re-)balance the columns
afterwards.
* rendering/RenderMultiColumnBlock.h:
* rendering/RenderMultiColumnFlowThread.cpp:
(WebCore::RenderMultiColumnFlowThread::addForcedRegionBreak):
Locate the appropriate multi-column set and call its
addForcedBreak().
* rendering/RenderMultiColumnFlowThread.h:
* rendering/RenderMultiColumnSet.cpp:
(WebCore::RenderMultiColumnSet::RenderMultiColumnSet):
(WebCore::RenderMultiColumnSet::findRunWithTallestColumns):
(WebCore::RenderMultiColumnSet::distributeImplicitBreaks): Figure
out how many implicit breaks each single &quot;content run&quot; should
contain. The taller the content run, the more implicit breaks.
(WebCore::RenderMultiColumnSet::calculateBalancedHeight): This is
now a const method that only does half of what the old
calculateBalancedHeight() did. The rest (such as actually storing
the new column height) is done by recalculateBalancedHeight().
(WebCore::RenderMultiColumnSet::clearForcedBreaks): Needs to be
called between each layout pass, to clear the list of &quot;content
runs&quot;.
(WebCore::RenderMultiColumnSet::addForcedBreak): Only useful when
columns are to be balanced. It receives explicit (forced) breaks
and stores them as &quot;content runs&quot;. When layout is done, we'll go
through the list of content runs, and see where implicit breaks
should be inserted (if there's room for any). The goal is to
insert implicit breaks in such a way that the final columns become
as short as possible.
(WebCore::RenderMultiColumnSet::recalculateBalancedHeight):
Calculates and sets a new balanced column height. This used to be
done directly in calculateBalancedHeight(), but that method is now
const and it now only calculates the new height and returns it.
(WebCore::RenderMultiColumnSet::prepareForLayout):
* rendering/RenderMultiColumnSet.h: Remove old data members
intended for forced breaks (they were unused), and introduce a
&quot;content run&quot; vector instead. A new content run is triggered by an
explicit break. This is only used when column balancing is
enabled. When not balanced, RenderMultiColumnSet doesn't need to
do anything when explicit breaks are inserted.

LayoutTests:

* fast/multicol/newmulticol/break-after-expected.html: Added.
* fast/multicol/newmulticol/break-after.html: Added.
* fast/multicol/newmulticol/break-before-expected.html: Added.
* fast/multicol/newmulticol/break-before.html: Added.
* fast/multicol/newmulticol/breaks-2-columns-3-expected.html: Added.
* fast/multicol/newmulticol/breaks-2-columns-3-no-balancing-expected.html: Added.
* fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html: Added.
* fast/multicol/newmulticol/breaks-2-columns-3.html: Added.
* fast/multicol/newmulticol/breaks-3-columns-3-expected.html: Added.
* fast/multicol/newmulticol/breaks-3-columns-3.html: Added.
* fast/multicol/newmulticol/fixed-height-fill-balance-2-expected.html: Added.
* fast/multicol/newmulticol/fixed-height-fill-balance-2.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockFlowcpp">trunk/Source/WebCore/rendering/RenderBlockFlow.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderFlowThreadh">trunk/Source/WebCore/rendering/RenderFlowThread.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnBlockcpp">trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnBlockh">trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnFlowThreadcpp">trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnFlowThreadh">trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnSetcpp">trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnSeth">trunk/Source/WebCore/rendering/RenderMultiColumnSet.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreakafterexpectedhtml">trunk/LayoutTests/fast/multicol/newmulticol/break-after-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreakafterhtml">trunk/LayoutTests/fast/multicol/newmulticol/break-after.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreakbeforeexpectedhtml">trunk/LayoutTests/fast/multicol/newmulticol/break-before-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreakbeforehtml">trunk/LayoutTests/fast/multicol/newmulticol/break-before.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3expectedhtml">trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3nobalancingexpectedhtml">trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3nobalancinghtml">trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3html">trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreaks3columns3expectedhtml">trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolbreaks3columns3html">trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolfixedheightfillbalance2expectedhtml">trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastmulticolnewmulticolfixedheightfillbalance2html">trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/LayoutTests/ChangeLog        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2014-01-20  Morten Stenshorne  &lt;mstensho@opera.com&gt;
+
+        Region based multicol: support explicit column breaks
+        https://bugs.webkit.org/show_bug.cgi?id=123993
+
+        Reviewed by David Hyatt.
+
+        * fast/multicol/newmulticol/break-after-expected.html: Added.
+        * fast/multicol/newmulticol/break-after.html: Added.
+        * fast/multicol/newmulticol/break-before-expected.html: Added.
+        * fast/multicol/newmulticol/break-before.html: Added.
+        * fast/multicol/newmulticol/breaks-2-columns-3-expected.html: Added.
+        * fast/multicol/newmulticol/breaks-2-columns-3-no-balancing-expected.html: Added.
+        * fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html: Added.
+        * fast/multicol/newmulticol/breaks-2-columns-3.html: Added.
+        * fast/multicol/newmulticol/breaks-3-columns-3-expected.html: Added.
+        * fast/multicol/newmulticol/breaks-3-columns-3.html: Added.
+        * fast/multicol/newmulticol/fixed-height-fill-balance-2-expected.html: Added.
+        * fast/multicol/newmulticol/fixed-height-fill-balance-2.html: Added.
+
</ins><span class="cx"> 2014-01-20  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Allow MediaSessionManager to restrict 'preload' behavior
</span></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreakafterexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/break-after-expected.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/break-after-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/break-after-expected.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;script&gt;
+            if (window.internals)
+                internals.settings.setRegionBasedColumnsEnabled(true);
+        &lt;/script&gt;
+        &lt;style&gt;
+            .mc &gt; div { padding:0 0.5em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div class=&quot;mc&quot; style=&quot;-webkit-columns:3; -webkit-column-gap:1em; columns:3; column-gap:1em; orphans:1; widows:1; width:32em; background:olive;&quot;&gt;
+            &lt;div&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div style=&quot;-webkit-column-break-before:always; break-before:column;&quot;&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreakafterhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/break-after.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/break-after.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/break-after.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;script&gt;
+            if (window.internals)
+                internals.settings.setRegionBasedColumnsEnabled(true);
+        &lt;/script&gt;
+        &lt;style&gt;
+            .mc &gt; div { padding:0 0.5em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div class=&quot;mc&quot; style=&quot;-webkit-columns:3; -webkit-column-gap:1em; columns:3; column-gap:1em; orphans:1; widows:1; width:32em; background:olive;&quot;&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreakbeforeexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/break-before-expected.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/break-before-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/break-before-expected.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;style&gt;
+            .mc { float:left; width:9em; padding:0 0.5em; }
+            .gap { float:left; width:1em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div style=&quot;float:left; background:olive;&quot;&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreakbeforehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/break-before.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/break-before.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/break-before.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;script&gt;
+            if (window.internals)
+                internals.settings.setRegionBasedColumnsEnabled(true);
+        &lt;/script&gt;
+        &lt;style&gt;
+            .mc &gt; div { padding:0 0.5em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div class=&quot;mc&quot; style=&quot;-webkit-columns:3; -webkit-column-gap:1em; columns:3; column-gap:1em; orphans:1; widows:1; width:32em; background:olive;&quot;&gt;
+            &lt;div&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div style=&quot;-webkit-column-break-before:always; break-before:column;&quot;&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3expectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-expected.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-expected.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;style&gt;
+            .mc { float:left; width:9em; padding:0 0.5em; }
+            .gap { float:left; width:1em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div style=&quot;float:left; background:olive;&quot;&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                first column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3nobalancingexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing-expected.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing-expected.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;multicol with break&lt;/title&gt;
+        &lt;style&gt;
+            .mc { float:left; width:7em; padding:0 0.5em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em; line-height:2em;&quot;&gt;
+        &lt;div style=&quot;float:left; height:10em; background:olive;&quot;&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+        &lt;div class=&quot;mc&quot;&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+        &lt;/div&gt;
+        &lt;div class=&quot;mc&quot;&gt;
+            fifth column&lt;br&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3nobalancinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;multicol with break&lt;/title&gt;
+        &lt;script&gt;
+            if (window.internals)
+                internals.settings.setRegionBasedColumnsEnabled(true);
+        &lt;/script&gt;
+        &lt;style&gt;
+            .mc &gt; div { padding:0 0.5em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div class=&quot;mc&quot; style=&quot;-webkit-columns:3; -webkit-column-gap:0; -webkit-column-fill:auto; columns:3; column-gap:0; column-fill:auto; orphans:1; widows:1; width:24em; height:10em; line-height:2em; background:olive;&quot;&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                first column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fifth column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreaks2columns3html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/breaks-2-columns-3.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;script&gt;
+            if (window.internals)
+                internals.settings.setRegionBasedColumnsEnabled(true);
+        &lt;/script&gt;
+        &lt;style&gt;
+            .mc &gt; div { padding:0 0.5em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div class=&quot;mc&quot; style=&quot;-webkit-columns:3; -webkit-column-gap:1em; columns:3; column-gap:1em; orphans:1; widows:1; width:32em; background:olive;&quot;&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                first column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreaks3columns3expectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3-expected.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3-expected.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;style&gt;
+            .mc { float:left; width:6em; padding:0 0.5em; }
+            .gap { float:left; width:1em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div style=&quot;float:left; background:olive;&quot;&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                first column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+            &lt;div class=&quot;mc&quot;&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+        &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+        &lt;div class=&quot;mc&quot;&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+            fourth column&lt;br&gt;
+        &lt;/div&gt;
+        &lt;div class=&quot;gap&quot;&gt;&amp;nbsp;&lt;/div&gt;
+        &lt;div class=&quot;mc&quot;&gt;
+            fifth column&lt;br&gt;
+            fifth column&lt;br&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolbreaks3columns3html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/breaks-3-columns-3.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;auto-height multicol with break&lt;/title&gt;
+        &lt;script&gt;
+            if (window.internals)
+                internals.settings.setRegionBasedColumnsEnabled(true);
+        &lt;/script&gt;
+        &lt;style&gt;
+            .mc &gt; div { padding:0 0.5em; }
+        &lt;/style&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;min-width:40em;&quot;&gt;
+        &lt;div class=&quot;mc&quot; style=&quot;-webkit-columns:3; -webkit-column-gap:1em; columns:3; column-gap:1em; orphans:1; widows:1; width:23em; background:olive;&quot;&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                first column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+                second column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div style=&quot;-webkit-column-break-after:always; break-after:column;&quot;&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+                third column&lt;br&gt;
+            &lt;/div&gt;
+            &lt;div&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fourth column&lt;br&gt;
+                fifth column&lt;br&gt;
+                fifth column&lt;br&gt;
+            &lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolfixedheightfillbalance2expectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2-expected.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2-expected.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;balancing fixed-height multicol&lt;/title&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;overflow:hidden;&quot;&gt;
+        &lt;p&gt;There should be three identical blue rectangles below.&lt;/p&gt;
+        &lt;div style=&quot;width:20em;&quot;&gt;
+            &lt;div style=&quot;float:left; width:6em; height:2em; background:blue;&quot;&gt;&lt;/div&gt;
+            &lt;div style=&quot;float:left; width:1em; height:2em;&quot;&gt;&lt;/div&gt;
+            &lt;div style=&quot;float:left; width:6em; height:2em; background:blue;&quot;&gt;&lt;/div&gt;
+            &lt;div style=&quot;float:left; width:1em; height:2em;&quot;&gt;&lt;/div&gt;
+            &lt;div style=&quot;float:left; width:6em; height:2em; background:blue;&quot;&gt;&lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolnewmulticolfixedheightfillbalance2html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2.html (0 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/newmulticol/fixed-height-fill-balance-2.html        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;title&gt;balancing fixed-height multicol&lt;/title&gt;
+        &lt;script&gt;
+            if (window.internals)
+                internals.settings.setRegionBasedColumnsEnabled(true);
+        &lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body style=&quot;overflow:hidden;&quot;&gt;
+        &lt;p&gt;There should be three identical blue rectangles below.&lt;/p&gt;
+        &lt;div style=&quot;-webkit-columns:3; -webkit-column-gap:1em; columns:3; column-gap:1em; line-height:2em; height:3.9em; width:20em;&quot;&gt;
+            &lt;div style=&quot;background:blue;&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;
+        &lt;/div&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/ChangeLog        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2014-01-20  Morten Stenshorne  &lt;mstensho@opera.com&gt;
+
+        Region based multicol: support explicit column breaks
+        https://bugs.webkit.org/show_bug.cgi?id=123993
+
+        Reviewed by David Hyatt.
+
+        Merely supporting insertion of explicit (forced) column breaks in
+        the region based multicol implementation is really simple: just
+        hook up with what the CSS regions code is already doing.
+
+        However, there is one complication: column balancing. In order to
+        balance columns as nicely as possible when there are explicit
+        breaks, we need to figure out between which explicit breaks the
+        implicit breaks will occur (if there's room for any at all).
+
+        Tests: fast/multicol/newmulticol/break-after.html
+               fast/multicol/newmulticol/break-before.html
+               fast/multicol/newmulticol/breaks-2-columns-3-no-balancing.html
+               fast/multicol/newmulticol/breaks-2-columns-3.html
+               fast/multicol/newmulticol/breaks-3-columns-3.html
+               fast/multicol/newmulticol/fixed-height-fill-balance-2.html
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::applyBeforeBreak):
+        (WebCore::RenderBlockFlow::applyAfterBreak): Use the already
+        existing region breaking code when inserting breaks in region
+        based multicol.
+        * rendering/RenderFlowThread.h:
+        * rendering/RenderMultiColumnBlock.cpp:
+        (WebCore::RenderMultiColumnBlock::RenderMultiColumnBlock):
+        (WebCore::RenderMultiColumnBlock::relayoutForPagination): Avoid
+        re-balancing if the multicol's contents were not laid out. Apart
+        from being good for performance, this is now necessary because of
+        how explicit breaks are implemented.
+        (WebCore::RenderMultiColumnBlock::layoutSpecialExcludedChild):
+        Detect if the contents are going to be laid out, or skipped, so
+        that we can tell if we need to (re-)balance the columns
+        afterwards.
+        * rendering/RenderMultiColumnBlock.h:
+        * rendering/RenderMultiColumnFlowThread.cpp:
+        (WebCore::RenderMultiColumnFlowThread::addForcedRegionBreak):
+        Locate the appropriate multi-column set and call its
+        addForcedBreak().
+        * rendering/RenderMultiColumnFlowThread.h:
+        * rendering/RenderMultiColumnSet.cpp:
+        (WebCore::RenderMultiColumnSet::RenderMultiColumnSet):
+        (WebCore::RenderMultiColumnSet::findRunWithTallestColumns):
+        (WebCore::RenderMultiColumnSet::distributeImplicitBreaks): Figure
+        out how many implicit breaks each single &quot;content run&quot; should
+        contain. The taller the content run, the more implicit breaks.
+        (WebCore::RenderMultiColumnSet::calculateBalancedHeight): This is
+        now a const method that only does half of what the old
+        calculateBalancedHeight() did. The rest (such as actually storing
+        the new column height) is done by recalculateBalancedHeight().
+        (WebCore::RenderMultiColumnSet::clearForcedBreaks): Needs to be
+        called between each layout pass, to clear the list of &quot;content
+        runs&quot;.
+        (WebCore::RenderMultiColumnSet::addForcedBreak): Only useful when
+        columns are to be balanced. It receives explicit (forced) breaks
+        and stores them as &quot;content runs&quot;. When layout is done, we'll go
+        through the list of content runs, and see where implicit breaks
+        should be inserted (if there's room for any). The goal is to
+        insert implicit breaks in such a way that the final columns become
+        as short as possible.
+        (WebCore::RenderMultiColumnSet::recalculateBalancedHeight):
+        Calculates and sets a new balanced column height. This used to be
+        done directly in calculateBalancedHeight(), but that method is now
+        const and it now only calculates the new height and returns it.
+        (WebCore::RenderMultiColumnSet::prepareForLayout):
+        * rendering/RenderMultiColumnSet.h: Remove old data members
+        intended for forced breaks (they were unused), and introduce a
+        &quot;content run&quot; vector instead. A new content run is triggered by an
+        explicit break. This is only used when column balancing is
+        enabled. When not balanced, RenderMultiColumnSet doesn't need to
+        do anything when explicit breaks are inserted.
+
</ins><span class="cx"> 2014-01-20  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Allow MediaSessionManager to restrict 'preload' behavior
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockFlowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -1348,15 +1348,21 @@
</span><span class="cx"> LayoutUnit RenderBlockFlow::applyBeforeBreak(RenderBox&amp; child, LayoutUnit logicalOffset)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: Add page break checking here when we support printing.
</span><del>-    bool checkColumnBreaks = view().layoutState()-&gt;isPaginatingColumns();
</del><ins>+    RenderFlowThread* flowThread = flowThreadContainingBlock();
+    bool isInsideMulticolFlowThread = flowThread &amp;&amp; !flowThread-&gt;isRenderNamedFlowThread();
+    bool checkColumnBreaks = isInsideMulticolFlowThread || view().layoutState()-&gt;isPaginatingColumns();
</ins><span class="cx">     bool checkPageBreaks = !checkColumnBreaks &amp;&amp; view().layoutState()-&gt;m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
</span><del>-    RenderFlowThread* flowThread = flowThreadContainingBlock();
</del><span class="cx">     bool checkRegionBreaks = flowThread &amp;&amp; flowThread-&gt;isRenderNamedFlowThread();
</span><del>-    bool checkBeforeAlways = (checkColumnBreaks &amp;&amp; child.style().columnBreakBefore() == PBALWAYS) || (checkPageBreaks &amp;&amp; child.style().pageBreakBefore() == PBALWAYS)
</del><ins>+    bool checkBeforeAlways = (checkColumnBreaks &amp;&amp; child.style().columnBreakBefore() == PBALWAYS)
+        || (checkPageBreaks &amp;&amp; child.style().pageBreakBefore() == PBALWAYS)
</ins><span class="cx">         || (checkRegionBreaks &amp;&amp; child.style().regionBreakBefore() == PBALWAYS);
</span><span class="cx">     if (checkBeforeAlways &amp;&amp; inNormalFlow(child) &amp;&amp; hasNextPage(logicalOffset, IncludePageBoundary)) {
</span><del>-        if (checkColumnBreaks)
-            view().layoutState()-&gt;addForcedColumnBreak(&amp;child, logicalOffset);
</del><ins>+        if (checkColumnBreaks) {
+            if (isInsideMulticolFlowThread)
+                checkRegionBreaks = true;
+            else
+                view().layoutState()-&gt;addForcedColumnBreak(&amp;child, logicalOffset);
+        }
</ins><span class="cx">         if (checkRegionBreaks) {
</span><span class="cx">             LayoutUnit offsetBreakAdjustment = 0;
</span><span class="cx">             if (flowThread-&gt;addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset, &amp;child, true, &amp;offsetBreakAdjustment))
</span><span class="lines">@@ -1370,11 +1376,13 @@
</span><span class="cx"> LayoutUnit RenderBlockFlow::applyAfterBreak(RenderBox&amp; child, LayoutUnit logicalOffset, MarginInfo&amp; marginInfo)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: Add page break checking here when we support printing.
</span><del>-    bool checkColumnBreaks = view().layoutState()-&gt;isPaginatingColumns();
</del><ins>+    RenderFlowThread* flowThread = flowThreadContainingBlock();
+    bool isInsideMulticolFlowThread = flowThread &amp;&amp; !flowThread-&gt;isRenderNamedFlowThread();
+    bool checkColumnBreaks = isInsideMulticolFlowThread || view().layoutState()-&gt;isPaginatingColumns();
</ins><span class="cx">     bool checkPageBreaks = !checkColumnBreaks &amp;&amp; view().layoutState()-&gt;m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
</span><del>-    RenderFlowThread* flowThread = flowThreadContainingBlock();
</del><span class="cx">     bool checkRegionBreaks = flowThread &amp;&amp; flowThread-&gt;isRenderNamedFlowThread();
</span><del>-    bool checkAfterAlways = (checkColumnBreaks &amp;&amp; child.style().columnBreakAfter() == PBALWAYS) || (checkPageBreaks &amp;&amp; child.style().pageBreakAfter() == PBALWAYS)
</del><ins>+    bool checkAfterAlways = (checkColumnBreaks &amp;&amp; child.style().columnBreakAfter() == PBALWAYS)
+        || (checkPageBreaks &amp;&amp; child.style().pageBreakAfter() == PBALWAYS)
</ins><span class="cx">         || (checkRegionBreaks &amp;&amp; child.style().regionBreakAfter() == PBALWAYS);
</span><span class="cx">     if (checkAfterAlways &amp;&amp; inNormalFlow(child) &amp;&amp; hasNextPage(logicalOffset, IncludePageBoundary)) {
</span><span class="cx">         LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
</span><span class="lines">@@ -1382,8 +1390,12 @@
</span><span class="cx">         // So our margin doesn't participate in the next collapsing steps.
</span><span class="cx">         marginInfo.clearMargin();
</span><span class="cx"> 
</span><del>-        if (checkColumnBreaks)
-            view().layoutState()-&gt;addForcedColumnBreak(&amp;child, logicalOffset);
</del><ins>+        if (checkColumnBreaks) {
+            if (isInsideMulticolFlowThread)
+                checkRegionBreaks = true;
+            else
+                view().layoutState()-&gt;addForcedColumnBreak(&amp;child, logicalOffset);
+        }
</ins><span class="cx">         if (checkRegionBreaks) {
</span><span class="cx">             LayoutUnit offsetBreakAdjustment = 0;
</span><span class="cx">             if (flowThread-&gt;addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, &amp;child, false, &amp;offsetBreakAdjustment))
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderFlowThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderFlowThread.h (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderFlowThread.h        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.h        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -145,7 +145,7 @@
</span><span class="cx">     void markAutoLogicalHeightRegionsForLayout();
</span><span class="cx">     void markRegionsForOverflowLayoutIfNeeded();
</span><span class="cx"> 
</span><del>-    bool addForcedRegionBreak(const RenderBlock*, LayoutUnit, RenderBox* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0);
</del><ins>+    virtual bool addForcedRegionBreak(const RenderBlock*, LayoutUnit, RenderBox* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0);
</ins><span class="cx">     void applyBreakAfterContent(LayoutUnit);
</span><span class="cx"> 
</span><span class="cx">     bool pageLogicalSizeChanged() const { return m_pageLogicalSizeChanged; }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnBlock.cpp        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx">     , m_columnWidth(0)
</span><span class="cx">     , m_columnHeightAvailable(0)
</span><span class="cx">     , m_inBalancingPass(false)
</span><ins>+    , m_needsRebalancing(false)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -96,8 +97,9 @@
</span><span class="cx"> 
</span><span class="cx"> bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer&amp; statePusher)
</span><span class="cx"> {
</span><del>-    if (m_inBalancingPass || !requiresBalancing())
</del><ins>+    if (m_inBalancingPass || !m_needsRebalancing)
</ins><span class="cx">         return false;
</span><ins>+    m_needsRebalancing = false;
</ins><span class="cx">     m_inBalancingPass = true; // Prevent re-entering this method (and recursion into layout).
</span><span class="cx"> 
</span><span class="cx">     bool needsRelayout;
</span><span class="lines">@@ -113,7 +115,7 @@
</span><span class="cx">         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox-&gt;nextSiblingBox())
</span><span class="cx">             if (childBox != m_flowThread &amp;&amp; childBox-&gt;isRenderMultiColumnSet()) {
</span><span class="cx">                 RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
</span><del>-                if (multicolSet-&gt;calculateBalancedHeight(firstPass)) {
</del><ins>+                if (multicolSet-&gt;recalculateBalancedHeight(firstPass)) {
</ins><span class="cx">                     multicolSet-&gt;setChildNeedsLayout(MarkOnlyThis);
</span><span class="cx">                     needsRelayout = true;
</span><span class="cx">                 }
</span><span class="lines">@@ -170,6 +172,18 @@
</span><span class="cx">     if (relayoutChildren)
</span><span class="cx">         m_flowThread-&gt;setChildNeedsLayout(MarkOnlyThis);
</span><span class="cx">     
</span><ins>+    if (requiresBalancing()) {
+        // At the end of multicol layout, relayoutForPagination() is called unconditionally, but if
+        // no children are to be laid out (e.g. fixed width with layout already being up-to-date),
+        // we want to prevent it from doing any work, so that the column balancing machinery doesn't
+        // kick in and trigger additional unnecessary layout passes. Actually, it's not just a good
+        // idea in general to not waste time on balancing content that hasn't been re-laid out; we
+        // are actually required to guarantee this. The calculation of implicit breaks needs to be
+        // preceded by a proper layout pass, since it's layout that sets up content runs, and the
+        // runs get deleted right after every pass.
+        m_needsRebalancing = shouldInvalidateRegions || m_flowThread-&gt;needsLayout();
+    }
+
</ins><span class="cx">     setLogicalTopForChild(*m_flowThread, borderAndPaddingBefore());
</span><span class="cx">     m_flowThread-&gt;layoutIfNeeded();
</span><span class="cx">     determineLogicalLeftPositionForChild(*m_flowThread);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnBlock.h        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx">                               // These values will be cached (eventually) for multi-column blocks.
</span><span class="cx">     LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto.
</span><span class="cx">     bool m_inBalancingPass; // Set when relayouting for column balancing.
</span><ins>+    bool m_needsRebalancing;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> RENDER_OBJECT_TYPE_CASTS(RenderMultiColumnBlock, isRenderMultiColumnBlock())
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnFlowThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -110,4 +110,15 @@
</span><span class="cx">         multicolSet-&gt;updateMinimumColumnHeight(minHeight);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool RenderMultiColumnFlowThread::addForcedRegionBreak(const RenderBlock* block, LayoutUnit offset, RenderBox* /*breakChild*/, bool /*isBefore*/, LayoutUnit* offsetBreakAdjustment)
+{
+    if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(block, offset))) {
+        multicolSet-&gt;addForcedBreak(offset);
+        if (offsetBreakAdjustment)
+            *offsetBreakAdjustment = pageLogicalHeightForOffset(offset) ? pageRemainingLogicalHeightForOffset(offset, IncludePageBoundary) : LayoutUnit(0);
+        return true;
+    }
+    return false;
</ins><span class="cx"> }
</span><ins>+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnFlowThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     virtual LayoutUnit initialLogicalWidth() const override;
</span><span class="cx">     virtual void setPageBreak(const RenderBlock*, LayoutUnit offset, LayoutUnit spaceShortage) override;
</span><span class="cx">     virtual void updateMinimumPageHeight(const RenderBlock*, LayoutUnit offset, LayoutUnit minHeight) override;
</span><ins>+    virtual bool addForcedRegionBreak(const RenderBlock*, LayoutUnit, RenderBox* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) override;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnSet.cpp        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -41,9 +41,6 @@
</span><span class="cx">     , m_maxColumnHeight(LayoutUnit::max())
</span><span class="cx">     , m_minSpaceShortage(LayoutUnit::max())
</span><span class="cx">     , m_minimumColumnHeight(0)
</span><del>-    , m_forcedBreaksCount(0)
-    , m_maximumDistanceBetweenForcedBreaks(0)
-    , m_forcedBreakOffset(0)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -71,47 +68,124 @@
</span><span class="cx">     // FIXME: the height may also be affected by the enclosing pagination context, if any.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool RenderMultiColumnSet::calculateBalancedHeight(bool initial)
</del><ins>+unsigned RenderMultiColumnSet::findRunWithTallestColumns() const
</ins><span class="cx"> {
</span><del>-    ASSERT(toRenderMultiColumnBlock(parent())-&gt;requiresBalancing());
-    LayoutUnit oldColumnHeight = m_computedColumnHeight;
-    LayoutUnit currentMinSpaceShortage = m_minSpaceShortage;
-    m_minSpaceShortage = LayoutUnit::max();
</del><ins>+    unsigned indexWithLargestHeight = 0;
+    LayoutUnit largestHeight;
+    LayoutUnit previousOffset;
+    size_t runCount = m_contentRuns.size();
+    ASSERT(runCount);
+    for (size_t i = 0; i &lt; runCount; i++) {
+        const ContentRun&amp; run = m_contentRuns[i];
+        LayoutUnit height = run.columnLogicalHeight(previousOffset);
+        if (largestHeight &lt; height) {
+            largestHeight = height;
+            indexWithLargestHeight = i;
+        }
+        previousOffset = run.breakOffset();
+    }
+    return indexWithLargestHeight;
+}
</ins><span class="cx"> 
</span><ins>+void RenderMultiColumnSet::distributeImplicitBreaks()
+{
+    unsigned breakCount = forcedBreaksCount();
+
+#ifndef NDEBUG
+    // There should be no implicit breaks assumed at this point.
+    for (unsigned i = 0; i &lt; breakCount; i++)
+        ASSERT(!m_contentRuns[i].assumedImplicitBreaks());
+#endif // NDEBUG
+
+    // There will always be at least one break, since the flow thread reports a &quot;forced break&quot; at
+    // end of content.
+    ASSERT(breakCount &gt;= 1);
+
+    // If there is room for more breaks (to reach the used value of column-count), imagine that we
+    // insert implicit breaks at suitable locations. At any given time, the content run with the
+    // currently tallest columns will get another implicit break &quot;inserted&quot;, which will increase its
+    // column count by one and shrink its columns' height. Repeat until we have the desired total
+    // number of breaks. The largest column height among the runs will then be the initial column
+    // height for the balancer to use.
+    while (breakCount &lt; m_computedColumnCount) {
+        unsigned index = findRunWithTallestColumns();
+        m_contentRuns[index].assumeAnotherImplicitBreak();
+        breakCount++;
+    }
+}
+
+LayoutUnit RenderMultiColumnSet::calculateBalancedHeight(bool initial) const
+{
</ins><span class="cx">     if (initial) {
</span><span class="cx">         // Start with the lowest imaginable column height.
</span><del>-        LayoutUnit logicalHeightGuess = ceilf(float(flowThread()-&gt;logicalHeight()) / float(m_computedColumnCount));
-        logicalHeightGuess = std::max(logicalHeightGuess, m_minimumColumnHeight);
-        setAndConstrainColumnHeight(logicalHeightGuess);
-
-        // The multicol container now typically needs at least one more layout pass with a new
-        // column height, but if height was specified, we only need to do this if we found that we
-        // might need less space than that. On the other hand, if we determined that the columns
-        // need to be as tall as the specified height of the container, we have already laid it out
-        // correctly, and there's no need for another pass.
-        return m_computedColumnHeight != oldColumnHeight;
</del><ins>+        unsigned index = findRunWithTallestColumns();
+        LayoutUnit startOffset = index &gt; 0 ? m_contentRuns[index - 1].breakOffset() : LayoutUnit(0);
+        return std::max&lt;LayoutUnit&gt;(m_contentRuns[index].columnLogicalHeight(startOffset), m_minimumColumnHeight);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (columnCount() &lt;= computedColumnCount())
</del><ins>+    if (columnCount() &lt;= computedColumnCount()) {
</ins><span class="cx">         // With the current column height, the content fits without creating overflowing columns. We're done.
</span><del>-        return false;
</del><ins>+        return m_computedColumnHeight;
+    }
</ins><span class="cx"> 
</span><ins>+    if (forcedBreaksCount() &gt; 1 &amp;&amp; forcedBreaksCount() &gt;= computedColumnCount()) {
+        // Too many forced breaks to allow any implicit breaks. Initial balancing should already
+        // have set a good height. There's nothing more we should do.
+        return m_computedColumnHeight;
+    }
+
</ins><span class="cx">     // If the initial guessed column height wasn't enough, stretch it now. Stretch by the lowest
</span><span class="cx">     // amount of space shortage found during layout.
</span><span class="cx"> 
</span><del>-    ASSERT(currentMinSpaceShortage != LayoutUnit::max()); // If this can actually happen, we probably have a bug.
-    if (currentMinSpaceShortage == LayoutUnit::max())
-        return false; // So bail out rather than looping infinitely.
</del><ins>+    ASSERT(m_minSpaceShortage &gt; 0); // We should never _shrink_ the height!
+    ASSERT(m_minSpaceShortage != LayoutUnit::max()); // If this happens, we probably have a bug.
+    if (m_minSpaceShortage == LayoutUnit::max())
+        return m_computedColumnHeight; // So bail out rather than looping infinitely.
</ins><span class="cx"> 
</span><del>-    setAndConstrainColumnHeight(m_computedColumnHeight + currentMinSpaceShortage);
</del><ins>+    return m_computedColumnHeight + m_minSpaceShortage;
+}
</ins><span class="cx"> 
</span><del>-    // If we reach the maximum column height (typically set by the height or max-height property),
-    // we may not be allowed to stretch further. Return true only if stretching
-    // succeeded. Otherwise, we're done.
-    ASSERT(m_computedColumnHeight &gt;= oldColumnHeight); // We shouldn't be able to shrink the height!
-    return m_computedColumnHeight &gt; oldColumnHeight;
</del><ins>+void RenderMultiColumnSet::clearForcedBreaks()
+{
+    m_contentRuns.clear();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RenderMultiColumnSet::addForcedBreak(LayoutUnit offsetFromFirstPage)
+{
+    if (!toRenderMultiColumnBlock(parent())-&gt;requiresBalancing())
+        return;
+    if (!m_contentRuns.isEmpty() &amp;&amp; offsetFromFirstPage &lt;= m_contentRuns.last().breakOffset())
+        return;
+    // Append another item as long as we haven't exceeded used column count. What ends up in the
+    // overflow area shouldn't affect column balancing.
+    if (m_contentRuns.size() &lt; m_computedColumnCount)
+        m_contentRuns.append(ContentRun(offsetFromFirstPage));
+}
+
+bool RenderMultiColumnSet::recalculateBalancedHeight(bool initial)
+{
+    ASSERT(toRenderMultiColumnBlock(parent())-&gt;requiresBalancing());
+
+    LayoutUnit oldColumnHeight = m_computedColumnHeight;
+    if (initial)
+        distributeImplicitBreaks();
+    LayoutUnit newColumnHeight = calculateBalancedHeight(initial);
+    setAndConstrainColumnHeight(newColumnHeight);
+
+    // After having calculated an initial column height, the multicol container typically needs at
+    // least one more layout pass with a new column height, but if a height was specified, we only
+    // need to do this if we think that we need less space than specified. Conversely, if we
+    // determined that the columns need to be as tall as the specified height of the container, we
+    // have already laid it out correctly, and there's no need for another pass.
+
+    if (m_computedColumnHeight == oldColumnHeight)
+        return false; // No change. We're done.
+
+    m_minSpaceShortage = LayoutUnit::max();
+    clearForcedBreaks();
+    return true; // Need another pass.
+}
+
</ins><span class="cx"> void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage)
</span><span class="cx"> {
</span><span class="cx">     if (spaceShortage &gt;= m_minSpaceShortage)
</span><span class="lines">@@ -173,6 +247,8 @@
</span><span class="cx">     } else
</span><span class="cx">         setAndConstrainColumnHeight(heightAdjustedForSetOffset(multicolBlock-&gt;columnHeightAvailable()));
</span><span class="cx"> 
</span><ins>+    clearForcedBreaks();
+
</ins><span class="cx">     // Nuke previously stored minimum column height. Contents may have changed for all we know.
</span><span class="cx">     m_minimumColumnHeight = 0;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnSet.h (162365 => 162366)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnSet.h        2014-01-20 19:39:15 UTC (rev 162365)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnSet.h        2014-01-20 19:55:59 UTC (rev 162366)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #define RenderMultiColumnSet_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;RenderRegionSet.h&quot;
</span><ins>+#include &lt;wtf/Vector.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -62,30 +63,14 @@
</span><span class="cx">     void updateMinimumColumnHeight(LayoutUnit height) { m_minimumColumnHeight = std::max(height, m_minimumColumnHeight); }
</span><span class="cx">     LayoutUnit minimumColumnHeight() const { return m_minimumColumnHeight; }
</span><span class="cx"> 
</span><del>-    unsigned forcedBreaksCount() const { return m_forcedBreaksCount; }
-    LayoutUnit forcedBreakOffset() const { return m_forcedBreakOffset; }
-    LayoutUnit maximumDistanceBetweenForcedBreaks() const { return m_maximumDistanceBetweenForcedBreaks; }
-    void clearForcedBreaks()
-    { 
-        m_forcedBreaksCount = 0;
-        m_maximumDistanceBetweenForcedBreaks = 0;
-        m_forcedBreakOffset = 0;
-    }
-    void addForcedBreak(LayoutUnit offsetFromFirstPage)
-    { 
-        ASSERT(!computedColumnHeight());
-        LayoutUnit distanceFromLastBreak = offsetFromFirstPage - m_forcedBreakOffset;
-        if (!distanceFromLastBreak)
-            return;
-        m_forcedBreaksCount++;
-        m_maximumDistanceBetweenForcedBreaks = std::max(m_maximumDistanceBetweenForcedBreaks, distanceFromLastBreak);
-        m_forcedBreakOffset = offsetFromFirstPage;
-    }
</del><ins>+    unsigned forcedBreaksCount() const { return m_contentRuns.size(); }
+    void clearForcedBreaks();
+    void addForcedBreak(LayoutUnit offsetFromFirstPage);
</ins><span class="cx"> 
</span><del>-    // Calculate the column height when contents are supposed to be balanced. If 'initial' is set,
-    // guess an initial column height; otherwise, stretch the column height a tad. Return true if
-    // column height changed and another layout pass is required.
-    bool calculateBalancedHeight(bool initial);
</del><ins>+    // (Re-)calculate the column height when contents are supposed to be balanced. If 'initial' is
+    // set, guess an initial column height; otherwise, stretch the column height a tad. Return true
+    // if column height changed and another layout pass is required.
+    bool recalculateBalancedHeight(bool initial);
</ins><span class="cx"> 
</span><span class="cx">     // Record space shortage (the amount of space that would have been enough to prevent some
</span><span class="cx">     // element from being moved to the next column) at a column break. The smallest amount of space
</span><span class="lines">@@ -135,17 +120,52 @@
</span><span class="cx"> 
</span><span class="cx">     void setAndConstrainColumnHeight(LayoutUnit);
</span><span class="cx"> 
</span><del>-    unsigned m_computedColumnCount;
-    LayoutUnit m_computedColumnWidth;
</del><ins>+    // Return the index of the content run with the currently tallest columns, taking all implicit
+    // breaks assumed so far into account.
+    unsigned findRunWithTallestColumns() const;
+
+    // Given the current list of content runs, make assumptions about where we need to insert
+    // implicit breaks (if there's room for any at all; depending on the number of explicit breaks),
+    // and store the results. This is needed in order to balance the columns.
+    void distributeImplicitBreaks();
+
+    LayoutUnit calculateBalancedHeight(bool initial) const;
+
+    unsigned m_computedColumnCount; // Used column count (the resulting 'N' from the pseudo-algorithm in the multicol spec)
+    LayoutUnit m_computedColumnWidth; // Used column width (the resulting 'W' from the pseudo-algorithm in the multicol spec)
</ins><span class="cx">     LayoutUnit m_computedColumnHeight;
</span><span class="cx">     
</span><span class="cx">     // The following variables are used when balancing the column set.
</span><span class="cx">     LayoutUnit m_maxColumnHeight; // Maximum column height allowed.
</span><span class="cx">     LayoutUnit m_minSpaceShortage; // The smallest amout of space shortage that caused a column break.
</span><span class="cx">     LayoutUnit m_minimumColumnHeight;
</span><del>-    unsigned m_forcedBreaksCount; // FIXME: We will ultimately need to cache more information to balance around forced breaks properly.
-    LayoutUnit m_maximumDistanceBetweenForcedBreaks;
-    LayoutUnit m_forcedBreakOffset;
</del><ins>+
+    // A run of content without explicit (forced) breaks; i.e. a flow thread portion between two
+    // explicit breaks, between flow thread start and an explicit break, between an explicit break
+    // and flow thread end, or, in cases when there are no explicit breaks at all: between flow flow
+    // thread start and flow thread end. We need to know where the explicit breaks are, in order to
+    // figure out where the implicit breaks will end up, so that we get the columns properly
+    // balanced. A content run starts out as representing one single column, and will represent one
+    // additional column for each implicit break &quot;inserted&quot; there.
+    class ContentRun {
+    public:
+        ContentRun(LayoutUnit breakOffset)
+            : m_breakOffset(breakOffset)
+            , m_assumedImplicitBreaks(0) { }
+
+        unsigned assumedImplicitBreaks() const { return m_assumedImplicitBreaks; }
+        void assumeAnotherImplicitBreak() { m_assumedImplicitBreaks++; }
+        LayoutUnit breakOffset() const { return m_breakOffset; }
+
+        // Return the column height that this content run would require, considering the implicit
+        // breaks assumed so far.
+        LayoutUnit columnLogicalHeight(LayoutUnit startOffset) const { return ceilf(float(m_breakOffset - startOffset) / float(m_assumedImplicitBreaks + 1)); }
+
+    private:
+        LayoutUnit m_breakOffset; // Flow thread offset where this run ends.
+        unsigned m_assumedImplicitBreaks; // Number of implicit breaks in this run assumed so far.
+    };
+    Vector&lt;ContentRun, 1&gt; m_contentRuns;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> RENDER_OBJECT_TYPE_CASTS(RenderMultiColumnSet, isRenderMultiColumnSet())
</span></span></pre>
</div>
</div>

</body>
</html>