| 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex)
{ | 115 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex)
{ |
| 116 const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; | 116 const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; |
| 117 if (m_childIndex < children.size()) | 117 if (m_childIndex < children.size()) |
| 118 return children[m_childIndex++]; | 118 return children[m_childIndex++]; |
| 119 | 119 |
| 120 m_childIndex = 0; | 120 m_childIndex = 0; |
| 121 } | 121 } |
| 122 return 0; | 122 return 0; |
| 123 } | 123 } |
| 124 | 124 |
| 125 PassOwnPtr<GridCoordinate> nextEmptyGridArea() | 125 bool checkEmptyCells(size_t rowSpan, size_t columnSpan) const |
| 126 { |
| 127 // Ignore cells outside current grid as we will grow it later if needed. |
| 128 size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size()); |
| 129 size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size(
)); |
| 130 |
| 131 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect
spanning areas to be small. |
| 132 for (size_t row = m_rowIndex; row < maxRows; ++row) { |
| 133 for (size_t column = m_columnIndex; column < maxColumns; ++column) { |
| 134 const GridCell& children = m_grid[row][column]; |
| 135 if (!children.isEmpty()) |
| 136 return false; |
| 137 } |
| 138 } |
| 139 |
| 140 return true; |
| 141 } |
| 142 |
| 143 PassOwnPtr<GridCoordinate> nextEmptyGridArea(size_t fixedTrackSpan, size_t v
aryingTrackSpan) |
| 126 { | 144 { |
| 127 ASSERT(!m_grid.isEmpty()); | 145 ASSERT(!m_grid.isEmpty()); |
| 146 ASSERT(fixedTrackSpan >= 1 && varyingTrackSpan >= 1); |
| 147 |
| 148 size_t rowSpan = (m_direction == ForColumns) ? varyingTrackSpan : fixedT
rackSpan; |
| 149 size_t columnSpan = (m_direction == ForColumns) ? fixedTrackSpan : varyi
ngTrackSpan; |
| 128 | 150 |
| 129 size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m
_columnIndex; | 151 size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m
_columnIndex; |
| 130 const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_gr
id.size() : m_grid[0].size(); | 152 const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_gr
id.size() : m_grid[0].size(); |
| 131 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex)
{ | 153 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex)
{ |
| 132 const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; | 154 if (checkEmptyCells(rowSpan, columnSpan)) { |
| 133 if (children.isEmpty()) { | 155 OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(Grid
Span(m_rowIndex, m_rowIndex + rowSpan - 1), GridSpan(m_columnIndex, m_columnInde
x + columnSpan - 1))); |
| 134 OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(Grid
Span(m_rowIndex, m_rowIndex), GridSpan(m_columnIndex, m_columnIndex))); | |
| 135 // Advance the iterator to avoid an infinite loop where we would
return the same grid area over and over. | 156 // Advance the iterator to avoid an infinite loop where we would
return the same grid area over and over. |
| 136 ++varyingTrackIndex; | 157 ++varyingTrackIndex; |
| 137 return result.release(); | 158 return result.release(); |
| 138 } | 159 } |
| 139 } | 160 } |
| 140 return nullptr; | 161 return nullptr; |
| 141 } | 162 } |
| 142 | 163 |
| 143 private: | 164 private: |
| 144 const GridRepresentation& m_grid; | 165 const GridRepresentation& m_grid; |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromA
utoPlacementPosition(*style(), *child, ForColumns, GridResolvedPosition(0)); | 860 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromA
utoPlacementPosition(*style(), *child, ForColumns, GridResolvedPosition(0)); |
| 840 maximumColumnIndex = std::max<size_t>(maximumColumnIndex, positions.
resolvedFinalPosition.next().toInt()); | 861 maximumColumnIndex = std::max<size_t>(maximumColumnIndex, positions.
resolvedFinalPosition.next().toInt()); |
| 841 } | 862 } |
| 842 } | 863 } |
| 843 | 864 |
| 844 m_grid.grow(maximumRowIndex); | 865 m_grid.grow(maximumRowIndex); |
| 845 for (size_t i = 0; i < m_grid.size(); ++i) | 866 for (size_t i = 0; i < m_grid.size(); ++i) |
| 846 m_grid[i].grow(maximumColumnIndex); | 867 m_grid[i].grow(maximumColumnIndex); |
| 847 } | 868 } |
| 848 | 869 |
| 849 bool RenderGrid::checkEmptyCells(const GridCoordinate& coordinate) const | |
| 850 { | |
| 851 // Ignore cells outside current grid as we will grow it later if needed. | |
| 852 size_t maxRows = std::min(coordinate.rows.resolvedFinalPosition.next().toInt
(), gridRowCount()); | |
| 853 size_t maxColumns = std::min(coordinate.columns.resolvedFinalPosition.next()
.toInt(), gridColumnCount()); | |
| 854 | |
| 855 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spa
nning areas to be small. | |
| 856 for (size_t row = coordinate.rows.resolvedInitialPosition.toInt(); row < max
Rows; ++row) { | |
| 857 for (size_t column = coordinate.columns.resolvedInitialPosition.toInt();
column < maxColumns; ++column) { | |
| 858 const GridCell& children = m_grid[row][column]; | |
| 859 if (!children.isEmpty()) | |
| 860 return false; | |
| 861 } | |
| 862 } | |
| 863 | |
| 864 return true; | |
| 865 } | |
| 866 | |
| 867 PassOwnPtr<GridCoordinate> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOu
tsideGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection
, const GridSpan& specifiedPositions) const | 870 PassOwnPtr<GridCoordinate> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOu
tsideGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection
, const GridSpan& specifiedPositions) const |
| 868 { | 871 { |
| 869 GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ?
ForRows : ForColumns; | 872 GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ?
ForRows : ForColumns; |
| 870 const size_t endOfCrossDirection = crossDirection == ForColumns ? gridColumn
Count() : gridRowCount(); | 873 const size_t endOfCrossDirection = crossDirection == ForColumns ? gridColumn
Count() : gridRowCount(); |
| 871 GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPosition
sFromAutoPlacementPosition(*style(), *gridItem, crossDirection, GridResolvedPosi
tion(endOfCrossDirection)); | 874 GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPosition
sFromAutoPlacementPosition(*style(), *gridItem, crossDirection, GridResolvedPosi
tion(endOfCrossDirection)); |
| 872 return adoptPtr(new GridCoordinate(specifiedDirection == ForColumns ? crossD
irectionPositions : specifiedPositions, specifiedDirection == ForColumns ? speci
fiedPositions : crossDirectionPositions)); | 875 return adoptPtr(new GridCoordinate(specifiedDirection == ForColumns ? crossD
irectionPositions : specifiedPositions, specifiedDirection == ForColumns ? speci
fiedPositions : crossDirectionPositions)); |
| 873 } | 876 } |
| 874 | 877 |
| 875 PassOwnPtr<GridCoordinate> RenderGrid::findEmptyGridAreaAtSpecifiedPositionsInsi
deGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection, c
onst GridSpan& specifiedPositions) const | |
| 876 { | |
| 877 GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ?
ForRows : ForColumns; | |
| 878 | |
| 879 GridIterator iterator(m_grid, specifiedDirection, specifiedPositions.resolve
dInitialPosition.toInt()); | |
| 880 OwnPtr<GridCoordinate> emptyGridArea; | |
| 881 for (emptyGridArea = iterator.nextEmptyGridArea(); emptyGridArea; emptyGridA
rea = iterator.nextEmptyGridArea()) { | |
| 882 GridResolvedPosition crossDirectionInitialPositionIndex = crossDirection
== ForColumns ? emptyGridArea->columns.resolvedInitialPosition : emptyGridArea-
>rows.resolvedInitialPosition; | |
| 883 GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPosi
tionsFromAutoPlacementPosition(*style(), *gridItem, crossDirection, crossDirecti
onInitialPositionIndex); | |
| 884 | |
| 885 emptyGridArea->rows = specifiedDirection == ForColumns ? crossDirectionP
ositions : specifiedPositions; | |
| 886 emptyGridArea->columns = specifiedDirection == ForColumns ? specifiedPos
itions : crossDirectionPositions; | |
| 887 if (checkEmptyCells(*emptyGridArea)) | |
| 888 break; | |
| 889 } | |
| 890 | |
| 891 return emptyGridArea.release(); | |
| 892 } | |
| 893 | |
| 894 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au
toGridItems) | 878 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au
toGridItems) |
| 895 { | 879 { |
| 896 for (size_t i = 0; i < autoGridItems.size(); ++i) { | 880 for (size_t i = 0; i < autoGridItems.size(); ++i) { |
| 897 OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridP
ositionsFromStyle(*style(), *autoGridItems[i], autoPlacementMajorAxisDirection()
); | 881 OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridP
ositionsFromStyle(*style(), *autoGridItems[i], autoPlacementMajorAxisDirection()
); |
| 898 OwnPtr<GridCoordinate> emptyGridArea = findEmptyGridAreaAtSpecifiedPosit
ionsInsideGrid(autoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPo
sitions); | 882 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositions
FromAutoPlacementPosition(*style(), *autoGridItems[i], autoPlacementMinorAxisDir
ection(), GridResolvedPosition(0)); |
| 883 |
| 884 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx
isPositions->resolvedInitialPosition.toInt()); |
| 885 OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorA
xisPositions->integerSpan(), minorAxisPositions.integerSpan()); |
| 899 if (!emptyGridArea) | 886 if (!emptyGridArea) |
| 900 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(a
utoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPositions); | 887 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(a
utoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPositions); |
| 901 insertItemIntoGrid(autoGridItems[i], *emptyGridArea); | 888 insertItemIntoGrid(autoGridItems[i], *emptyGridArea); |
| 902 } | 889 } |
| 903 } | 890 } |
| 904 | 891 |
| 905 void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri
dItems) | 892 void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri
dItems) |
| 906 { | 893 { |
| 907 for (size_t i = 0; i < autoGridItems.size(); ++i) | 894 for (size_t i = 0; i < autoGridItems.size(); ++i) |
| 908 placeAutoMajorAxisItemOnGrid(autoGridItems[i]); | 895 placeAutoMajorAxisItemOnGrid(autoGridItems[i]); |
| 909 } | 896 } |
| 910 | 897 |
| 911 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) | 898 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) |
| 912 { | 899 { |
| 913 OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPosit
ionsFromStyle(*style(), *gridItem, autoPlacementMinorAxisDirection()); | 900 OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPosit
ionsFromStyle(*style(), *gridItem, autoPlacementMinorAxisDirection()); |
| 914 ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridI
tem, autoPlacementMajorAxisDirection())); | 901 ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridI
tem, autoPlacementMajorAxisDirection())); |
| 902 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFrom
AutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirection(), Gr
idResolvedPosition(0)); |
| 915 OwnPtr<GridCoordinate> emptyGridArea; | 903 OwnPtr<GridCoordinate> emptyGridArea; |
| 916 if (minorAxisPositions) { | 904 if (minorAxisPositions) { |
| 917 emptyGridArea = findEmptyGridAreaAtSpecifiedPositionsInsideGrid(gridItem
, autoPlacementMinorAxisDirection(), *minorAxisPositions); | 905 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAx
isPositions->resolvedInitialPosition.toInt()); |
| 906 emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions->integerSp
an(), majorAxisPositions.integerSpan()); |
| 918 if (!emptyGridArea) | 907 if (!emptyGridArea) |
| 919 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g
ridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions); | 908 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g
ridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions); |
| 920 } else { | 909 } else { |
| 910 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositions
FromAutoPlacementPosition(*style(), *gridItem, autoPlacementMinorAxisDirection()
, GridResolvedPosition(0)); |
| 911 |
| 921 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForC
olumns) ? gridColumnCount() : gridRowCount(); | 912 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForC
olumns) ? gridColumnCount() : gridRowCount(); |
| 922 for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++major
AxisIndex) { | 913 for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++major
AxisIndex) { |
| 923 // We need to resolve the position for every different index as the
number of cells might vary depending on it. | 914 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), maj
orAxisIndex); |
| 924 // This will happen when we have "span <custom-indent>", which has a
different resolution based on the position. | 915 emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.intege
rSpan(), minorAxisPositions.integerSpan()); |
| 925 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPosit
ionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirecti
on(), majorAxisIndex); | |
| 926 emptyGridArea = findEmptyGridAreaAtSpecifiedPositionsInsideGrid(grid
Item, autoPlacementMajorAxisDirection(), majorAxisPositions); | |
| 927 | 916 |
| 928 if (emptyGridArea) { | 917 if (emptyGridArea) { |
| 929 // Check that it fits in the minor axis direction, as we shouldn
't grow in that direction here (it was already managed in populateExplicitGridAn
dOrderIterator()). | 918 // Check that it fits in the minor axis direction, as we shouldn
't grow in that direction here (it was already managed in populateExplicitGridAn
dOrderIterator()). |
| 930 GridResolvedPosition minorAxisFinalPositionIndex = autoPlacement
MinorAxisDirection() == ForColumns ? emptyGridArea->columns.resolvedFinalPositio
n : emptyGridArea->rows.resolvedFinalPosition; | 919 GridResolvedPosition minorAxisFinalPositionIndex = autoPlacement
MinorAxisDirection() == ForColumns ? emptyGridArea->columns.resolvedFinalPositio
n : emptyGridArea->rows.resolvedFinalPosition; |
| 931 const size_t endOfMinorAxis = autoPlacementMinorAxisDirection()
== ForColumns ? gridColumnCount() : gridRowCount(); | 920 const size_t endOfMinorAxis = autoPlacementMinorAxisDirection()
== ForColumns ? gridColumnCount() : gridRowCount(); |
| 932 if (minorAxisFinalPositionIndex.toInt() < endOfMinorAxis) | 921 if (minorAxisFinalPositionIndex.toInt() < endOfMinorAxis) |
| 933 break; | 922 break; |
| 934 | 923 |
| 935 // Discard empty grid area as it does not fit in the minor axis
direction. | 924 // Discard empty grid area as it does not fit in the minor axis
direction. |
| 936 // We don't need to create a new empty grid area yet as we might
find a valid one in the next iteration. | 925 // We don't need to create a new empty grid area yet as we might
find a valid one in the next iteration. |
| 937 emptyGridArea = nullptr; | 926 emptyGridArea = nullptr; |
| 938 } | 927 } |
| 939 } | 928 } |
| 940 | 929 |
| 941 if (!emptyGridArea) { | 930 if (!emptyGridArea) |
| 942 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPosit
ionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMinorAxisDirecti
on(), GridResolvedPosition(0)); | |
| 943 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g
ridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); | 931 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g
ridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); |
| 944 } | |
| 945 } | 932 } |
| 946 | 933 |
| 947 insertItemIntoGrid(gridItem, *emptyGridArea); | 934 insertItemIntoGrid(gridItem, *emptyGridArea); |
| 948 } | 935 } |
| 949 | 936 |
| 950 GridTrackSizingDirection RenderGrid::autoPlacementMajorAxisDirection() const | 937 GridTrackSizingDirection RenderGrid::autoPlacementMajorAxisDirection() const |
| 951 { | 938 { |
| 952 GridAutoFlow flow = style()->gridAutoFlow(); | 939 GridAutoFlow flow = style()->gridAutoFlow(); |
| 953 ASSERT(flow != AutoFlowNone); | 940 ASSERT(flow != AutoFlowNone); |
| 954 return (flow == AutoFlowColumn) ? ForColumns : ForRows; | 941 return (flow == AutoFlowColumn) ? ForColumns : ForRows; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 if (isOutOfFlowPositioned()) | 1249 if (isOutOfFlowPositioned()) |
| 1263 return "RenderGrid (positioned)"; | 1250 return "RenderGrid (positioned)"; |
| 1264 if (isAnonymous()) | 1251 if (isAnonymous()) |
| 1265 return "RenderGrid (generated)"; | 1252 return "RenderGrid (generated)"; |
| 1266 if (isRelPositioned()) | 1253 if (isRelPositioned()) |
| 1267 return "RenderGrid (relative positioned)"; | 1254 return "RenderGrid (relative positioned)"; |
| 1268 return "RenderGrid"; | 1255 return "RenderGrid"; |
| 1269 } | 1256 } |
| 1270 | 1257 |
| 1271 } // namespace WebCore | 1258 } // namespace WebCore |
| OLD | NEW |