OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011 Apple 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 : positionOffset(position), distributionOffset(distribution) {} | 48 : positionOffset(position), distributionOffset(distribution) {} |
49 | 49 |
50 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; } | 50 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; } |
51 | 51 |
52 LayoutUnit positionOffset = LayoutUnit(-1); | 52 LayoutUnit positionOffset = LayoutUnit(-1); |
53 LayoutUnit distributionOffset = LayoutUnit(-1); | 53 LayoutUnit distributionOffset = LayoutUnit(-1); |
54 }; | 54 }; |
55 | 55 |
56 LayoutGrid::LayoutGrid(Element* element) | 56 LayoutGrid::LayoutGrid(Element* element) |
57 : LayoutBlock(element), m_grid(this), m_trackSizingAlgorithm(this, m_grid) { | 57 : LayoutBlock(element), m_grid(this), m_trackSizingAlgorithm(this, m_grid) { |
58 ASSERT(!childrenInline()); | 58 DCHECK(!childrenInline()); |
59 if (!isAnonymous()) | 59 if (!isAnonymous()) |
60 UseCounter::count(document(), UseCounter::CSSGridLayout); | 60 UseCounter::count(document(), UseCounter::CSSGridLayout); |
61 } | 61 } |
62 | 62 |
63 LayoutGrid::~LayoutGrid() {} | 63 LayoutGrid::~LayoutGrid() {} |
64 | 64 |
65 LayoutGrid* LayoutGrid::createAnonymous(Document* document) { | 65 LayoutGrid* LayoutGrid::createAnonymous(Document* document) { |
66 LayoutGrid* layoutGrid = new LayoutGrid(nullptr); | 66 LayoutGrid* layoutGrid = new LayoutGrid(nullptr); |
67 layoutGrid->setDocumentForAnonymous(document); | 67 layoutGrid->setDocumentForAnonymous(document); |
68 return layoutGrid; | 68 return layoutGrid; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 // all the cases with orthogonal flows require this extra cycle; we need a | 177 // all the cases with orthogonal flows require this extra cycle; we need a |
178 // more specific condition to detect whether child's min-content contribution | 178 // more specific condition to detect whether child's min-content contribution |
179 // has changed or not. | 179 // has changed or not. |
180 if (m_grid.hasAnyOrthogonalGridItem()) { | 180 if (m_grid.hasAnyOrthogonalGridItem()) { |
181 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns); | 181 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns); |
182 computeTrackSizesForDefiniteSize(ForRows, availableSpaceForRows); | 182 computeTrackSizesForDefiniteSize(ForRows, availableSpaceForRows); |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 void LayoutGrid::layoutBlock(bool relayoutChildren) { | 186 void LayoutGrid::layoutBlock(bool relayoutChildren) { |
187 ASSERT(needsLayout()); | 187 DCHECK(needsLayout()); |
188 | 188 |
189 // We cannot perform a simplifiedLayout() on a dirty grid that | 189 // We cannot perform a simplifiedLayout() on a dirty grid that |
190 // has positioned items to be laid out. | 190 // has positioned items to be laid out. |
191 if (!relayoutChildren && | 191 if (!relayoutChildren && |
192 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) && | 192 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) && |
193 simplifiedLayout()) | 193 simplifiedLayout()) |
194 return; | 194 return; |
195 | 195 |
196 SubtreeLayoutScope layoutScope(*this); | 196 SubtreeLayoutScope layoutScope(*this); |
197 | 197 |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 | 694 |
695 grid.setNeedsItemsPlacement(false); | 695 grid.setNeedsItemsPlacement(false); |
696 | 696 |
697 #if DCHECK_IS_ON() | 697 #if DCHECK_IS_ON() |
698 for (LayoutBox* child = grid.orderIterator().first(); child; | 698 for (LayoutBox* child = grid.orderIterator().first(); child; |
699 child = grid.orderIterator().next()) { | 699 child = grid.orderIterator().next()) { |
700 if (child->isOutOfFlowPositioned()) | 700 if (child->isOutOfFlowPositioned()) |
701 continue; | 701 continue; |
702 | 702 |
703 GridArea area = grid.gridItemArea(*child); | 703 GridArea area = grid.gridItemArea(*child); |
704 ASSERT(area.rows.isTranslatedDefinite() && | 704 DCHECK(area.rows.isTranslatedDefinite()); |
705 area.columns.isTranslatedDefinite()); | 705 DCHECK(area.columns.isTranslatedDefinite()); |
706 } | 706 } |
707 #endif | 707 #endif |
708 } | 708 } |
709 | 709 |
710 void LayoutGrid::populateExplicitGridAndOrderIterator(Grid& grid) const { | 710 void LayoutGrid::populateExplicitGridAndOrderIterator(Grid& grid) const { |
711 OrderIteratorPopulator populator(grid.orderIterator()); | 711 OrderIteratorPopulator populator(grid.orderIterator()); |
712 int smallestRowStart = 0; | 712 int smallestRowStart = 0; |
713 int smallestColumnStart = 0; | 713 int smallestColumnStart = 0; |
714 | 714 |
715 size_t autoRepeatRows = grid.autoRepeatTracks(ForRows); | 715 size_t autoRepeatRows = grid.autoRepeatTracks(ForRows); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 // auto-placed item's position inserted on that track. This is needed to | 797 // auto-placed item's position inserted on that track. This is needed to |
798 // implement "sparse" packing for items locked to a given track. | 798 // implement "sparse" packing for items locked to a given track. |
799 // See http://dev.w3.org/csswg/css-grid/#auto-placement-algo | 799 // See http://dev.w3.org/csswg/css-grid/#auto-placement-algo |
800 HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, | 800 HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, |
801 WTF::UnsignedWithZeroKeyHashTraits<unsigned>> | 801 WTF::UnsignedWithZeroKeyHashTraits<unsigned>> |
802 minorAxisCursors; | 802 minorAxisCursors; |
803 | 803 |
804 for (const auto& autoGridItem : autoGridItems) { | 804 for (const auto& autoGridItem : autoGridItems) { |
805 GridSpan majorAxisPositions = | 805 GridSpan majorAxisPositions = |
806 grid.gridItemSpan(*autoGridItem, autoPlacementMajorAxisDirection()); | 806 grid.gridItemSpan(*autoGridItem, autoPlacementMajorAxisDirection()); |
807 ASSERT(majorAxisPositions.isTranslatedDefinite()); | 807 DCHECK(majorAxisPositions.isTranslatedDefinite()); |
808 DCHECK(!grid.gridItemSpan(*autoGridItem, autoPlacementMinorAxisDirection()) | 808 DCHECK(!grid.gridItemSpan(*autoGridItem, autoPlacementMinorAxisDirection()) |
809 .isTranslatedDefinite()); | 809 .isTranslatedDefinite()); |
810 size_t minorAxisSpanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( | 810 size_t minorAxisSpanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( |
811 *style(), *autoGridItem, autoPlacementMinorAxisDirection()); | 811 *style(), *autoGridItem, autoPlacementMinorAxisDirection()); |
812 unsigned majorAxisInitialPosition = majorAxisPositions.startLine(); | 812 unsigned majorAxisInitialPosition = majorAxisPositions.startLine(); |
813 | 813 |
814 GridIterator iterator( | 814 GridIterator iterator( |
815 grid, autoPlacementMajorAxisDirection(), majorAxisPositions.startLine(), | 815 grid, autoPlacementMajorAxisDirection(), majorAxisPositions.startLine(), |
816 isGridAutoFlowDense ? 0 | 816 isGridAutoFlowDense ? 0 |
817 : minorAxisCursors.at(majorAxisInitialPosition)); | 817 : minorAxisCursors.at(majorAxisInitialPosition)); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 | 1091 |
1092 child->layoutIfNeeded(); | 1092 child->layoutIfNeeded(); |
1093 | 1093 |
1094 // We need pending layouts to be done in order to compute auto-margins | 1094 // We need pending layouts to be done in order to compute auto-margins |
1095 // properly. | 1095 // properly. |
1096 updateAutoMarginsInColumnAxisIfNeeded(*child); | 1096 updateAutoMarginsInColumnAxisIfNeeded(*child); |
1097 updateAutoMarginsInRowAxisIfNeeded(*child); | 1097 updateAutoMarginsInRowAxisIfNeeded(*child); |
1098 | 1098 |
1099 const GridArea& area = m_grid.gridItemArea(*child); | 1099 const GridArea& area = m_grid.gridItemArea(*child); |
1100 #if DCHECK_IS_ON() | 1100 #if DCHECK_IS_ON() |
1101 DCHECK(area.columns.startLine() < | 1101 DCHECK_LT(area.columns.startLine(), |
1102 m_trackSizingAlgorithm.tracks(ForColumns).size()); | 1102 m_trackSizingAlgorithm.tracks(ForColumns).size()); |
1103 DCHECK(area.rows.startLine() < | 1103 DCHECK_LT(area.rows.startLine(), |
1104 m_trackSizingAlgorithm.tracks(ForRows).size()); | 1104 m_trackSizingAlgorithm.tracks(ForRows).size()); |
1105 #endif | 1105 #endif |
1106 child->setLogicalLocation(findChildLogicalPosition(*child)); | 1106 child->setLogicalLocation(findChildLogicalPosition(*child)); |
1107 | 1107 |
1108 // Keep track of children overflowing their grid area as we might need to | 1108 // Keep track of children overflowing their grid area as we might need to |
1109 // paint them even if the grid-area is not visible. Using physical | 1109 // paint them even if the grid-area is not visible. Using physical |
1110 // dimensions for simplicity, so we can forget about orthogonalty. | 1110 // dimensions for simplicity, so we can forget about orthogonalty. |
1111 LayoutUnit childGridAreaHeight = | 1111 LayoutUnit childGridAreaHeight = |
1112 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalHeight | 1112 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalHeight |
1113 : overrideContainingBlockContentLogicalWidth; | 1113 : overrideContainingBlockContentLogicalWidth; |
1114 LayoutUnit childGridAreaWidth = | 1114 LayoutUnit childGridAreaWidth = |
1115 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalWidth | 1115 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalWidth |
1116 : overrideContainingBlockContentLogicalHeight; | 1116 : overrideContainingBlockContentLogicalHeight; |
1117 LayoutRect gridAreaRect( | 1117 LayoutRect gridAreaRect( |
1118 gridAreaLogicalPosition(area), | 1118 gridAreaLogicalPosition(area), |
1119 LayoutSize(childGridAreaWidth, childGridAreaHeight)); | 1119 LayoutSize(childGridAreaWidth, childGridAreaHeight)); |
1120 if (!gridAreaRect.contains(child->frameRect())) | 1120 if (!gridAreaRect.contains(child->frameRect())) |
1121 m_gridItemsOverflowingGridArea.push_back(child); | 1121 m_gridItemsOverflowingGridArea.push_back(child); |
1122 } | 1122 } |
1123 } | 1123 } |
1124 | 1124 |
1125 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) { | 1125 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) { |
1126 ASSERT(child.isOutOfFlowPositioned()); | 1126 DCHECK(child.isOutOfFlowPositioned()); |
1127 child.containingBlock()->insertPositionedObject(&child); | 1127 child.containingBlock()->insertPositionedObject(&child); |
1128 | 1128 |
1129 PaintLayer* childLayer = child.layer(); | 1129 PaintLayer* childLayer = child.layer(); |
1130 childLayer->setStaticInlinePosition(LayoutUnit(borderStart())); | 1130 childLayer->setStaticInlinePosition(LayoutUnit(borderStart())); |
1131 childLayer->setStaticBlockPosition(LayoutUnit(borderBefore())); | 1131 childLayer->setStaticBlockPosition(LayoutUnit(borderBefore())); |
1132 } | 1132 } |
1133 | 1133 |
1134 void LayoutGrid::layoutPositionedObjects(bool relayoutChildren, | 1134 void LayoutGrid::layoutPositionedObjects(bool relayoutChildren, |
1135 PositionedLayoutBehavior info) { | 1135 PositionedLayoutBehavior info) { |
1136 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); | 1136 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); |
(...skipping 28 matching lines...) Expand all Loading... |
1165 | 1165 |
1166 layoutPositionedObject(child, relayoutChildren, info); | 1166 layoutPositionedObject(child, relayoutChildren, info); |
1167 } | 1167 } |
1168 } | 1168 } |
1169 | 1169 |
1170 void LayoutGrid::offsetAndBreadthForPositionedChild( | 1170 void LayoutGrid::offsetAndBreadthForPositionedChild( |
1171 const LayoutBox& child, | 1171 const LayoutBox& child, |
1172 GridTrackSizingDirection direction, | 1172 GridTrackSizingDirection direction, |
1173 LayoutUnit& offset, | 1173 LayoutUnit& offset, |
1174 LayoutUnit& breadth) { | 1174 LayoutUnit& breadth) { |
1175 ASSERT(!isOrthogonalChild(child)); | 1175 DCHECK(!isOrthogonalChild(child)); |
1176 bool isForColumns = direction == ForColumns; | 1176 bool isForColumns = direction == ForColumns; |
1177 | 1177 |
1178 GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle( | 1178 GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle( |
1179 *style(), child, direction, autoRepeatCountForDirection(direction)); | 1179 *style(), child, direction, autoRepeatCountForDirection(direction)); |
1180 if (positions.isIndefinite()) { | 1180 if (positions.isIndefinite()) { |
1181 offset = LayoutUnit(); | 1181 offset = LayoutUnit(); |
1182 breadth = isForColumns ? clientLogicalWidth() : clientLogicalHeight(); | 1182 breadth = isForColumns ? clientLogicalWidth() : clientLogicalHeight(); |
1183 return; | 1183 return; |
1184 } | 1184 } |
1185 | 1185 |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1508 return child.styleRef().marginLeft().isAuto() || | 1508 return child.styleRef().marginLeft().isAuto() || |
1509 child.styleRef().marginRight().isAuto(); | 1509 child.styleRef().marginRight().isAuto(); |
1510 return child.styleRef().marginTop().isAuto() || | 1510 return child.styleRef().marginTop().isAuto() || |
1511 child.styleRef().marginBottom().isAuto(); | 1511 child.styleRef().marginBottom().isAuto(); |
1512 } | 1512 } |
1513 | 1513 |
1514 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be | 1514 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be |
1515 // moved to LayoutBox. | 1515 // moved to LayoutBox. |
1516 DISABLE_CFI_PERF | 1516 DISABLE_CFI_PERF |
1517 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) { | 1517 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) { |
1518 ASSERT(!child.isOutOfFlowPositioned()); | 1518 DCHECK(!child.isOutOfFlowPositioned()); |
1519 | 1519 |
1520 LayoutUnit availableAlignmentSpace = | 1520 LayoutUnit availableAlignmentSpace = |
1521 child.overrideContainingBlockContentLogicalWidth() - | 1521 child.overrideContainingBlockContentLogicalWidth() - |
1522 child.logicalWidth() - child.marginLogicalWidth(); | 1522 child.logicalWidth() - child.marginLogicalWidth(); |
1523 if (availableAlignmentSpace <= 0) | 1523 if (availableAlignmentSpace <= 0) |
1524 return; | 1524 return; |
1525 | 1525 |
1526 Length marginStart = child.style()->marginStartUsing(style()); | 1526 Length marginStart = child.style()->marginStartUsing(style()); |
1527 Length marginEnd = child.style()->marginEndUsing(style()); | 1527 Length marginEnd = child.style()->marginEndUsing(style()); |
1528 if (marginStart.isAuto() && marginEnd.isAuto()) { | 1528 if (marginStart.isAuto() && marginEnd.isAuto()) { |
1529 child.setMarginStart(availableAlignmentSpace / 2, style()); | 1529 child.setMarginStart(availableAlignmentSpace / 2, style()); |
1530 child.setMarginEnd(availableAlignmentSpace / 2, style()); | 1530 child.setMarginEnd(availableAlignmentSpace / 2, style()); |
1531 } else if (marginStart.isAuto()) { | 1531 } else if (marginStart.isAuto()) { |
1532 child.setMarginStart(availableAlignmentSpace, style()); | 1532 child.setMarginStart(availableAlignmentSpace, style()); |
1533 } else if (marginEnd.isAuto()) { | 1533 } else if (marginEnd.isAuto()) { |
1534 child.setMarginEnd(availableAlignmentSpace, style()); | 1534 child.setMarginEnd(availableAlignmentSpace, style()); |
1535 } | 1535 } |
1536 } | 1536 } |
1537 | 1537 |
1538 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be | 1538 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be |
1539 // moved to LayoutBox. | 1539 // moved to LayoutBox. |
1540 DISABLE_CFI_PERF | 1540 DISABLE_CFI_PERF |
1541 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) { | 1541 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) { |
1542 ASSERT(!child.isOutOfFlowPositioned()); | 1542 DCHECK(!child.isOutOfFlowPositioned()); |
1543 | 1543 |
1544 LayoutUnit availableAlignmentSpace = | 1544 LayoutUnit availableAlignmentSpace = |
1545 child.overrideContainingBlockContentLogicalHeight() - | 1545 child.overrideContainingBlockContentLogicalHeight() - |
1546 child.logicalHeight() - child.marginLogicalHeight(); | 1546 child.logicalHeight() - child.marginLogicalHeight(); |
1547 if (availableAlignmentSpace <= 0) | 1547 if (availableAlignmentSpace <= 0) |
1548 return; | 1548 return; |
1549 | 1549 |
1550 Length marginBefore = child.style()->marginBeforeUsing(style()); | 1550 Length marginBefore = child.style()->marginBeforeUsing(style()); |
1551 Length marginAfter = child.style()->marginAfterUsing(style()); | 1551 Length marginAfter = child.style()->marginAfterUsing(style()); |
1552 if (marginBefore.isAuto() && marginAfter.isAuto()) { | 1552 if (marginBefore.isAuto() && marginAfter.isAuto()) { |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 return {LayoutUnit(), LayoutUnit()}; | 2031 return {LayoutUnit(), LayoutUnit()}; |
2032 case ContentPositionNormal: | 2032 case ContentPositionNormal: |
2033 break; | 2033 break; |
2034 } | 2034 } |
2035 | 2035 |
2036 NOTREACHED(); | 2036 NOTREACHED(); |
2037 return {LayoutUnit(), LayoutUnit()}; | 2037 return {LayoutUnit(), LayoutUnit()}; |
2038 } | 2038 } |
2039 | 2039 |
2040 LayoutUnit LayoutGrid::translateRTLCoordinate(LayoutUnit coordinate) const { | 2040 LayoutUnit LayoutGrid::translateRTLCoordinate(LayoutUnit coordinate) const { |
2041 ASSERT(!styleRef().isLeftToRightDirection()); | 2041 DCHECK(!styleRef().isLeftToRightDirection()); |
2042 | 2042 |
2043 LayoutUnit alignmentOffset = m_columnPositions[0]; | 2043 LayoutUnit alignmentOffset = m_columnPositions[0]; |
2044 LayoutUnit rightGridEdgePosition = | 2044 LayoutUnit rightGridEdgePosition = |
2045 m_columnPositions[m_columnPositions.size() - 1]; | 2045 m_columnPositions[m_columnPositions.size() - 1]; |
2046 return rightGridEdgePosition + alignmentOffset - coordinate; | 2046 return rightGridEdgePosition + alignmentOffset - coordinate; |
2047 } | 2047 } |
2048 | 2048 |
2049 LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child) const { | 2049 LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child) const { |
2050 LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child); | 2050 LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child); |
2051 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child); | 2051 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2103 if (direction == ForRows) | 2103 if (direction == ForRows) |
2104 return grid.numTracks(ForRows); | 2104 return grid.numTracks(ForRows); |
2105 | 2105 |
2106 return grid.numTracks(ForRows) | 2106 return grid.numTracks(ForRows) |
2107 ? grid.numTracks(ForColumns) | 2107 ? grid.numTracks(ForColumns) |
2108 : GridPositionsResolver::explicitGridColumnCount( | 2108 : GridPositionsResolver::explicitGridColumnCount( |
2109 styleRef(), grid.autoRepeatTracks(ForColumns)); | 2109 styleRef(), grid.autoRepeatTracks(ForColumns)); |
2110 } | 2110 } |
2111 | 2111 |
2112 } // namespace blink | 2112 } // namespace blink |
OLD | NEW |