Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1523)

Unified Diff: Source/core/rendering/RenderBlock.cpp

Issue 16943008: Column balancing support in the region based multicol implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBox.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/RenderBlock.cpp
diff --git a/Source/core/rendering/RenderBlock.cpp b/Source/core/rendering/RenderBlock.cpp
index 98447ab9250f181d8ec38c173bdfd69223f760a2..1877404f63443ad579ea0c940b5bde5227316de2 100644
--- a/Source/core/rendering/RenderBlock.cpp
+++ b/Source/core/rendering/RenderBlock.cpp
@@ -7386,11 +7386,9 @@ LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit
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 @@ bool RenderBlock::pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment,
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 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, Layout
// 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 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, Layout
}
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 @@ LayoutUnit RenderBlock::adjustBlockChildForPagination(LayoutUnit logicalTopAfter
// 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);
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBox.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698