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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp

Issue 2479483002: Properly avoid breaking inside a float's top margin. (Closed)
Patch Set: Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 // |previousStrut| was already baked into the logical top, so don't add 1033 // |previousStrut| was already baked into the logical top, so don't add
1034 // it again. 1034 // it again.
1035 newLogicalTop += paginationStrut - previousStrut; 1035 newLogicalTop += paginationStrut - previousStrut;
1036 } else { 1036 } else {
1037 // No valid break point here. Propagate the strut from the child to this 1037 // No valid break point here. Propagate the strut from the child to this
1038 // block, but only if the block allows it. If the block doesn't allow it, 1038 // block, but only if the block allows it. If the block doesn't allow it,
1039 // we'll just ignore the strut and carry on, without breaking. This 1039 // we'll just ignore the strut and carry on, without breaking. This
1040 // happens e.g. when a tall break-inside:avoid object with a top margin is 1040 // happens e.g. when a tall break-inside:avoid object with a top margin is
1041 // the first in-flow child in the fragmentation context. 1041 // the first in-flow child in the fragmentation context.
1042 if (allowsPaginationStrut()) { 1042 if (allowsPaginationStrut()) {
1043 paginationStrut += logicalTop + marginBeforeIfFloating(); 1043 paginationStrut += logicalTop;
1044 setPaginationStrutPropagatedFromChild(paginationStrut); 1044 setPaginationStrutPropagatedFromChild(paginationStrut);
1045 if (childBlockFlow) 1045 if (childBlockFlow)
1046 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit()); 1046 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit());
1047 } 1047 }
1048 child.resetPaginationStrut(); 1048 child.resetPaginationStrut();
1049 } 1049 }
1050 } 1050 }
1051 1051
1052 // Similar to how we apply clearance. Go ahead and boost height() to be the 1052 // Similar to how we apply clearance. Go ahead and boost height() to be the
1053 // place where we're going to position the child. 1053 // place where we're going to position the child.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 setDidBreakAtLineToAvoidWidow(); 1155 setDidBreakAtLineToAvoidWidow();
1156 } 1156 }
1157 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, 1157 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex,
1158 pageLogicalHeight)) { 1158 pageLogicalHeight)) {
1159 // Note that when setting the strut on a block, it may be propagated to 1159 // Note that when setting the strut on a block, it may be propagated to
1160 // parent blocks later on, if a block's logical top is flush with that of 1160 // parent blocks later on, if a block's logical top is flush with that of
1161 // its parent. We don't want content-less portions (struts) at the 1161 // its parent. We don't want content-less portions (struts) at the
1162 // beginning of a block before a break, if it can be avoided. After all, 1162 // beginning of a block before a break, if it can be avoided. After all,
1163 // that's the reason for setting struts on blocks and not lines in the 1163 // that's the reason for setting struts on blocks and not lines in the
1164 // first place. 1164 // first place.
1165 LayoutUnit strut = 1165 setPaginationStrutPropagatedFromChild(paginationStrut + logicalOffset);
1166 paginationStrut + logicalOffset + marginBeforeIfFloating();
1167 setPaginationStrutPropagatedFromChild(strut);
1168 } else { 1166 } else {
1169 delta += paginationStrut; 1167 delta += paginationStrut;
1170 lineBox.setPaginationStrut(paginationStrut); 1168 lineBox.setPaginationStrut(paginationStrut);
1171 lineBox.setIsFirstAfterPageBreak(true); 1169 lineBox.setIsFirstAfterPageBreak(true);
1172 } 1170 }
1173 paginatedContentWasLaidOut(newLogicalOffset + lineHeight); 1171 paginatedContentWasLaidOut(newLogicalOffset + lineHeight);
1174 return; 1172 return;
1175 } 1173 }
1176 1174
1177 LayoutUnit strutToPropagate; 1175 LayoutUnit strutToPropagate;
1178 if (remainingLogicalHeight == pageLogicalHeight) { 1176 if (remainingLogicalHeight == pageLogicalHeight) {
1179 // We're at the very top of a page or column. 1177 // We're at the very top of a page or column.
1180 if (lineBox != firstRootBox()) 1178 if (lineBox != firstRootBox())
1181 lineBox.setIsFirstAfterPageBreak(true); 1179 lineBox.setIsFirstAfterPageBreak(true);
1182 // If this is the first line in the block, and the block has a top border, 1180 // If this is the first line in the block, and the block has a top border or
1183 // padding, or (in case it's a float) margin, we may want to set a strut on 1181 // padding, we may want to set a strut on the block, so that everything ends
1184 // the block, so that everything ends up in the next column or page. Setting 1182 // up in the next column or page. Setting a strut on the block is also
1185 // a strut on the block is also important when it comes to satisfying orphan 1183 // important when it comes to satisfying orphan requirements.
1186 // requirements.
1187 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, 1184 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex,
1188 pageLogicalHeight)) 1185 pageLogicalHeight))
1189 strutToPropagate = logicalOffset + marginBeforeIfFloating(); 1186 strutToPropagate = logicalOffset;
1190 } else if (lineBox == firstRootBox() && allowsPaginationStrut()) { 1187 } else if (lineBox == firstRootBox() && allowsPaginationStrut()) {
1191 // This is the first line in the block. The block may still start in the 1188 // This is the first line in the block. The block may still start in the
1192 // previous column or page, and if that's the case, attempt to pull it over 1189 // previous column or page, and if that's the case, attempt to pull it over
1193 // to where this line is, so that we don't split the top border, padding, or 1190 // to where this line is, so that we don't split the top border or padding.
1194 // (in case it's a float) margin.
1195 LayoutUnit totalLogicalOffset = logicalOffset + marginBeforeIfFloating();
1196 LayoutUnit strut = 1191 LayoutUnit strut =
1197 remainingLogicalHeight + totalLogicalOffset - pageLogicalHeight; 1192 remainingLogicalHeight + logicalOffset - pageLogicalHeight;
1198 if (strut > 0) { 1193 if (strut > LayoutUnit()) {
1199 // The block starts in a previous column or page. Set a strut on the block 1194 // The block starts in a previous column or page. Set a strut on the block
1200 // if there's room for the top border, padding and (if it's a float) 1195 // if there's room for the top border, padding and the line in one column
1201 // margin and the line in one column or page. 1196 // or page.
1202 if (totalLogicalOffset + lineHeight <= pageLogicalHeight) 1197 if (logicalOffset + lineHeight <= pageLogicalHeight)
1203 strutToPropagate = strut; 1198 strutToPropagate = strut;
1204 } 1199 }
1205 } 1200 }
1206 1201
1207 // If we found that some preceding content (lines, border and padding) belongs 1202 // If we found that some preceding content (lines, border and padding) belongs
1208 // together with this line, we should pull the entire block with us to the 1203 // together with this line, we should pull the entire block with us to the
1209 // fragmentainer we're currently in. We need to avoid this when the block 1204 // fragmentainer we're currently in. We need to avoid this when the block
1210 // precedes the first fragmentainer, though. We shouldn't fragment content 1205 // precedes the first fragmentainer, though. We shouldn't fragment content
1211 // there, but rather let it appear in the overflow area before the first 1206 // there, but rather let it appear in the overflow area before the first
1212 // fragmentainer. 1207 // fragmentainer.
(...skipping 2477 matching lines...) Expand 10 before | Expand all | Expand 10 after
3690 childBox->layoutIfNeeded(); 3685 childBox->layoutIfNeeded();
3691 3686
3692 if (isPaginated) { 3687 if (isPaginated) {
3693 LayoutBlockFlow* childBlockFlow = 3688 LayoutBlockFlow* childBlockFlow =
3694 childBox->isLayoutBlockFlow() ? toLayoutBlockFlow(childBox) : nullptr; 3689 childBox->isLayoutBlockFlow() ? toLayoutBlockFlow(childBox) : nullptr;
3695 // The first piece of content inside the child may have set a strut during 3690 // The first piece of content inside the child may have set a strut during
3696 // layout. 3691 // layout.
3697 LayoutUnit strut = 3692 LayoutUnit strut =
3698 childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild() 3693 childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild()
3699 : LayoutUnit(); 3694 : LayoutUnit();
3695
3696 LayoutUnit marginBefore = marginBeforeForChild(*childBox);
3697 if (marginBefore > LayoutUnit()) {
3698 // Avoid breaking inside the top margin of a float.
3699 if (strut) {
3700 // If we already had decided to break, just add the margin. The strut
3701 // so far only accounts for pushing the top border edge to the next
3702 // fragmentainer. We need to push the margin over as well, because
3703 // there's no break opportunity between margin and border.
3704 strut += marginBefore;
3705 } else {
3706 // Even if we didn't break before the border box to the next
3707 // fragmentainer, we need to check if we can fit the margin before
3708 // it.
3709 LayoutUnit marginEdge = childBox->logicalTop() - marginBefore;
3710 if (LayoutUnit pageHeight = pageLogicalHeightForOffset(marginEdge)) {
3711 LayoutUnit remainingSpace = pageRemainingLogicalHeightForOffset(
3712 marginEdge, AssociateWithLatterPage);
3713 if (remainingSpace <= marginBefore)
3714 strut += remainingSpace;
3715 }
3716 }
3717 }
3700 if (!strut) { 3718 if (!strut) {
3701 // Otherwise, if we are unsplittable and don't fit, move to the next 3719 // If we are unsplittable and don't fit, move to the next page or column
3702 // page or column if that helps the situation. 3720 // if that helps the situation.
3703 strut = 3721 strut =
3704 adjustForUnsplittableChild(*childBox, floatLogicalLocation.y()) - 3722 adjustForUnsplittableChild(*childBox, floatLogicalLocation.y()) -
3705 floatLogicalLocation.y(); 3723 floatLogicalLocation.y();
3706 } 3724 }
3707 3725
3708 childBox->setPaginationStrut(strut); 3726 childBox->setPaginationStrut(strut);
3709 if (strut) { 3727 if (strut) {
3710 floatLogicalLocation = computeLogicalLocationForFloat( 3728 floatLogicalLocation = computeLogicalLocationForFloat(
3711 floatingObject, floatLogicalLocation.y() + strut); 3729 floatingObject, floatLogicalLocation.y() + strut);
3712 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); 3730 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
4550 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); 4568 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState);
4551 } 4569 }
4552 4570
4553 void LayoutBlockFlow::invalidateDisplayItemClients( 4571 void LayoutBlockFlow::invalidateDisplayItemClients(
4554 PaintInvalidationReason invalidationReason) const { 4572 PaintInvalidationReason invalidationReason) const {
4555 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( 4573 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients(
4556 invalidationReason); 4574 invalidationReason);
4557 } 4575 }
4558 4576
4559 } // namespace blink 4577 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlockFlow.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698