Column balancing support in the region based multicol implementation.

Start by setting the column height to the flow thread's height divided
by the number of columns. Then stretch the column height until
contents fits without creating overflowing columns, or until the
maximum allowed column height is reached, whichever comes first. This
may require several layout iterations (but normally only a
couple). For each time we stretch, stretch by the least amount
required to make a difference to which box goes where.

Also make sure that the columns get tall enough to honor orphans
and widows settings.

This change takes some tiny steps in preparing for multiple column
set support.

This patch is ported from WebKit.
https://bugs.webkit.org/show_bug.cgi?id=116033
Reviewed in WebKit by David Hyatt.

BUG=252675

Review URL: https://chromiumcodereview.appspot.com/16943008

git-svn-id: svn://svn.chromium.org/blink/trunk@153028 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-images-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-images-expected.txt
new file mode 100644
index 0000000..1186e1e52
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-images-expected.txt
@@ -0,0 +1,8 @@
+PASS mc.offsetHeight is 246
+PASS document.documentElement.scrollWidth is document.documentElement.clientWidth
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be a 2 by 2 image grid below.
+
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-images.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-images.html
new file mode 100644
index 0000000..6ae8faf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-images.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>balancing multicol with max-height</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+    <style>
+      img { display:block; height:123px; }
+    </style>
+  </head>
+  <body>
+    <p>There should be a 2 by 2 image grid below.</p>
+    <div id="mc" style="-webkit-columns:3; columns:3; orphans:1; widows:1; color:olive; background:olive;">
+      <img src="../resources/ipad.jpg">
+      <img src="../resources/ipad.jpg">
+      <img src="../resources/ipad.jpg">
+      <img src="../resources/ipad.jpg">
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "246");
+      shouldBe("document.documentElement.scrollWidth", "document.documentElement.clientWidth");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight1-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight1-expected.txt
new file mode 100644
index 0000000..3f8b68d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight1-expected.txt
@@ -0,0 +1,12 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS document.documentElement.scrollWidth is document.documentElement.clientWidth
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight1.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight1.html
new file mode 100644
index 0000000..f55d6d4e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>balancing multicol with max-height</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:3; columns:3; max-height:2em; orphans:1; widows:1; color:olive; background:olive;">
+      line<br>
+      line<br>
+      line<br>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      line<br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+      shouldBe("document.documentElement.scrollWidth", "document.documentElement.clientWidth");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight2-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight2-expected.txt
new file mode 100644
index 0000000..847019a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight2-expected.txt
@@ -0,0 +1,14 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS document.documentElement.scrollWidth is not document.documentElement.clientWidth
+PASS document.documentElement.scrollWidth is >= document.documentElement.clientWidth
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+
+
+
+
+
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight2.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight2.html
new file mode 100644
index 0000000..386625e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance-maxheight2.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>balancing multicol with max-height</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:3; columns:3; max-height:2em; orphans:1; widows:1; color:olive; background:olive;">
+      <br>
+      <br>
+      <br>
+      <br>
+    </div>
+    <div id="ref" style="margin-top:1em; height:2em; color:olive; background:olive;">
+      <br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+      // There should be horizontal overflow:
+      shouldNotBe("document.documentElement.scrollWidth", "document.documentElement.clientWidth");
+      shouldBeGreaterThanOrEqual("document.documentElement.scrollWidth", "document.documentElement.clientWidth");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance1-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance1-expected.txt
new file mode 100644
index 0000000..ed5f0bb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance1-expected.txt
@@ -0,0 +1,12 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+line
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance1.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance1.html
new file mode 100644
index 0000000..affc27d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:4; columns:4; orphans:1; widows:1; color:olive; background:olive;">
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      line<br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance2-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance2-expected.txt
new file mode 100644
index 0000000..955d8c0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance2-expected.txt
@@ -0,0 +1,11 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance2.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance2.html
new file mode 100644
index 0000000..d7658f4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance2.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:4; columns:4; orphans:1; widows:1; color:olive; background:olive;">
+      line<br>
+      line<br>
+      line<br>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      line<br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance3-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance3-expected.txt
new file mode 100644
index 0000000..089672d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance3-expected.txt
@@ -0,0 +1,9 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance3.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance3.html
new file mode 100644
index 0000000..00326ec
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance3.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:4; columns:4; orphans:1; widows:1; color:olive; background:olive;">
+      line<br>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      line<br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance4-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance4-expected.txt
new file mode 100644
index 0000000..3661bd2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance4-expected.txt
@@ -0,0 +1,14 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+line
+line
+line
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance4.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance4.html
new file mode 100644
index 0000000..de0d7d9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance4.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:4; columns:4; orphans:1; widows:1; color:olive; background:olive;">
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      line<br>
+      line<br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance5-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance5-expected.txt
new file mode 100644
index 0000000..5d8a114
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance5-expected.txt
@@ -0,0 +1,17 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance5.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance5.html
new file mode 100644
index 0000000..94b84da
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance5.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:4; columns:4; orphans:1; widows:1; color:olive; background:olive;">
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      line<br>
+      line<br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance6-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance6-expected.txt
new file mode 100644
index 0000000..0f31ca7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance6-expected.txt
@@ -0,0 +1,8 @@
+PASS mc.offsetHeight is 34
+PASS mc.scrollWidth is 500
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be no scrollbar on this page.
+
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance6.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance6.html
new file mode 100644
index 0000000..85ab365
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance6.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be no scrollbar on this page.</p>
+    <div id="mc" style="-webkit-columns:3; columns:3; overflow:auto; width:500px; orphans:1; widows:1;">
+      <div style="height:100px;"></div>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "34");
+      shouldBe("mc.scrollWidth", "500");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance7-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance7-expected.txt
new file mode 100644
index 0000000..4efea43
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance7-expected.txt
@@ -0,0 +1,18 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance7.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance7.html
new file mode 100644
index 0000000..75670213
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance7.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:3; columns:3; orphans:1; widows:1; color:olive; background:olive;">
+      <div style="font-size:1.3em;">line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      <div style="font-size:1.3em;">line</div>
+      <div>line</div>
+      <div>line</div>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance8-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance8-expected.txt
new file mode 100644
index 0000000..4efea43
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance8-expected.txt
@@ -0,0 +1,18 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance8.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance8.html
new file mode 100644
index 0000000..cf0bac36
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance8.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:3; columns:3; orphans:1; widows:1; color:olive; background:olive;">
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div style="font-size:1.3em;">line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      <div style="font-size:1.3em;">line</div>
+      <div>line</div>
+      <div>line</div>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance9-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance9-expected.txt
new file mode 100644
index 0000000..4efea43
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance9-expected.txt
@@ -0,0 +1,18 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
+line
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance9.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance9.html
new file mode 100644
index 0000000..9af3eab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/balance9.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:3; columns:3; orphans:1; widows:1; color:olive; background:olive;">
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div>line</div>
+      <div style="font-size:1.3em;">line</div>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      <div style="font-size:1.3em;">line</div>
+      <div>line</div>
+      <div>line</div>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/cell-shrinkback-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/cell-shrinkback-expected.html
new file mode 100644
index 0000000..b1dcf5a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/cell-shrinkback-expected.html
@@ -0,0 +1,10 @@
+<div style="height: 100px; width: 200px; border: solid; -webkit-columns: 2; -webkit-column-gap:0">
+    <div style="height: 55px;"></div>
+    <table cellspacing=0 cellpadding=0>
+        <tr>
+            <td><div style="height: 50px; width: 25px;"></div></td>
+            <td style="background-color: orange;" valign=bottom>Text</td>
+        </tr>
+    </table>
+    <div style="border-top: solid;"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/cell-shrinkback.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/cell-shrinkback.html
new file mode 100644
index 0000000..bf74672
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/cell-shrinkback.html
@@ -0,0 +1,14 @@
+<script>
+  if (window.internals)
+    internals.settings.setRegionBasedColumnsEnabled(true);
+</script>
+<div style="height: 100px; width: 200px; border: solid; -webkit-columns: 2; -webkit-column-gap:0">
+    <div style="height: 55px;"></div>
+    <table cellspacing=0 cellpadding=0>
+        <tr>
+            <td><div style="height: 50px; width: 25px;"></div></td>
+            <td style="background-color: orange;" valign=bottom>Text</td>
+        </tr>
+    </table>
+    <div style="border-top: solid;"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/columns-shorthand-parsing-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/columns-shorthand-parsing-expected.html
new file mode 100644
index 0000000..76c9af1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/columns-shorthand-parsing-expected.html
@@ -0,0 +1,105 @@
+<html>
+<head>
+<style>
+div {
+  -webkit-columns: 2;
+  -moz-column-count: 2;
+  columns: 2;
+}
+</style>
+</head>
+<body>
+<div>
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+</div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/columns-shorthand-parsing.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/columns-shorthand-parsing.html
new file mode 100644
index 0000000..9544240
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/columns-shorthand-parsing.html
@@ -0,0 +1,108 @@
+<html>
+<head>
+<script>
+  if (window.internals)
+    internals.settings.setRegionBasedColumnsEnabled(true);
+</script>
+<style>
+div {
+  -webkit-columns: 2;
+  -moz-column-count: 2;
+}
+</style>
+</head>
+<body>
+<div>
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+This content should be split into two columns.
+</div>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/orphans-and-widows-balance-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/orphans-and-widows-balance-expected.txt
new file mode 100644
index 0000000..f77a876e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/orphans-and-widows-balance-expected.txt
@@ -0,0 +1,15 @@
+PASS mc.offsetHeight is ref.offsetHeight
+PASS successfullyParsed is true
+
+TEST COMPLETE
+There should be two identical boxes below.
+
+line
+line
+line
+line
+line
+line
+line
+line
+
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/orphans-and-widows-balance.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/orphans-and-widows-balance.html
new file mode 100644
index 0000000..8c599fb41
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/orphans-and-widows-balance.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Orphans and widows in auto-height multicol</title>
+    <script src="../../js/resources/js-test-pre.js"></script>
+    <script>
+      if (window.testRunner)
+        testRunner.dumpAsText();
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+  </head>
+  <body>
+    <p>There should be two identical boxes below.</p>
+    <div id="mc" style="-webkit-columns:4; columns:4; orphans:4; widows:4; color:olive; background:olive;">
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+    </div>
+    <div id="ref" style="margin-top:1em; color:olive; background:olive;">
+      line<br>
+      line<br>
+      line<br>
+      line<br>
+    </div>
+    <script>
+      shouldBe("mc.offsetHeight", "ref.offsetHeight");
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/single-line-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/single-line-expected.html
new file mode 100644
index 0000000..f0479ce9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/single-line-expected.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+    "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>CSS3 Multi-column Layout: Single line test</title>
+    <style type="text/css">
+      .multicol {
+        -webkit-columns: 4;
+        -webkit-column-rule: #bbb 1px solid;
+        background-color: #eee;
+      }
+      p, div {
+        margin: 1em; /* Using horizontal margins here as a work-around for glyphs with negative
+                        bearings. The old multicol implementation has buggy clipping. */
+      }
+      .large {
+        font-size: 30px;
+      }
+    </style>
+  </head>
+  <body>
+    <p>
+      This test checks if CSS3 multi-column layout properly works
+      when the multi-column block contains only one line of text.
+    </p>
+    <p>
+      Test successful if the following text is readable
+      (i.e. not split into two different columns).
+    </p>
+    <p class="multicol">
+      Short text.
+    </p>
+    <p class="multicol">
+      <span class="large">Bigger text.</span>
+    </p>
+    <p class="multicol">
+      Partially <span class="large">big</span> text.
+    </p>
+    <div class="multicol">
+      <p>Nested block.</p>
+    </div>
+    <div>
+      <p class="multicol">Nested block #2.</p>
+    </div>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/single-line.html b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/single-line.html
new file mode 100644
index 0000000..8d1b8be
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/newmulticol/single-line.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+    "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>CSS3 Multi-column Layout: Single line test</title>
+    <script>
+      if (window.internals)
+        internals.settings.setRegionBasedColumnsEnabled(true);
+    </script>
+    <style type="text/css">
+      .multicol {
+        -webkit-columns: 4;
+        -webkit-column-rule: #bbb 1px solid;
+        background-color: #eee;
+      }
+      p, div {
+        margin: 1em; /* Using horizontal margins here as a work-around for glyphs with negative
+                        bearings. The old multicol implementation has buggy clipping. */
+      }
+      .large {
+        font-size: 30px;
+      }
+    </style>
+  </head>
+  <body>
+    <p>
+      This test checks if CSS3 multi-column layout properly works
+      when the multi-column block contains only one line of text.
+    </p>
+    <p>
+      Test successful if the following text is readable
+      (i.e. not split into two different columns).
+    </p>
+    <p class="multicol">
+      Short text.
+    </p>
+    <p class="multicol">
+      <span class="large">Bigger text.</span>
+    </p>
+    <p class="multicol">
+      Partially <span class="large">big</span> text.
+    </p>
+    <div class="multicol">
+      <p>Nested block.</p>
+    </div>
+    <div>
+      <p class="multicol">Nested block #2.</p>
+    </div>
+  </body>
+</html>
diff --git a/third_party/WebKit/Source/core/rendering/RenderBlock.cpp b/third_party/WebKit/Source/core/rendering/RenderBlock.cpp
index e541536..068fee0 100644
--- a/third_party/WebKit/Source/core/rendering/RenderBlock.cpp
+++ b/third_party/WebKit/Source/core/rendering/RenderBlock.cpp
@@ -7386,11 +7386,9 @@
     if (!isUnsplittable)
         return logicalOffset;
     LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
