Images/replaced elements that are as tall as a page should be on their own page
https://bugs.webkit.org/show_bug.cgi?id=138886 - <rdar://problem/18296371>

Reviewed by Dean Jackson.

Source/WebCore:

Added fast/multicol/tall-image-behavior.html (and RL/LR variants)

* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::computeReplacedAndTextLineTopAndBottom):
* rendering/InlineFlowBox.h:
Add a new method that computes the line top and line bottom ignoring all margins,
overflow and line-height. This allows us to see if a line that is taller than a page
can be made to fit if we ignored margins and unused descent.

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::adjustLinePositionForPagination):
Call the new helper function, computeReplacedAndTextLineTopAndBottom and push
to a new page if we see that we can fit on a page by ourselves without blank space
included.

LayoutTests:

* fast/multicol/tall-image-behavior-lr.html: Added.
* fast/multicol/tall-image-behavior-rl.html: Added.
* fast/multicol/tall-image-behavior.html: Added.
* platform/mac/fast/multicol/tall-image-behavior-expected.png: Added.
* platform/mac/fast/multicol/tall-image-behavior-expected.txt: Added.
* platform/mac/fast/multicol/tall-image-behavior-lr-expected.png: Added.
* platform/mac/fast/multicol/tall-image-behavior-lr-expected.txt: Added.
* platform/mac/fast/multicol/tall-image-behavior-rl-expected.png: Added.
* platform/mac/fast/multicol/tall-image-behavior-rl-expected.txt: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@176354 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderBlockFlow.cpp b/Source/WebCore/rendering/RenderBlockFlow.cpp
index f96b1a0..47e3b1b 100644
--- a/Source/WebCore/rendering/RenderBlockFlow.cpp
+++ b/Source/WebCore/rendering/RenderBlockFlow.cpp
@@ -1640,11 +1640,28 @@
     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
     // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflow.height() still fits, we are
     // still going to add a strut, so that the visible overflow fits on a single page.
-    if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight)
-        || !hasNextPage(logicalOffset))
+    if (!pageLogicalHeight || !hasNextPage(logicalOffset)) {
         // FIXME: In case the line aligns with the top of the page (or it's slightly shifted downwards) it will not be marked as the first line in the page.
         // From here, the fix is not straightforward because it's not easy to always determine when the current line is the first in the page.
         return;
+    }
+
+    if (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight) {
+        // We are so tall that we are bigger than a page. Before we give up and just leave the line where it is, try drilling into the
+        // line and computing a new height that excludes anything we consider "blank space". We will discard margins, descent, and even overflow. If we are
+        // able to fit with the blank space and overflow excluded, we will give the line its own page with the highest non-blank element being aligned with the
+        // top of the page.
+        // FIXME: We are still honoring gigantic margins, which does leave open the possibility of blank pages caused by this heuristic. It remains to be seen whether or not
+        // this will be a real-world issue. For now we don't try to deal with this problem.
+        logicalOffset = intMaxForLayoutUnit;
+        logicalBottom = intMinForLayoutUnit;
+        lineBox->computeReplacedAndTextLineTopAndBottom(logicalOffset, logicalBottom);
+        lineHeight = logicalBottom - logicalOffset;
+        if (logicalOffset == intMaxForLayoutUnit || lineHeight > pageLogicalHeight)
+            return; // Give up. We're genuinely too big even after excluding blank space and overflow.
+        pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
+    }
+    
     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
     overflowsRegion = (lineHeight > remainingLogicalHeight);