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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 // collapsing and clearance. After having applied those things, we'll be at | 808 // collapsing and clearance. After having applied those things, we'll be at |
809 // the position where we can honor requirements of unbreakable content, | 809 // the position where we can honor requirements of unbreakable content, |
810 // which may extend the strut further. | 810 // which may extend the strut further. |
811 child.resetPaginationStrut(); | 811 child.resetPaginationStrut(); |
812 insertForcedBreakBeforeChildIfNeeded(child, layoutInfo); | 812 insertForcedBreakBeforeChildIfNeeded(child, layoutInfo); |
813 } | 813 } |
814 | 814 |
815 // Now determine the correct ypos based off examination of collapsing margin | 815 // Now determine the correct ypos based off examination of collapsing margin |
816 // values. | 816 // values. |
817 LayoutUnit logicalTopBeforeClear = | 817 LayoutUnit logicalTopBeforeClear = |
818 collapseMargins(child, marginInfo, childIsSelfCollapsing, | 818 collapseMargins(child, layoutInfo, childIsSelfCollapsing, |
819 childDiscardMarginBefore, childDiscardMarginAfter); | 819 childDiscardMarginBefore, childDiscardMarginAfter); |
820 | 820 |
821 // Now check for clear. | 821 // Now check for clear. |
822 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfter; | 822 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfter; |
823 LayoutUnit newLogicalTop = clearFloatsIfNeeded( | 823 LayoutUnit newLogicalTop = clearFloatsIfNeeded( |
824 child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, | 824 child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, |
825 logicalTopBeforeClear, childIsSelfCollapsing, childDiscardMargin); | 825 logicalTopBeforeClear, childIsSelfCollapsing, childDiscardMargin); |
826 | 826 |
827 // If there's a forced break in front of this child, its final position has | 827 // If there's a forced break in front of this child, its final position has |
828 // already been determined. Otherwise, see if there are other reasons for | 828 // already been determined. Otherwise, see if there are other reasons for |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1592 if (afterMargin > 0) | 1592 if (afterMargin > 0) |
1593 childAfterPositive = afterMargin; | 1593 childAfterPositive = afterMargin; |
1594 else | 1594 else |
1595 childAfterNegative = -afterMargin; | 1595 childAfterNegative = -afterMargin; |
1596 } | 1596 } |
1597 | 1597 |
1598 return LayoutBlockFlow::MarginValues(childBeforePositive, childBeforeNegative, | 1598 return LayoutBlockFlow::MarginValues(childBeforePositive, childBeforeNegative, |
1599 childAfterPositive, childAfterNegative); | 1599 childAfterPositive, childAfterNegative); |
1600 } | 1600 } |
1601 | 1601 |
| 1602 LayoutUnit LayoutBlockFlow::adjustedMarginBeforeForPagination( |
| 1603 const LayoutBox& child, |
| 1604 LayoutUnit logicalTopMarginEdge, |
| 1605 LayoutUnit logicalTopBorderEdge, |
| 1606 const BlockChildrenLayoutInfo& layoutInfo) const { |
| 1607 LayoutUnit effectiveMargin = logicalTopBorderEdge - logicalTopMarginEdge; |
| 1608 DCHECK(isPageLogicalHeightKnown()); |
| 1609 if (effectiveMargin <= LayoutUnit()) |
| 1610 return effectiveMargin; |
| 1611 // If margins would pull us past the top of the next fragmentainer, then we |
| 1612 // need to pull back and let the margins collapse into the fragmentainer |
| 1613 // boundary. If we're at a fragmentainer boundary, and there's no forced break |
| 1614 // involved, collapse the margin with the boundary we're at. Otherwise, |
| 1615 // preserve the margin at the top of the fragmentainer, but collapse it with |
| 1616 // the next fragmentainer boundary, since no margin should ever live in more |
| 1617 // than one fragmentainer. |
| 1618 PageBoundaryRule rule = AssociateWithLatterPage; |
| 1619 if (!child.needsForcedBreakBefore(layoutInfo.previousBreakAfterValue()) && |
| 1620 offsetFromLogicalTopOfFirstPage() + logicalTopMarginEdge > LayoutUnit()) |
| 1621 rule = AssociateWithFormerPage; |
| 1622 LayoutUnit remainingSpace = |
| 1623 pageRemainingLogicalHeightForOffset(logicalTopMarginEdge, rule); |
| 1624 return std::min(effectiveMargin, remainingSpace); |
| 1625 } |
| 1626 |
1602 LayoutUnit LayoutBlockFlow::collapseMargins(LayoutBox& child, | 1627 LayoutUnit LayoutBlockFlow::collapseMargins(LayoutBox& child, |
1603 MarginInfo& marginInfo, | 1628 BlockChildrenLayoutInfo& layoutInfo, |
1604 bool childIsSelfCollapsing, | 1629 bool childIsSelfCollapsing, |
1605 bool childDiscardMarginBefore, | 1630 bool childDiscardMarginBefore, |
1606 bool childDiscardMarginAfter) { | 1631 bool childDiscardMarginAfter) { |
| 1632 MarginInfo& marginInfo = layoutInfo.marginInfo(); |
| 1633 |
1607 // The child discards the before margin when the the after margin has discard | 1634 // The child discards the before margin when the the after margin has discard |
1608 // in the case of a self collapsing block. | 1635 // in the case of a self collapsing block. |
1609 childDiscardMarginBefore = childDiscardMarginBefore || | 1636 childDiscardMarginBefore = childDiscardMarginBefore || |
1610 (childDiscardMarginAfter && childIsSelfCollapsing); | 1637 (childDiscardMarginAfter && childIsSelfCollapsing); |
1611 | 1638 |
1612 // Get the four margin values for the child and cache them. | 1639 // Get the four margin values for the child and cache them. |
1613 const LayoutBlockFlow::MarginValues childMargins = | 1640 const LayoutBlockFlow::MarginValues childMargins = |
1614 marginValuesForChild(child); | 1641 marginValuesForChild(child); |
1615 | 1642 |
1616 // Get our max pos and neg top margins. | 1643 // Get our max pos and neg top margins. |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); | 1785 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); |
1759 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); | 1786 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); |
1760 } else { | 1787 } else { |
1761 marginInfo.clearMargin(); | 1788 marginInfo.clearMargin(); |
1762 } | 1789 } |
1763 | 1790 |
1764 if (marginInfo.margin()) | 1791 if (marginInfo.margin()) |
1765 marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(&child)); | 1792 marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(&child)); |
1766 } | 1793 } |
1767 | 1794 |
1768 // If margins would pull us past the top of the next page, then we need to | 1795 if (view()->layoutState()->isPaginated() && isPageLogicalHeightKnown()) { |
1769 // pull back and pretend like the margins collapsed into the page edge. | |
1770 LayoutState* layoutState = view()->layoutState(); | |
1771 if (layoutState->isPaginated() && isPageLogicalHeightKnown() && | |
1772 logicalTop > beforeCollapseLogicalTop) { | |
1773 LayoutUnit oldLogicalTop = logicalTop; | 1796 LayoutUnit oldLogicalTop = logicalTop; |
1774 logicalTop = | 1797 LayoutUnit margin = adjustedMarginBeforeForPagination( |
1775 std::min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop)); | 1798 child, beforeCollapseLogicalTop, logicalTop, layoutInfo); |
| 1799 logicalTop = beforeCollapseLogicalTop + margin; |
1776 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); | 1800 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); |
1777 } | 1801 } |
1778 | 1802 |
1779 // If |child| has moved up into previous siblings it needs to avoid or clear | 1803 // If |child| has moved up into previous siblings it needs to avoid or clear |
1780 // any floats they contain. | 1804 // any floats they contain. |
1781 LayoutUnit oldLogicalHeight = logicalHeight(); | 1805 LayoutUnit oldLogicalHeight = logicalHeight(); |
1782 setLogicalHeight(logicalTop); | 1806 setLogicalHeight(logicalTop); |
1783 while (previousBlockFlow) { | 1807 while (previousBlockFlow) { |
1784 auto lowestFloat = previousBlockFlow->logicalTop() + | 1808 auto lowestFloat = previousBlockFlow->logicalTop() + |
1785 previousBlockFlow->lowestFloatLogicalBottom(); | 1809 previousBlockFlow->lowestFloatLogicalBottom(); |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2056 discardMarginBefore = mustDiscardMarginBeforeForChild(child); | 2080 discardMarginBefore = mustDiscardMarginBeforeForChild(child); |
2057 } | 2081 } |
2058 | 2082 |
2059 // Collapse the result with our current margins. | 2083 // Collapse the result with our current margins. |
2060 if (!discardMarginBefore) | 2084 if (!discardMarginBefore) |
2061 logicalTopEstimate += | 2085 logicalTopEstimate += |
2062 std::max(marginInfo.positiveMargin(), positiveMarginBefore) - | 2086 std::max(marginInfo.positiveMargin(), positiveMarginBefore) - |
2063 std::max(marginInfo.negativeMargin(), negativeMarginBefore); | 2087 std::max(marginInfo.negativeMargin(), negativeMarginBefore); |
2064 } | 2088 } |
2065 | 2089 |
2066 // Adjust logicalTopEstimate down to the next page if the margins are so large | |
2067 // that we don't fit on the current page. | |
2068 LayoutState* layoutState = view()->layoutState(); | 2090 LayoutState* layoutState = view()->layoutState(); |
2069 if (layoutState->isPaginated() && isPageLogicalHeightKnown() && | 2091 if (layoutState->isPaginated() && isPageLogicalHeightKnown()) { |
2070 logicalTopEstimate > logicalHeight()) | 2092 LayoutUnit margin = adjustedMarginBeforeForPagination( |
2071 logicalTopEstimate = | 2093 child, logicalHeight(), logicalTopEstimate, layoutInfo); |
2072 std::min(logicalTopEstimate, nextPageLogicalTop(logicalHeight())); | 2094 logicalTopEstimate = logicalHeight() + margin; |
| 2095 } |
2073 | 2096 |
2074 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); | 2097 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); |
2075 | 2098 |
2076 estimateWithoutPagination = logicalTopEstimate; | 2099 estimateWithoutPagination = logicalTopEstimate; |
2077 | 2100 |
2078 if (layoutState->isPaginated()) { | 2101 if (layoutState->isPaginated()) { |
2079 if (!layoutInfo.isAtFirstInFlowChild()) { | 2102 if (!layoutInfo.isAtFirstInFlowChild()) { |
2080 // Estimate the need for a forced break in front of this child. The final | 2103 // Estimate the need for a forced break in front of this child. The final |
2081 // break policy at this class A break point isn't known until we have laid | 2104 // break policy at this class A break point isn't known until we have laid |
2082 // out the children of |child|. There may be forced break-before values | 2105 // out the children of |child|. There may be forced break-before values |
(...skipping 2458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4541 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4564 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
4542 } | 4565 } |
4543 | 4566 |
4544 void LayoutBlockFlow::invalidateDisplayItemClients( | 4567 void LayoutBlockFlow::invalidateDisplayItemClients( |
4545 PaintInvalidationReason invalidationReason) const { | 4568 PaintInvalidationReason invalidationReason) const { |
4546 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4569 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
4547 invalidationReason); | 4570 invalidationReason); |
4548 } | 4571 } |
4549 | 4572 |
4550 } // namespace blink | 4573 } // namespace blink |
OLD | NEW |