-    LayoutState* layoutState = view()->layoutState();
-    if (layoutState->m_columnInfo)
-        layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
+    updateMinimumPageHeight(logicalOffset, childLogicalHeight);
     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
         || !hasNextPage(logicalOffset))
         return logicalOffset;
@@ -7418,6 +7416,38 @@
     return !checkRegion;
 }
 
+void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
+{
+    if (RenderFlowThread* flowThread = flowThreadContainingBlock())
+        flowThread->setPageBreak(offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
+}
+
+void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
+{
+    if (RenderFlowThread* flowThread = flowThreadContainingBlock())
+        flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
+    else if (ColumnInfo* colInfo = view()->layoutState()->m_columnInfo)
+        colInfo->updateMinimumColumnHeight(minHeight);
+}
+
+static inline LayoutUnit calculateMinimumPageHeight(RenderStyle* renderStyle, RootInlineBox* lastLine, LayoutUnit lineTop, LayoutUnit lineBottom)
+{
+    // We may require a certain minimum number of lines per page in order to satisfy
+    // orphans and widows, and that may affect the minimum page height.
+    unsigned lineCount = max<unsigned>(renderStyle->hasAutoOrphans() ? 1 : renderStyle->orphans(), renderStyle->hasAutoWidows() ? 1 : renderStyle->widows());
+    if (lineCount > 1) {
+        RootInlineBox* line = lastLine;
+        for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++)
+            line = line->prevRootBox();
+
+        // FIXME: Paginating using line overflow isn't all fine. See FIXME in
+        // adjustLinePositionForPagination() for more details.
+        LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), line->lineBottom());
+        lineTop = min(line->lineTopWithLeading(), overflow.y());
+    }
+    return lineBottom - lineTop;
+}
+
 void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, RenderFlowThread* flowThread)
 {
     // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
@@ -7441,11 +7471,9 @@
     // line and all following lines.
     LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
     LayoutUnit logicalOffset = min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
-    LayoutUnit lineHeight = max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY()) - logicalOffset;
-    RenderView* renderView = view();
-    LayoutState* layoutState = renderView->layoutState();
-    if (layoutState->m_columnInfo)
-        layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
+    LayoutUnit logicalBottom = max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY());
+    LayoutUnit lineHeight = logicalBottom - logicalOffset;
+    updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), lineBox, logicalOffset, logicalBottom));
     logicalOffset += delta;
     lineBox->setPaginationStrut(0);
     lineBox->setIsFirstAfterPageBreak(false);
