| 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 1286c81877554c9f6711676d849a689cf2ad6844..543857208a025c1c921b647e7c1722bc47083e21 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
|
| @@ -682,7 +682,7 @@ LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
|
| // 3. The child itself is unsplittable and doesn't fit in the current page or column.
|
| //
|
| // No matter which source, if we need to insert a strut, it should always take us to the exact
|
| - // top of the next page or column, or be zero.
|
| + // top of a page or column further ahead, or be zero.
|
|
|
| // We're now going to calculate the child's final pagination strut. We may end up propagating
|
| // it to its containing block (|this|), so reset it first.
|
| @@ -700,12 +700,8 @@ LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
|
| // 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 logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, logicalTop);
|
|
|
| - // Some sanity checks: No matter what the reason is for pushing the child to the next page or
|
| - // column, the amount should be the same.
|
| - ASSERT(!strutFromContent || logicalTopAfterForcedBreak == logicalTop || logicalTopAfterForcedBreak == logicalTopWithContentStrut);
|
| - ASSERT(!strutFromContent || logicalTopAfterUnsplittable == logicalTop || logicalTopAfterUnsplittable == logicalTopWithContentStrut);
|
| - ASSERT(logicalTopAfterUnsplittable == logicalTop || logicalTopAfterForcedBreak == logicalTop || logicalTopAfterUnsplittable == logicalTopAfterForcedBreak);
|
| -
|
| + // Pick the largest offset. Tall unsplittable content may take us to a page or column further
|
| + // ahead than the next one.
|
| LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut, std::max(logicalTopAfterForcedBreak, logicalTopAfterUnsplittable));
|
| LayoutUnit newLogicalTop = logicalTop;
|
| if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) {
|
| @@ -735,7 +731,7 @@ LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
|
| return newLogicalTop;
|
| }
|
|
|
| -static bool shouldSetStrutOnBlock(const LayoutBlockFlow& block, const RootInlineBox& lineBox, LayoutUnit lineLogicalOffset, int lineIndex, LayoutUnit remainingLogicalHeight)
|
| +static bool shouldSetStrutOnBlock(const LayoutBlockFlow& block, const RootInlineBox& lineBox, LayoutUnit lineLogicalOffset, int lineIndex, LayoutUnit pageLogicalHeight)
|
| {
|
| bool wantsStrutOnBlock = false;
|
| if (!block.style()->hasAutoOrphans() && block.style()->orphans() >= lineIndex) {
|
| @@ -751,10 +747,9 @@ static bool shouldSetStrutOnBlock(const LayoutBlockFlow& block, const RootInline
|
| // fits nicely where it is.
|
| LayoutUnit lineHeight = lineBox.lineBottomWithLeading() - lineBox.lineTopWithLeading();
|
| LayoutUnit totalLogicalHeight = lineHeight + std::max<LayoutUnit>(0, lineLogicalOffset);
|
| - LayoutUnit pageLogicalHeightAtNewOffset = block.pageLogicalHeightForOffset(lineLogicalOffset + remainingLogicalHeight);
|
| // It's rather pointless to break before the block if the current line isn't going to
|
| // fit in the same column or page, so check that as well.
|
| - if (totalLogicalHeight <= pageLogicalHeightAtNewOffset)
|
| + if (totalLogicalHeight <= pageLogicalHeight)
|
| wantsStrutOnBlock = true;
|
| }
|
| return wantsStrutOnBlock && block.allowsPaginationStrut();
|
| @@ -779,17 +774,25 @@ void LayoutBlockFlow::adjustLinePositionForPagination(RootInlineBox& lineBox, La
|
| LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
|
| if (!pageLogicalHeight)
|
| return;
|
| - if (lineHeight > pageLogicalHeight) {
|
| - // Too tall to fit in one page / column. Give up. Don't push to the next page / column.
|
| - // TODO(mstensho): Get rid of this. This is just utter weirdness, but the other browsers
|
| - // also do something slightly similar, although in much more specific cases than we do here,
|
| - // and printing Google Docs depends on it.
|
| - return;
|
| - }
|
| LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, AssociateWithLatterPage);
|
| -
|
| int lineIndex = lineCount(&lineBox);
|
| if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)) {
|
| + LayoutUnit paginationStrut = calculatePaginationStrutToFitContent(logicalOffset, remainingLogicalHeight, lineHeight);
|
| + LayoutUnit newLogicalOffset = logicalOffset + paginationStrut;
|
| + // The new offset may require us to insert a new row for columns (fragmentainer group).
|
| + // Give the multicol machinery an opportunity to do so (before checking the height of a
|
| + // column that wouldn't have existed yet otherwise).
|
| + paginatedContentWasLaidOut(newLogicalOffset);
|
| + // Moving to a different page or column may mean that its height is different.
|
| + pageLogicalHeight = pageLogicalHeightForOffset(newLogicalOffset);
|
| + if (lineHeight > pageLogicalHeight) {
|
| + // Too tall to fit in one page / column. Give up. Don't push to the next page / column.
|
| + // TODO(mstensho): Get rid of this. This is just utter weirdness, but the other browsers
|
| + // also do something slightly similar, although in much more specific cases than we do here,
|
| + // and printing Google Docs depends on it.
|
| + return;
|
| + }
|
| +
|
| // We need to insert a break now, either because there's no room for the line in the
|
| // current column / page, or because we have determined that we need a break to satisfy
|
| // widow requirements.
|
| @@ -797,21 +800,23 @@ void LayoutBlockFlow::adjustLinePositionForPagination(RootInlineBox& lineBox, La
|
| clearShouldBreakAtLineToAvoidWidow();
|
| setDidBreakAtLineToAvoidWidow();
|
| }
|
| - if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, remainingLogicalHeight)) {
|
| + if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, pageLogicalHeight)) {
|
| // Note that when setting the strut on a block, it may be propagated to parent blocks
|
| // later on, if a block's logical top is flush with that of its parent. We don't want
|
| // content-less portions (struts) at the beginning of a block before a break, if it can
|
| // be avoided. After all, that's the reason for setting struts on blocks and not lines
|
| // in the first place.
|
| - LayoutUnit strut = remainingLogicalHeight + logicalOffset + marginBeforeIfFloating();
|
| + LayoutUnit strut = paginationStrut + logicalOffset + marginBeforeIfFloating();
|
| setPaginationStrutPropagatedFromChild(strut);
|
| } else {
|
| - logicalOffset += remainingLogicalHeight;
|
| - delta += remainingLogicalHeight;
|
| - lineBox.setPaginationStrut(remainingLogicalHeight);
|
| + delta += paginationStrut;
|
| + lineBox.setPaginationStrut(paginationStrut);
|
| lineBox.setIsFirstAfterPageBreak(true);
|
| }
|
| - } else if (remainingLogicalHeight == pageLogicalHeight) {
|
| + return;
|
| + }
|
| +
|
| + if (remainingLogicalHeight == pageLogicalHeight) {
|
| // We're at the very top of a page or column.
|
| if (lineBox != firstRootBox())
|
| lineBox.setIsFirstAfterPageBreak(true);
|
| @@ -819,7 +824,7 @@ void LayoutBlockFlow::adjustLinePositionForPagination(RootInlineBox& lineBox, La
|
| // case it's a float) margin, we may want to set a strut on the block, so that everything
|
| // ends up in the next column or page. Setting a strut on the block is also important when
|
| // it comes to satisfying orphan requirements.
|
| - if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, remainingLogicalHeight)) {
|
| + if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, pageLogicalHeight)) {
|
| LayoutUnit strut = logicalOffset + marginBeforeIfFloating();
|
| setPaginationStrutPropagatedFromChild(strut);
|
| }
|
| @@ -853,11 +858,15 @@ LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutU
|
| if (!pageLogicalHeight)
|
| return logicalOffset;
|
| LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, AssociateWithLatterPage);
|
| - // Break if there's not enough space left for us, but only as long as we're not already at the
|
| - // top of a page. No point in leaving a page completely blank.
|
| - if (remainingLogicalHeight < childLogicalHeight && remainingLogicalHeight < pageLogicalHeight)
|
| - return logicalOffset + remainingLogicalHeight;
|
| - return logicalOffset;
|
| + if (remainingLogicalHeight >= childLogicalHeight)
|
| + return logicalOffset; // It fits fine where it is. No need to break.
|
| + LayoutUnit paginationStrut = calculatePaginationStrutToFitContent(logicalOffset, remainingLogicalHeight, childLogicalHeight);
|
| + if (paginationStrut == remainingLogicalHeight && remainingLogicalHeight == pageLogicalHeight) {
|
| + // Don't break if we were at the top of a page, and we failed to fit the content
|
| + // completely. No point in leaving a page completely blank.
|
| + return logicalOffset;
|
| + }
|
| + return logicalOffset + paginationStrut;
|
| }
|
|
|
| void LayoutBlockFlow::rebuildFloatsFromIntruding()
|
|
|