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

Unified Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp

Issue 1375673004: Keep block pagination struts after layout, and store them before any type of break. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: code review Created 5 years, 2 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 | « third_party/WebKit/Source/core/core.gypi ('k') | third_party/WebKit/Source/core/layout/LayoutBox.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3f9c12f381a38e37c3da6530c8d553774887fc86..92885dac8d79a9247a7cdc442cd2bae88a0e39cc 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -685,27 +685,47 @@ LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
{
LayoutBlockFlow* childBlockFlow = child.isLayoutBlockFlow() ? toLayoutBlockFlow(&child) : 0;
+ // Calculate the pagination strut for this child. A strut may come from three sources:
+ // 1. The first piece of content inside the child doesn't fit in the current page or column
+ // 2. A forced break before the child
+ // 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.
+
+ // 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.
+ child.resetPaginationStrut();
+
+ // The first piece of content inside the child may have set a strut during layout. Currently,
+ // only block flows support strut propagation, but this may (and should) change in the future.
+ // See crbug.com/539873
+ LayoutUnit strutFromContent = childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild() : LayoutUnit();
+ LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent;
+
// If the object has a page or column break value of "before", then we should shift to the top of the next page.
- LayoutUnit newLogicalTop = applyBeforeBreak(child, logicalTop);
+ LayoutUnit logicalTopAfterForcedBreak = applyBeforeBreak(child, 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 logicalTopBeforeUnsplittableAdjustment = newLogicalTop;
- LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, newLogicalTop);
-
- LayoutUnit paginationStrut = 0;
- LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
+ LayoutUnit logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, logicalTop);
LayoutUnit childLogicalHeight = child.logicalHeight();
- if (unsplittableAdjustmentDelta) {
- setPageBreak(newLogicalTop, childLogicalHeight - unsplittableAdjustmentDelta);
- paginationStrut = unsplittableAdjustmentDelta;
- } else if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromChild()) {
- paginationStrut = childBlockFlow->paginationStrutPropagatedFromChild();
- }
-
- if (paginationStrut) {
+ bool neededBreakForUnsplittable = logicalTopAfterUnsplittable != logicalTop;
+ if (neededBreakForUnsplittable)
+ setPageBreak(logicalTop, childLogicalHeight - (logicalTopAfterUnsplittable - 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);
+
+ LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut, std::max(logicalTopAfterForcedBreak, logicalTopAfterUnsplittable));
+ LayoutUnit newLogicalTop = logicalTop;
+ if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) {
+ ASSERT(paginationStrut > 0);
// We are willing to propagate out to our parent block as long as we were at the top of the block prior
// to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
- if (atBeforeSideOfBlock && logicalTop == newLogicalTop && allowsPaginationStrut()) {
+ if (atBeforeSideOfBlock && logicalTopAfterForcedBreak == logicalTop && allowsPaginationStrut()) {
// FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
// have all the information to do so (the strut only has the remaining amount to push). Gecko gets this wrong too
// and pushes to the next page anyway, so not too concerned about it.
@@ -716,11 +736,12 @@ LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
if (childBlockFlow)
childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit());
} else {
+ child.setPaginationStrut(paginationStrut);
newLogicalTop += paginationStrut;
}
}
- if (!unsplittableAdjustmentDelta) {
+ if (!neededBreakForUnsplittable) {
if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogicalTop)) {
LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(newLogicalTop, AssociateWithLatterPage);
LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeight;
@@ -2409,24 +2430,19 @@ bool LayoutBlockFlow::positionNewFloats(LineWidth* width)
childBox->layoutIfNeeded();
if (isPaginated) {
- LayoutUnit newLogicalTop = floatLogicalLocation.y();
-
- LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? toLayoutBlockFlow(childBox) : 0;
- if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromChild()) {
- // Some content inside this float has determined that we need to move to the next
- // page or column.
- newLogicalTop += childBlockFlow->paginationStrutPropagatedFromChild();
- } else {
- // Now that we know the final height, check if we are unsplittable, and if we don't
- // fit at the current position, but would fit at the top of the next page or
- // column, move there.
- newLogicalTop = adjustForUnsplittableChild(*childBox, newLogicalTop);
+ LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? toLayoutBlockFlow(childBox) : nullptr;
+ // The first piece of content inside the child may have set a strut during layout.
+ LayoutUnit strut = childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild() : LayoutUnit();
+ if (!strut) {
+ // Otherwise, if we are unsplittable and don't fit, move to the next page or column
+ // if that helps the situation.
+ strut = adjustForUnsplittableChild(*childBox, floatLogicalLocation.y()) - floatLogicalLocation.y();
}
- if (newLogicalTop != floatLogicalLocation.y()) {
- floatingObject.setPaginationStrut(newLogicalTop - floatLogicalLocation.y());
-
- floatLogicalLocation = computeLogicalLocationForFloat(floatingObject, newLogicalTop);
+ floatingObject.setPaginationStrut(strut);
+ childBox->setPaginationStrut(strut);
+ if (strut) {
+ floatLogicalLocation = computeLogicalLocationForFloat(floatingObject, floatLogicalLocation.y() + strut);
setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
setLogicalLeftForChild(*childBox, floatLogicalLocation.x() + childLogicalLeftMargin);
« no previous file with comments | « third_party/WebKit/Source/core/core.gypi ('k') | third_party/WebKit/Source/core/layout/LayoutBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698