@@ -7470,6 +7498,7 @@
         }
         LayoutUnit totalLogicalHeight = lineHeight + max<LayoutUnit>(0, logicalOffset);
         LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
+        setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
         if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineCount(lineBox)))
             && !isOutOfFlowPositioned() && !isTableCell())
             setPaginationStrut(remainingLogicalHeight + max<LayoutUnit>(0, logicalOffset));
@@ -7516,6 +7545,21 @@
     // If the object has a page or column break value of "before", then we should shift to the top of the next page.
     LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear);
 
+    if (pageLogicalHeightForOffset(result)) {
+        LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(result, ExcludePageBoundary);
+        LayoutUnit spaceShortage = child->logicalHeight() - remainingLogicalHeight;
+        if (spaceShortage > 0) {
+            // If the child crosses a column boundary, report a break, in case nothing inside it has already
+            // done so. The column balancer needs to know how much it has to stretch the columns to make more
+            // content fit. If no breaks are reported (but do occur), the balancer will have no clue. FIXME:
+            // This should be improved, though, because here we just pretend that the child is
+            // unsplittable. A splittable child, on the other hand, has break opportunities at every position
+            // where there's no child content, border or padding. In other words, we risk stretching more
+            // than necessary.
+            setPageBreak(result, spaceShortage);
+        }
+    }
+
     // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
     LayoutUnit logicalTopBeforeUnsplittableAdjustment = result;
     LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, result);
