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 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1048 } | 1048 } |
1049 | 1049 |
1050 // Similar to how we apply clearance. Go ahead and boost height() to be the | 1050 // Similar to how we apply clearance. Go ahead and boost height() to be the |
1051 // place where we're going to position the child. | 1051 // place where we're going to position the child. |
1052 setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop)); | 1052 setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop)); |
1053 | 1053 |
1054 // Return the final adjusted logical top. | 1054 // Return the final adjusted logical top. |
1055 return newLogicalTop; | 1055 return newLogicalTop; |
1056 } | 1056 } |
1057 | 1057 |
1058 LayoutUnit LayoutBlockFlow::adjustFloatForPagination( | |
szager1
2016/11/17 19:27:52
Can you rename this to something that indicates th
mstensho (USE GERRIT)
2016/11/17 20:06:57
Done.
| |
1059 LayoutBox& child, | |
1060 LayoutUnit logicalTopMarginEdge) { | |
1061 // The first piece of content inside the child may have set a strut during | |
1062 // layout. | |
1063 LayoutUnit strut; | |
1064 if (child.isLayoutBlockFlow()) | |
1065 strut = toLayoutBlockFlow(child).paginationStrutPropagatedFromChild(); | |
1066 | |
1067 LayoutUnit marginBefore = marginBeforeForChild(child); | |
1068 if (marginBefore > LayoutUnit()) { | |
1069 // Avoid breaking inside the top margin of a float. | |
1070 if (strut) { | |
1071 // If we already had decided to break, just add the margin. The strut so | |
1072 // far only accounts for pushing the top border edge to the next | |
1073 // fragmentainer. We need to push the margin over as well, because | |
1074 // there's no break opportunity between margin and border. | |
1075 strut += marginBefore; | |
1076 } else { | |
1077 // Even if we didn't break before the border box to the next | |
1078 // fragmentainer, we need to check if we can fit the margin before it. | |
1079 if (LayoutUnit pageLogicalHeight = | |
1080 pageLogicalHeightForOffset(logicalTopMarginEdge)) { | |
1081 LayoutUnit remainingSpace = pageRemainingLogicalHeightForOffset( | |
1082 logicalTopMarginEdge, AssociateWithLatterPage); | |
1083 if (remainingSpace <= marginBefore) | |
1084 strut += remainingSpace; | |
1085 } | |
1086 } | |
1087 } | |
1088 if (!strut) { | |
1089 // If we are unsplittable and don't fit, move to the next page or column | |
1090 // if that helps the situation. | |
1091 LayoutUnit newLogicalTopMarginEdge = | |
1092 adjustForUnsplittableChild(child, logicalTopMarginEdge); | |
1093 strut = newLogicalTopMarginEdge - logicalTopMarginEdge; | |
1094 } | |
1095 | |
1096 child.setPaginationStrut(strut); | |
1097 return logicalTopMarginEdge + strut; | |
1098 } | |
1099 | |
1058 static bool shouldSetStrutOnBlock(const LayoutBlockFlow& block, | 1100 static bool shouldSetStrutOnBlock(const LayoutBlockFlow& block, |
1059 const RootInlineBox& lineBox, | 1101 const RootInlineBox& lineBox, |
1060 LayoutUnit lineLogicalOffset, | 1102 LayoutUnit lineLogicalOffset, |
1061 int lineIndex, | 1103 int lineIndex, |
1062 LayoutUnit pageLogicalHeight) { | 1104 LayoutUnit pageLogicalHeight) { |
1063 if (lineBox == block.firstRootBox()) { | 1105 if (lineBox == block.firstRootBox()) { |
1064 // This is the first line in the block. We can take the whole block with us | 1106 // This is the first line in the block. We can take the whole block with us |
1065 // to the next page or column, rather than keeping a content-less portion of | 1107 // to the next page or column, rather than keeping a content-less portion of |
1066 // it in the previous one. Only do this if the line is flush with the | 1108 // it in the previous one. Only do this if the line is flush with the |
1067 // content edge of the block, though. If it isn't, it means that the line | 1109 // content edge of the block, though. If it isn't, it means that the line |
(...skipping 2547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3615 | 3657 |
3616 if (width) | 3658 if (width) |
3617 width->shrinkAvailableWidthForNewFloatIfNeeded(floatingObject); | 3659 width->shrinkAvailableWidthForNewFloatIfNeeded(floatingObject); |
3618 } | 3660 } |
3619 return true; | 3661 return true; |
3620 } | 3662 } |
3621 | 3663 |
3622 LayoutUnit LayoutBlockFlow::positionAndLayoutFloat( | 3664 LayoutUnit LayoutBlockFlow::positionAndLayoutFloat( |
3623 FloatingObject& floatingObject, | 3665 FloatingObject& floatingObject, |
3624 LayoutUnit logicalTopMarginEdge) { | 3666 LayoutUnit logicalTopMarginEdge) { |
3625 LayoutBox& childBox = *floatingObject.layoutObject(); | 3667 LayoutBox& child = *floatingObject.layoutObject(); |
3626 | 3668 |
3627 // FIXME Investigate if this can be removed. crbug.com/370006 | 3669 // FIXME Investigate if this can be removed. crbug.com/370006 |
3628 childBox.setMayNeedPaintInvalidation(); | 3670 child.setMayNeedPaintInvalidation(); |
3629 | 3671 |
3630 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() | 3672 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() |
3631 ? marginStartForChild(childBox) | 3673 ? marginStartForChild(child) |
3632 : marginEndForChild(childBox); | 3674 : marginEndForChild(child); |
3633 logicalTopMarginEdge = | 3675 logicalTopMarginEdge = std::max( |
3634 std::max(logicalTopMarginEdge, | 3676 logicalTopMarginEdge, lowestFloatLogicalBottom(child.style()->clear())); |
3635 lowestFloatLogicalBottom(childBox.style()->clear())); | |
3636 | 3677 |
3637 bool isPaginated = view()->layoutState()->isPaginated(); | 3678 bool isPaginated = view()->layoutState()->isPaginated(); |
3638 if (isPaginated && !childrenInline()) { | 3679 if (isPaginated && !childrenInline()) { |
3639 // Forced breaks are inserted at class A break points. Floats may be | 3680 // Forced breaks are inserted at class A break points. Floats may be |
3640 // affected by a break-after value on the previous in-flow sibling. | 3681 // affected by a break-after value on the previous in-flow sibling. |
3641 if (LayoutBox* previousInFlowBox = childBox.previousInFlowSiblingBox()) { | 3682 if (LayoutBox* previousInFlowBox = child.previousInFlowSiblingBox()) { |
3642 logicalTopMarginEdge = applyForcedBreak(logicalTopMarginEdge, | 3683 logicalTopMarginEdge = applyForcedBreak(logicalTopMarginEdge, |
3643 previousInFlowBox->breakAfter()); | 3684 previousInFlowBox->breakAfter()); |
3644 } | 3685 } |
3645 } | 3686 } |
3646 | 3687 |
3647 LayoutPoint floatLogicalLocation = | 3688 LayoutPoint floatLogicalLocation = |
3648 computeLogicalLocationForFloat(floatingObject, logicalTopMarginEdge); | 3689 computeLogicalLocationForFloat(floatingObject, logicalTopMarginEdge); |
3649 logicalTopMarginEdge = floatLogicalLocation.y(); | 3690 logicalTopMarginEdge = floatLogicalLocation.y(); |
3650 | 3691 |
3651 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); | 3692 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); |
3652 | 3693 |
3653 setLogicalLeftForChild(childBox, | 3694 setLogicalLeftForChild(child, |
3654 floatLogicalLocation.x() + childLogicalLeftMargin); | 3695 floatLogicalLocation.x() + childLogicalLeftMargin); |
3655 setLogicalTopForChild(childBox, | 3696 setLogicalTopForChild(child, |
3656 logicalTopMarginEdge + marginBeforeForChild(childBox)); | 3697 logicalTopMarginEdge + marginBeforeForChild(child)); |
3657 | 3698 |
3658 SubtreeLayoutScope layoutScope(childBox); | 3699 SubtreeLayoutScope layoutScope(child); |
3659 if (isPaginated && !childBox.needsLayout()) | 3700 if (isPaginated && !child.needsLayout()) |
3660 markChildForPaginationRelayoutIfNeeded(childBox, layoutScope); | 3701 markChildForPaginationRelayoutIfNeeded(child, layoutScope); |
3661 | 3702 |
3662 childBox.layoutIfNeeded(); | 3703 child.layoutIfNeeded(); |
3663 | 3704 |
3664 if (isPaginated) { | 3705 if (isPaginated) { |
3665 LayoutBlockFlow* childBlockFlow = | 3706 LayoutUnit newLogicalTopMarginEdge = |
3666 childBox.isLayoutBlockFlow() ? toLayoutBlockFlow(&childBox) : nullptr; | 3707 adjustFloatForPagination(child, logicalTopMarginEdge); |
3667 // The first piece of content inside the child may have set a strut during | 3708 if (logicalTopMarginEdge != newLogicalTopMarginEdge) { |
3668 // layout. | |
3669 LayoutUnit strut = | |
3670 childBlockFlow ? childBlockFlow->paginationStrutPropagatedFromChild() | |
3671 : LayoutUnit(); | |
3672 | |
3673 LayoutUnit marginBefore = marginBeforeForChild(childBox); | |
3674 if (marginBefore > LayoutUnit()) { | |
3675 // Avoid breaking inside the top margin of a float. | |
3676 if (strut) { | |
3677 // If we already had decided to break, just add the margin. The strut | |
3678 // so far only accounts for pushing the top border edge to the next | |
3679 // fragmentainer. We need to push the margin over as well, because | |
3680 // there's no break opportunity between margin and border. | |
3681 strut += marginBefore; | |
3682 } else { | |
3683 // Even if we didn't break before the border box to the next | |
3684 // fragmentainer, we need to check if we can fit the margin before | |
3685 // it. | |
3686 LayoutUnit marginEdge = childBox.logicalTop() - marginBefore; | |
3687 if (LayoutUnit pageHeight = pageLogicalHeightForOffset(marginEdge)) { | |
3688 LayoutUnit remainingSpace = pageRemainingLogicalHeightForOffset( | |
3689 marginEdge, AssociateWithLatterPage); | |
3690 if (remainingSpace <= marginBefore) | |
3691 strut += remainingSpace; | |
3692 } | |
3693 } | |
3694 } | |
3695 if (!strut) { | |
3696 // If we are unsplittable and don't fit, move to the next page or column | |
3697 // if that helps the situation. | |
3698 strut = adjustForUnsplittableChild(childBox, logicalTopMarginEdge) - | |
3699 logicalTopMarginEdge; | |
3700 } | |
3701 | |
3702 childBox.setPaginationStrut(strut); | |
3703 if (strut) { | |
3704 floatLogicalLocation = computeLogicalLocationForFloat( | 3709 floatLogicalLocation = computeLogicalLocationForFloat( |
3705 floatingObject, logicalTopMarginEdge + strut); | 3710 floatingObject, newLogicalTopMarginEdge); |
3706 logicalTopMarginEdge = floatLogicalLocation.y(); | 3711 logicalTopMarginEdge = floatLogicalLocation.y(); |
3707 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); | 3712 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); |
3708 | 3713 |
3709 setLogicalLeftForChild(childBox, | 3714 setLogicalLeftForChild(child, |
3710 floatLogicalLocation.x() + childLogicalLeftMargin); | 3715 floatLogicalLocation.x() + childLogicalLeftMargin); |
3711 setLogicalTopForChild( | 3716 setLogicalTopForChild(child, |
3712 childBox, logicalTopMarginEdge + marginBeforeForChild(childBox)); | 3717 logicalTopMarginEdge + marginBeforeForChild(child)); |
3713 | 3718 |
3714 if (childBox.isLayoutBlock()) | 3719 if (child.isLayoutBlock()) |
3715 childBox.setChildNeedsLayout(MarkOnlyThis); | 3720 child.setChildNeedsLayout(MarkOnlyThis); |
3716 childBox.layoutIfNeeded(); | 3721 child.layoutIfNeeded(); |
3717 } | 3722 } |
3718 } | 3723 } |
3719 | 3724 |
3720 setLogicalTopForFloat(floatingObject, logicalTopMarginEdge); | 3725 setLogicalTopForFloat(floatingObject, logicalTopMarginEdge); |
3721 | 3726 |
3722 setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + | 3727 setLogicalHeightForFloat(floatingObject, logicalHeightForChild(child) + |
3723 marginBeforeForChild(childBox) + | 3728 marginBeforeForChild(child) + |
3724 marginAfterForChild(childBox)); | 3729 marginAfterForChild(child)); |
3725 | 3730 |
3726 if (ShapeOutsideInfo* shapeOutside = childBox.shapeOutsideInfo()) | 3731 if (ShapeOutsideInfo* shapeOutside = child.shapeOutsideInfo()) |
3727 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(childBox)); | 3732 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(child)); |
3728 | 3733 |
3729 return logicalTopMarginEdge; | 3734 return logicalTopMarginEdge; |
3730 } | 3735 } |
3731 | 3736 |
3732 bool LayoutBlockFlow::hasOverhangingFloat(LayoutBox* layoutBox) { | 3737 bool LayoutBlockFlow::hasOverhangingFloat(LayoutBox* layoutBox) { |
3733 if (!m_floatingObjects || !parent()) | 3738 if (!m_floatingObjects || !parent()) |
3734 return false; | 3739 return false; |
3735 | 3740 |
3736 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 3741 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
3737 FloatingObjectSetIterator it = | 3742 FloatingObjectSetIterator it = |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4547 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4552 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
4548 } | 4553 } |
4549 | 4554 |
4550 void LayoutBlockFlow::invalidateDisplayItemClients( | 4555 void LayoutBlockFlow::invalidateDisplayItemClients( |
4551 PaintInvalidationReason invalidationReason) const { | 4556 PaintInvalidationReason invalidationReason) const { |
4552 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4557 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
4553 invalidationReason); | 4558 invalidationReason); |
4554 } | 4559 } |
4555 | 4560 |
4556 } // namespace blink | 4561 } // namespace blink |
OLD | NEW |