| Index: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
|
| index dd29fed7bae60dbf585a4a6250e217eff5ff7fa2..402aab313aef5c0bd1185f564cebacd9f6b4e0dd 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
|
| @@ -3533,15 +3533,6 @@ FloatingObject* LayoutBlockFlow::insertFloatingObject(LayoutBox& floatBox) {
|
| // Create the special object entry & append it to the list
|
|
|
| std::unique_ptr<FloatingObject> newObj = FloatingObject::create(&floatBox);
|
| -
|
| - // TODO(mstensho): Avoid laying out before positioning the object, as that's
|
| - // bad for pagination.
|
| - floatBox.layoutIfNeeded();
|
| -
|
| - setLogicalWidthForFloat(*newObj, logicalWidthForChild(floatBox) +
|
| - marginStartForChild(floatBox) +
|
| - marginEndForChild(floatBox));
|
| -
|
| return m_floatingObjects->add(std::move(newObj));
|
| }
|
|
|
| @@ -3675,38 +3666,81 @@ LayoutUnit LayoutBlockFlow::positionAndLayoutFloat(
|
| }
|
| }
|
|
|
| + if (child.needsLayout()) {
|
| + if (isPaginated) {
|
| + // Before we can lay out the float, we need to estimate a position for
|
| + // it. In order to do that, we first need to know its block start margin.
|
| + child.computeAndSetBlockDirectionMargins(this);
|
| + LayoutUnit marginBefore = marginBeforeForChild(child);
|
| +
|
| + // We have found the highest possible position for the float, so we'll
|
| + // lay out right there. Later on, we may be pushed further down by
|
| + // adjacent floats which we don't fit beside, or pushed by fragmentation
|
| + // if we need to break before the top margin edge of the float.
|
| + setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore);
|
| + child.layout();
|
| +
|
| + // May need to push the float to the next fragmentainer before attempting
|
| + // to place it.
|
| + logicalTopMarginEdge =
|
| + adjustFloatLogicalTopForPagination(child, logicalTopMarginEdge);
|
| + } else {
|
| + child.layout();
|
| + }
|
| + }
|
| +
|
| + LayoutUnit marginStart = marginStartForChild(child);
|
| + LayoutUnit marginEnd = marginEndForChild(child);
|
| + setLogicalWidthForFloat(
|
| + floatingObject, logicalWidthForChild(child) + marginStart + marginEnd);
|
| +
|
| + // We have determined the logical width of the float. This is enough
|
| + // information to fit it among other floats according to float positioning
|
| + // rules. Note that logical *height* doesn't really matter yet (until we're
|
| + // going to place subsequent floats or other objects that are affected by
|
| + // floats), since no float may be positioned above the outer logical top edge
|
| + // of any other earlier float in the block formatting context.
|
| LayoutUnit marginBefore = marginBeforeForChild(child);
|
| LayoutUnit marginAfter = marginAfterForChild(child);
|
| LayoutPoint floatLogicalLocation =
|
| computeLogicalLocationForFloat(floatingObject, logicalTopMarginEdge);
|
| logicalTopMarginEdge = floatLogicalLocation.y();
|
| -
|
| setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore);
|
|
|
| SubtreeLayoutScope layoutScope(child);
|
| - if (!child.needsLayout())
|
| - markChildForPaginationRelayoutIfNeeded(child, layoutScope);
|
|
|
| + // A new position may mean that we need to insert, move or remove breaks
|
| + // inside the float. We may also need to lay out if we just ceased to be
|
| + // fragmented, in order to remove pagination struts inside the child.
|
| + markChildForPaginationRelayoutIfNeeded(child, layoutScope);
|
| child.layoutIfNeeded();
|
|
|
| if (isPaginated) {
|
| + // We may have to insert a break before the float.
|
| LayoutUnit newLogicalTopMarginEdge =
|
| adjustFloatLogicalTopForPagination(child, logicalTopMarginEdge);
|
| if (logicalTopMarginEdge != newLogicalTopMarginEdge) {
|
| + // We had already found a location for the float, but a soft
|
| + // fragmentainer break then made us push it further down. This may affect
|
| + // the inline position of the float (since we may no longer be beside the
|
| + // same floats anymore). Block position will remain unaffected, though.
|
| floatLogicalLocation = computeLogicalLocationForFloat(
|
| floatingObject, newLogicalTopMarginEdge);
|
| - logicalTopMarginEdge = floatLogicalLocation.y();
|
| + DCHECK_EQ(floatLogicalLocation.y(), newLogicalTopMarginEdge);
|
| + logicalTopMarginEdge = newLogicalTopMarginEdge;
|
| +
|
| setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore);
|
|
|
| + // Pushing the child to the next fragmentainer most likely means that we
|
| + // need to recalculate pagination struts inside it.
|
| if (child.isLayoutBlock())
|
| child.setChildNeedsLayout(MarkOnlyThis);
|
| child.layoutIfNeeded();
|
| }
|
| }
|
|
|
| - LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection()
|
| - ? marginStartForChild(child)
|
| - : marginEndForChild(child);
|
| + LayoutUnit childLogicalLeftMargin =
|
| + style()->isLeftToRightDirection() ? marginStart : marginEnd;
|
| setLogicalLeftForChild(child,
|
| floatLogicalLocation.x() + childLogicalLeftMargin);
|
| setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
|
|
|