diff --git a/third_party/WebKit/Source/core/rendering/RenderBlock.h b/third_party/WebKit/Source/core/rendering/RenderBlock.h
index ce130bf..3a92dae 100644
--- a/third_party/WebKit/Source/core/rendering/RenderBlock.h
+++ b/third_party/WebKit/Source/core/rendering/RenderBlock.h
@@ -1098,6 +1098,14 @@
 protected:
     bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
 
+    // A page break is required at some offset due to space shortage in the current fragmentainer.
+    void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
+
+    // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
+    // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
+    // column balancer to help set a good minimum column height.
+    void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
+
     LayoutUnit adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
     void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, RenderFlowThread*); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
diff --git a/third_party/WebKit/Source/core/rendering/RenderBox.cpp b/third_party/WebKit/Source/core/rendering/RenderBox.cpp
index 043b019..5c9da8b 100644
--- a/third_party/WebKit/Source/core/rendering/RenderBox.cpp
+++ b/third_party/WebKit/Source/core/rendering/RenderBox.cpp
@@ -2521,8 +2521,11 @@
 {
     // FIXME(cbiesinger): The css-sizing spec is considering changing what min-content/max-content should resolve to.
     // If that happens, this code will have to change.
-    if (height.isIntrinsic())
+    if (height.isIntrinsic()) {
+        if (intrinsicContentHeight == -1)
+            return -1; // Intrinsic height isn't available.
         return computeIntrinsicLogicalContentHeightUsing(height, intrinsicContentHeight, borderAndPaddingLogicalHeight());
+    }
     if (height.isFixed())
         return height.value();
     if (height.isPercent())
diff --git a/third_party/WebKit/Source/core/rendering/RenderFlowThread.h b/third_party/WebKit/Source/core/rendering/RenderFlowThread.h
index 06b29d29..55ea156 100644
--- a/third_party/WebKit/Source/core/rendering/RenderFlowThread.h
+++ b/third_party/WebKit/Source/core/rendering/RenderFlowThread.h
@@ -104,7 +104,10 @@
     LayoutUnit pageLogicalWidthForOffset(LayoutUnit);
     LayoutUnit pageLogicalHeightForOffset(LayoutUnit);
     LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule = IncludePageBoundary);
