OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |