Index: third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
diff --git a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
index 1da394c505ab71d68d6a91a8da5925e656c8db2a..92caebf9aa6fb8b0dd83e7c294545f88e9b9fd60 100644 |
--- a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
+++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
@@ -52,9 +52,6 @@ void ColumnBalancer::traverseChildren(const LayoutObject& object) { |
// joined with the break-before value of the next in-flow block-level sibling. |
EBreak previousBreakAfterValue = BreakAuto; |
- const LayoutFlowThread* flowThread = columnSet().flowThread(); |
- bool isHorizontalWritingMode = flowThread->isHorizontalWritingMode(); |
- |
for (const LayoutObject* child = object.slowFirstChild(); child; |
child = child->nextSibling()) { |
if (!child->isBox()) { |
@@ -65,20 +62,33 @@ void ColumnBalancer::traverseChildren(const LayoutObject& object) { |
} |
const LayoutBox& childBox = toLayoutBox(*child); |
- LayoutRect overflowRect = childBox.layoutOverflowRect(); |
- LayoutUnit childLogicalBottomWithOverflow = |
- childBox.logicalTop() + |
- (isHorizontalWritingMode ? overflowRect.maxY() : overflowRect.maxX()); |
- if (m_flowThreadOffset + childLogicalBottomWithOverflow <= |
+ |
+ LayoutUnit borderEdgeOffset; |
+ LayoutUnit logicalTop = childBox.logicalTop(); |
+ LayoutUnit logicalHeight = childBox.logicalHeightWithVisibleOverflow(); |
+ // Floats' margins don't collapse with column boundaries, and we don't want |
+ // to break inside them, or separate them from the float's border box. Set |
+ // the offset to the margin-before edge (rather than border-before edge), |
+ // and include the block direction margins in the child height. |
+ if (childBox.isFloating()) { |
+ LayoutUnit marginBefore = childBox.marginBefore(object.style()); |
+ LayoutUnit marginAfter = childBox.marginAfter(object.style()); |
+ logicalHeight = |
+ std::max(logicalHeight, childBox.logicalHeight() + marginAfter); |
+ logicalTop -= marginBefore; |
+ logicalHeight += marginBefore; |
+ |
+ // As soon as we want to process content inside this child, though, we |
+ // need to get to its border-before edge. |
+ borderEdgeOffset = marginBefore; |
+ } |
+ |
+ if (m_flowThreadOffset + logicalTop + logicalHeight <= |
logicalTopInFlowThread()) { |
// This child is fully above the flow thread portion we're examining. |
continue; |
} |
- LayoutUnit childLogicalTopWithOverflow = |
- childBox.logicalTop() + |
- (isHorizontalWritingMode ? overflowRect.y() : overflowRect.x()); |
- if (m_flowThreadOffset + childLogicalTopWithOverflow >= |
- logicalBottomInFlowThread()) { |
+ if (m_flowThreadOffset + logicalTop >= logicalBottomInFlowThread()) { |
// This child is fully below the flow thread portion we're examining. We |
// cannot just stop here, though, thanks to negative margins. |
// So keep looking. |
@@ -90,18 +100,25 @@ void ColumnBalancer::traverseChildren(const LayoutObject& object) { |
// Tables are wicked. Both table rows and table cells are relative to their |
// table section. |
LayoutUnit offsetForThisChild = |
- childBox.isTableRow() ? LayoutUnit() : childBox.logicalTop(); |
+ childBox.isTableRow() ? LayoutUnit() : logicalTop; |
+ |
m_flowThreadOffset += offsetForThisChild; |
- examineBoxAfterEntering(childBox, previousBreakAfterValue); |
+ examineBoxAfterEntering(childBox, logicalHeight, previousBreakAfterValue); |
// Unless the child is unsplittable, or if the child establishes an inner |
// multicol container, we descend into its subtree for further examination. |
if (childBox.getPaginationBreakability() != LayoutBox::ForbidBreaks && |
(!childBox.isLayoutBlockFlow() || |
- !toLayoutBlockFlow(childBox).multiColumnFlowThread())) |
+ !toLayoutBlockFlow(childBox).multiColumnFlowThread())) { |
+ // We need to get to the border edge before processing content inside |
+ // this child. If the child is floated, we're currently at the margin |
+ // edge. |
+ m_flowThreadOffset += borderEdgeOffset; |
traverseSubtree(childBox); |
+ m_flowThreadOffset -= borderEdgeOffset; |
+ } |
previousBreakAfterValue = childBox.breakAfter(); |
- examineBoxBeforeLeaving(childBox); |
+ examineBoxBeforeLeaving(childBox, logicalHeight); |
m_flowThreadOffset -= offsetForThisChild; |
} |
@@ -134,6 +151,7 @@ LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const { |
void InitialColumnHeightFinder::examineBoxAfterEntering( |
const LayoutBox& box, |
+ LayoutUnit childLogicalHeight, |
EBreak previousBreakAfterValue) { |
if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { |
if (box.needsForcedBreakBefore(previousBreakAfterValue)) { |
@@ -147,11 +165,8 @@ void InitialColumnHeightFinder::examineBoxAfterEntering( |
} |
if (box.getPaginationBreakability() != LayoutBox::AllowAnyBreaks) { |
- LayoutUnit unsplittableLogicalHeight = box.logicalHeight(); |
- if (box.isFloating()) |
- unsplittableLogicalHeight += box.marginBefore() + box.marginAfter(); |
m_tallestUnbreakableLogicalHeight = |
- std::max(m_tallestUnbreakableLogicalHeight, unsplittableLogicalHeight); |
+ std::max(m_tallestUnbreakableLogicalHeight, childLogicalHeight); |
return; |
} |
// Need to examine inner multicol containers to find their tallest unbreakable |
@@ -171,7 +186,9 @@ void InitialColumnHeightFinder::examineBoxAfterEntering( |
std::max(m_tallestUnbreakableLogicalHeight, innerUnbreakableHeight); |
} |
-void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) {} |
+void InitialColumnHeightFinder::examineBoxBeforeLeaving( |
+ const LayoutBox& box, |
+ LayoutUnit childLogicalHeight) {} |
static inline LayoutUnit columnLogicalHeightRequirementForLine( |
const ComputedStyle& style, |
@@ -296,6 +313,7 @@ MinimumSpaceShortageFinder::MinimumSpaceShortageFinder( |
void MinimumSpaceShortageFinder::examineBoxAfterEntering( |
const LayoutBox& box, |
+ LayoutUnit childLogicalHeight, |
EBreak previousBreakAfterValue) { |
LayoutBox::PaginationBreakability breakability = |
box.getPaginationBreakability(); |
@@ -310,7 +328,7 @@ void MinimumSpaceShortageFinder::examineBoxAfterEntering( |
LayoutUnit strut = box.paginationStrut(); |
// Figure out how much more space we would need to prevent it from being |
// pushed to the next column. |
- recordSpaceShortage(box.logicalHeight() - strut); |
+ recordSpaceShortage(childLogicalHeight - strut); |
if (breakability != LayoutBox::ForbidBreaks && |
m_pendingStrut == LayoutUnit::min()) { |
// We now want to look for the first piece of unbreakable content |
@@ -327,7 +345,7 @@ void MinimumSpaceShortageFinder::examineBoxAfterEntering( |
if (breakability != LayoutBox::ForbidBreaks) { |
// See if this breakable box crosses column boundaries. |
- LayoutUnit bottomInFlowThread = flowThreadOffset() + box.logicalHeight(); |
+ LayoutUnit bottomInFlowThread = flowThreadOffset() + childLogicalHeight; |
const MultiColumnFragmentainerGroup& group = |
groupAtOffset(flowThreadOffset()); |
if (isFirstAfterBreak(flowThreadOffset()) || |
@@ -367,7 +385,9 @@ void MinimumSpaceShortageFinder::examineBoxAfterEntering( |
} |
} |
-void MinimumSpaceShortageFinder::examineBoxBeforeLeaving(const LayoutBox& box) { |
+void MinimumSpaceShortageFinder::examineBoxBeforeLeaving( |
+ const LayoutBox& box, |
+ LayoutUnit childLogicalHeight) { |
if (m_pendingStrut == LayoutUnit::min() || |
box.getPaginationBreakability() != LayoutBox::ForbidBreaks) |
return; |
@@ -378,7 +398,7 @@ void MinimumSpaceShortageFinder::examineBoxBeforeLeaving(const LayoutBox& box) { |
// shortage. |
LayoutUnit logicalOffsetFromCurrentColumn = |
offsetFromColumnLogicalTop(flowThreadOffset()); |
- recordSpaceShortage(logicalOffsetFromCurrentColumn + box.logicalHeight() - |
+ recordSpaceShortage(logicalOffsetFromCurrentColumn + childLogicalHeight - |
m_pendingStrut); |
m_pendingStrut = LayoutUnit::min(); |
} |