-    
+
+    virtual void setPageBreak(LayoutUnit /*offset*/, LayoutUnit /*spaceShortage*/) { }
+    virtual void updateMinimumPageHeight(LayoutUnit /*offset*/, LayoutUnit /*minHeight*/) { }
+
     enum RegionAutoGenerationPolicy {
         AllowRegionAutoGeneration,
         DisallowRegionAutoGeneration,
diff --git a/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp b/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp
index e441829..434fccd 100644
--- a/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp
+++ b/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp
@@ -27,6 +27,8 @@
 #include "core/rendering/RenderMultiColumnBlock.h"
 
 #include "core/rendering/RenderMultiColumnFlowThread.h"
+#include "core/rendering/RenderMultiColumnSet.h"
+#include "core/rendering/RenderView.h"
 
 using namespace std;
 
@@ -37,8 +39,8 @@
     , m_flowThread(0)
     , m_columnCount(1)
     , m_columnWidth(0)
-    , m_columnHeight(0)
-    , m_requiresBalancing(false)
+    , m_columnHeightAvailable(0)
+    , m_inBalancingPass(false)
 {
 }
 
@@ -89,21 +91,49 @@
 {
     // We don't actually update any of the variables. We just subclassed to adjust our column height.
     updateLogicalHeight();
-    LayoutUnit newContentLogicalHeight = contentLogicalHeight();
-    m_requiresBalancing = !newContentLogicalHeight;
-    if (!m_requiresBalancing) {
-        // The regions will be invalidated when we lay them out and they change size to
-        // the new column height.
-        if (columnHeight() != newContentLogicalHeight)
-            setColumnHeight(newContentLogicalHeight);
-    }
+    m_columnHeightAvailable = max<LayoutUnit>(contentLogicalHeight(), 0);
     setLogicalHeight(0);
 }
 
-bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer&)
+bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer& statePusher)
 {
-    // FIXME: Implement.
-    return false;
+    if (m_inBalancingPass || !requiresBalancing())
+        return false;
+    m_inBalancingPass = true; // Prevent re-entering this method (and recursion into layout).
+
+    bool needsRelayout;
+    bool neededRelayout = false;
+    bool firstPass = true;
+    do {
+        // Column heights may change here because of balancing. We may have to do multiple layout
+        // passes, depending on how the contents is fitted to the changed column heights. In most
+        // cases, laying out again twice or even just once will suffice. Sometimes we need more
+        // passes than that, though, but the number of retries should not exceed the number of
+        // columns, unless we have a bug.
+        needsRelayout = false;
+        for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
+            if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) {
+                RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
+                if (multicolSet->calculateBalancedHeight(firstPass)) {
+                    multicolSet->setChildNeedsLayout(true, MarkOnlyThis);
+                    needsRelayout = true;
+                }
+            }
+        }
+
+        if (needsRelayout) {
+            // Layout again. Column balancing resulted in a new height.
+            neededRelayout = true;
+            m_flowThread->setChildNeedsLayout(true, MarkOnlyThis);
+            setChildNeedsLayout(true, MarkOnlyThis);
+            if (firstPass)
+                statePusher.pop();
+            layoutBlock(false);
+        }
+        firstPass = false;
+    } while (needsRelayout);
+    m_inBalancingPass = false;
+    return neededRelayout;
 }
 
 void RenderMultiColumnBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
@@ -121,17 +151,17 @@
     if (!m_flowThread)
         return 0;
     
-    // Update the sizes of our regions (but not the placement) before we lay out the flow thread.
+    // Update the dimensions of our regions before we lay out the flow thread.
     // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
     // instead of trying to keep them around.
     bool shouldInvalidateRegions = false;
     for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
         if (childBox == m_flowThread)
             continue;
-        
+
         if (relayoutChildren || childBox->needsLayout()) {
-            childBox->updateLogicalWidth();
-            childBox->updateLogicalHeight();
+            if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
+                toRenderMultiColumnSet(childBox)->prepareForLayout();
             shouldInvalidateRegions = true;
         }
     }
diff --git a/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h b/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h
index 1dfaf232..c4e3cdc4 100644
--- a/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h
+++ b/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h
@@ -37,15 +37,14 @@
 public:
     RenderMultiColumnBlock(Element*);
 
-    LayoutUnit columnHeight() const { return m_columnHeight; }
-    void setColumnHeight(LayoutUnit columnHeight) { m_columnHeight = columnHeight; }
+    LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; }
 
     LayoutUnit columnWidth() const { return m_columnWidth; }
     unsigned columnCount() const { return m_columnCount; }
 
     RenderMultiColumnFlowThread* flowThread() const { return m_flowThread; }
 
-    bool requiresBalancing() const { return m_requiresBalancing; }
+    bool requiresBalancing() const { return !m_columnHeightAvailable; }
 
 private:
     virtual bool isRenderMultiColumnBlock() const { return true; }
@@ -70,8 +69,8 @@
     unsigned m_columnCount;   // The default column count/width that are based off our containing block width. These values represent only the default,
     LayoutUnit m_columnWidth; // since a multi-column block that is split across variable width pages or regions will have different column counts and widths in each.
                               // These values will be cached (eventually) for multi-column blocks.
-    LayoutUnit m_columnHeight; // The current column height.
-    bool m_requiresBalancing; // Whether or not the block specified any kind of logical height. We have to balance by default if it didn't.
+    LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto.
+    bool m_inBalancingPass; // Set when relayouting for column balancing.
 };
 
 inline RenderMultiColumnBlock* toRenderMultiColumnBlock(RenderObject* object)
diff --git a/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp
index 2bf368807..5e3c26f8 100644
--- a/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp
+++ b/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp
@@ -95,14 +95,25 @@
     firstSet = RenderMultiColumnSet::createAnonymous(this);
     firstSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentBlock->style(), BLOCK));
     parentBlock->RenderBlock::addChild(firstSet);
-    
-    // Even though we aren't placed yet, we can go ahead and set up our size.
-    firstSet->updateLogicalWidth();
-    firstSet->updateLogicalHeight();
 
-    firstSet->setRequiresBalancing(parentBlock->requiresBalancing());
-    
+    // Even though we aren't placed yet, we can go ahead and set up our size. At this point we're
+    // typically in the middle of laying out the thread, attempting to paginate, and we need to do
+    // some rudimentary "layout" of the set now, so that pagination will work.
+    firstSet->prepareForLayout();
+
     validateRegions();
 }
 
+void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
+{
+    if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset)))
+        multicolSet->recordSpaceShortage(spaceShortage);
+}
+
+void RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
+{
+    if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset)))
+        multicolSet->updateMinimumColumnHeight(minHeight);
+}
+
 }
diff --git a/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h b/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h
index d57cb1b..ace5c43 100644
--- a/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h
+++ b/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h
@@ -44,6 +44,8 @@
     virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
     virtual void autoGenerateRegionsToBlockOffset(LayoutUnit) OVERRIDE;
     virtual LayoutUnit initialLogicalWidth() const OVERRIDE;
+    virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) OVERRIDE;
+    virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight) OVERRIDE;
 };
 
 } // namespace WebCore
diff --git a/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp b/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp
index 59b89ad..78413e4 100644
--- a/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp
+++ b/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp
@@ -40,7 +40,8 @@
     , m_computedColumnCount(1)
     , m_computedColumnWidth(0)
     , m_computedColumnHeight(0)
-    , m_requiresBalancing(false)
+    , m_maxColumnHeight(LayoutUnit::max())
+    , m_minSpaceShortage(LayoutUnit::max())
     , m_minimumColumnHeight(0)
     , m_forcedBreaksCount(0)
     , m_maximumDistanceBetweenForcedBreaks(0)
@@ -56,13 +57,84 @@
     return renderer;
 }
 
+LayoutUnit RenderMultiColumnSet::heightAdjustedForSetOffset(LayoutUnit height) const
+{
+    RenderMultiColumnBlock* multicolBlock = toRenderMultiColumnBlock(parent());
+    LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderBefore() - multicolBlock->paddingBefore();
+
+    height -= contentLogicalTop;
+    return max(height, LayoutUnit(1)); // Let's avoid zero height, as that would probably cause an infinite amount of columns to be created.
+}
+
 LayoutUnit RenderMultiColumnSet::pageLogicalTopForOffset(LayoutUnit offset) const
 {
     LayoutUnit portionLogicalTop = (isHorizontalWritingMode() ? flowThreadPortionRect().y() : flowThreadPortionRect().x());
-    unsigned columnIndex = (offset - portionLogicalTop) / computedColumnHeight();
+    unsigned columnIndex = columnIndexAtOffset(offset, AssumeNewColumns);
     return portionLogicalTop + columnIndex * computedColumnHeight();
 }
 
+void RenderMultiColumnSet::setAndConstrainColumnHeight(LayoutUnit newHeight)
+{
+    m_computedColumnHeight = newHeight;
+    if (m_computedColumnHeight > m_maxColumnHeight)
+        m_computedColumnHeight = m_maxColumnHeight;
+    // FIXME: the height may also be affected by the enclosing pagination context, if any.
+}
+
+bool RenderMultiColumnSet::calculateBalancedHeight(bool initial)
+{
+    ASSERT(toRenderMultiColumnBlock(parent())->requiresBalancing());
+    LayoutUnit oldColumnHeight = m_computedColumnHeight;
+    LayoutUnit currentMinSpaceShortage = m_minSpaceShortage;
+    m_minSpaceShortage = LayoutUnit::max();
+
+    if (initial) {
+        // Start with the lowest imaginable column height.
+        LayoutUnit logicalHeightGuess = ceilf(float(flowThread()->logicalHeight()) / float(m_computedColumnCount));
+        logicalHeightGuess = 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;
+    }
+
+    if (columnCount() <= computedColumnCount()) {
+        // With the current column height, the content fits without creating overflowing columns. We're done.
+        return false;
+    }
+
+    // If the initial guessed column height wasn't enough, stretch it now. Stretch by the lowest
+    // amount of space shortage found during layout.
+
+    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.
+
+    setAndConstrainColumnHeight(m_computedColumnHeight + currentMinSpaceShortage);
+
+    // 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 >= oldColumnHeight); // We shouldn't be able to shrink the height!
+    return m_computedColumnHeight > oldColumnHeight;
+}
+
+void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage)
+{
+    if (spaceShortage >= m_minSpaceShortage)
+        return;
+
+    // The space shortage is what we use as our stretch amount. We need a positive number here in
+    // order to get anywhere.
+    ASSERT(spaceShortage > 0);
+
+    m_minSpaceShortage = spaceShortage;
+}
+
 void RenderMultiColumnSet::updateLogicalWidth()
 {
     RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
@@ -74,9 +146,6 @@
 
     // If we overflow, increase our logical width.
     unsigned colCount = columnCount();
-    if (!colCount)
-        return;
-    
     LayoutUnit colGap = columnGap();
     LayoutUnit minimumContentLogicalWidth = colCount * computedColumnWidth() + (colCount - 1) * colGap;
     LayoutUnit currentContentLogicalWidth = contentLogicalWidth();
@@ -88,23 +157,42 @@
     setLogicalWidth(logicalWidth() + delta);
 }
 
-void RenderMultiColumnSet::updateLogicalHeight()
+void RenderMultiColumnSet::prepareForLayout()
 {
-    // FIXME: This is the only class that overrides updateLogicalHeight. If we didn't have to set computedColumnHeight,
-    // we could remove this and make updateLogicalHeight non-virtual. https://bugs.webkit.org/show_bug.cgi?id=96804
-    // Make sure our column height is up to date.
-    LogicalExtentComputedValues computedValues;
-    computeLogicalHeight(0, 0, computedValues);
-    setComputedColumnHeight(computedValues.m_extent); // FIXME: Once we make more than one column set, this will become variable.
-    
-    // Our logical height is always just the height of our columns.
-    setLogicalHeight(computedColumnHeight());
+    RenderMultiColumnBlock* multicolBlock = toRenderMultiColumnBlock(parent());
+    RenderStyle* multicolStyle = multicolBlock->style();
+
+    // Set box logical top.
+    ASSERT(!previousSiblingBox() || !previousSiblingBox()->isRenderMultiColumnSet()); // FIXME: multiple set not implemented; need to examine previous set to calculate the correct logical top.
+    setLogicalTop(multicolBlock->borderBefore() + multicolBlock->paddingBefore());
+
+    // Set box width.
+    updateLogicalWidth();
+
+    if (multicolBlock->requiresBalancing()) {
+        // Set maximum column height. We will not stretch beyond this.
+        m_maxColumnHeight = LayoutUnit::max();
+        if (!multicolStyle->logicalHeight().isAuto())
+            m_maxColumnHeight = multicolBlock->computeContentLogicalHeight(multicolStyle->logicalHeight(), -1);
+        if (!multicolStyle->logicalMaxHeight().isUndefined()) {
+            LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle->logicalMaxHeight(), -1);
+            if (m_maxColumnHeight > logicalMaxHeight)
+                m_maxColumnHeight = logicalMaxHeight;
+        }
+        m_maxColumnHeight = heightAdjustedForSetOffset(m_maxColumnHeight);
+        m_computedColumnHeight = 0; // Restart balancing.
+    } else {
+        setAndConstrainColumnHeight(heightAdjustedForSetOffset(multicolBlock->columnHeightAvailable()));
+    }
+
+    // Nuke previously stored minimum column height. Contents may have changed for all we know.
+    m_minimumColumnHeight = 0;
 }
 
-void RenderMultiColumnSet::computeLogicalHeight(LayoutUnit, LayoutUnit, LogicalExtentComputedValues& computedValues) const
+void RenderMultiColumnSet::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
 {
-    RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
-    computedValues.m_extent = parentBlock->columnHeight();
+    computedValues.m_extent = m_computedColumnHeight;
+    computedValues.m_position = logicalTop;
 }
 
 LayoutUnit RenderMultiColumnSet::columnGap() const
@@ -119,12 +207,16 @@
 
 unsigned RenderMultiColumnSet::columnCount() const
 {
+    // We must always return a value of 1 or greater. Column count = 0 is a meaningless situation,
+    // and will confuse and cause problems in other parts of the code.
     if (!computedColumnHeight())
-        return 0;
-    
+        return 1;
+
     // Our portion rect determines our column count. We have as many columns as needed to fit all the content.
     LayoutUnit logicalHeightInColumns = flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().height() : flowThreadPortionRect().width();
-    return ceil(static_cast<float>(logicalHeightInColumns) / computedColumnHeight());
+    unsigned count = ceil(static_cast<float>(logicalHeightInColumns) / computedColumnHeight());
+    ASSERT(count >= 1);
+    return count;
 }
 
 LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const
@@ -144,18 +236,22 @@
     return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
 }
 
-unsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset) const
+unsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset, ColumnIndexCalculationMode mode) const
 {
     LayoutRect portionRect(flowThreadPortionRect());
-    LayoutUnit flowThreadLogicalTop = isHorizontalWritingMode() ? portionRect.y() : portionRect.x();
-    LayoutUnit flowThreadLogicalBottom = isHorizontalWritingMode() ? portionRect.maxY() : portionRect.maxX();
-    
+
     // Handle the offset being out of range.
+    LayoutUnit flowThreadLogicalTop = isHorizontalWritingMode() ? portionRect.y() : portionRect.x();
     if (offset < flowThreadLogicalTop)
         return 0;
-    if (offset >= flowThreadLogicalBottom)
-        return columnCount() - 1;
-    
+    // If we're laying out right now, we cannot constrain against some logical bottom, since it
+    // isn't known yet. Otherwise, just return the last column if we're past the logical bottom.
+    if (mode == ClampToExistingColumns) {
+        LayoutUnit flowThreadLogicalBottom = isHorizontalWritingMode() ? portionRect.maxY() : portionRect.maxX();
+        if (offset >= flowThreadLogicalBottom)
+            return columnCount() - 1;
+    }
+
     // Just divide by the column height to determine the correct column.
     return static_cast<float>(offset - flowThreadLogicalTop) / computedColumnHeight();
 }
diff --git a/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h b/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h
index bd5b0cd..a0d2792 100644
--- a/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h
+++ b/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h
@@ -56,10 +56,8 @@
         m_computedColumnWidth = width;
         m_computedColumnCount = count;
     }
-    void setComputedColumnHeight(LayoutUnit height)
-    {
-        m_computedColumnHeight = height;
-    }
+
+    LayoutUnit heightAdjustedForSetOffset(LayoutUnit height) const;
 
     void updateMinimumColumnHeight(LayoutUnit height) { m_minimumColumnHeight = std::max(height, m_minimumColumnHeight); }
     LayoutUnit minimumColumnHeight() const { return m_minimumColumnHeight; }
@@ -84,12 +82,21 @@
         m_forcedBreakOffset = offsetFromFirstPage;
     }
 
-    bool requiresBalancing() const { return m_requiresBalancing; }
-    void setRequiresBalancing(bool balancing) { m_requiresBalancing = balancing; }
+    // 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);
+
+    // Record space shortage (the amount of space that would have been enough to prevent some
+    // element from being moved to the next column) at a column break. The smallest amount of space
+    // shortage we find is the amount with which we will stretch the column height, if it turns out
+    // after layout that the columns weren't tall enough.
+    void recordSpaceShortage(LayoutUnit spaceShortage);
 
     virtual void updateLogicalWidth() OVERRIDE;
-    virtual void updateLogicalHeight() OVERRIDE;
-    
+
+    void prepareForLayout();
+
 private:
     RenderMultiColumnSet(RenderFlowThread*);
 
@@ -123,15 +130,22 @@
 
     LayoutRect flowThreadPortionRectAt(unsigned index) const;
     LayoutRect flowThreadPortionOverflowRect(const LayoutRect& flowThreadPortion, unsigned index, unsigned colCount, LayoutUnit colGap) const;
-    
-    unsigned columnIndexAtOffset(LayoutUnit) const;
-    
+
+    enum ColumnIndexCalculationMode {
+        ClampToExistingColumns, // Stay within the range of already existing columns.
+        AssumeNewColumns // Allow column indices outside the range of already existing columns.
+    };
+    unsigned columnIndexAtOffset(LayoutUnit, ColumnIndexCalculationMode = ClampToExistingColumns) const;
+
+    void setAndConstrainColumnHeight(LayoutUnit);
+
     unsigned m_computedColumnCount;
     LayoutUnit m_computedColumnWidth;
     LayoutUnit m_computedColumnHeight;
     
     // The following variables are used when balancing the column set.
-    bool m_requiresBalancing; // Whether or not the columns in the column set have to be balanced, i.e., made to be similar logical heights.
+    LayoutUnit m_maxColumnHeight; // Maximum column height allowed.
+    LayoutUnit m_minSpaceShortage; // The smallest amout of space shortage that caused a column break.
     LayoutUnit m_minimumColumnHeight;
     unsigned m_forcedBreaksCount; // FIXME: We will ultimately need to cache more information to balance around forced breaks properly.
     LayoutUnit m_maximumDistanceBetweenForcedBreaks;