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 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 } | 1098 } |
1099 | 1099 |
1100 if (maximumColumnSize > gridColumnCount()) { | 1100 if (maximumColumnSize > gridColumnCount()) { |
1101 for (size_t row = 0; row < gridRowCount(); ++row) | 1101 for (size_t row = 0; row < gridRowCount(); ++row) |
1102 m_grid[row].grow(maximumColumnSize); | 1102 m_grid[row].grow(maximumColumnSize); |
1103 } | 1103 } |
1104 } | 1104 } |
1105 | 1105 |
1106 void LayoutGrid::insertItemIntoGrid(LayoutBox& child, const GridCoordinate& coor
dinate) | 1106 void LayoutGrid::insertItemIntoGrid(LayoutBox& child, const GridCoordinate& coor
dinate) |
1107 { | 1107 { |
| 1108 RELEASE_ASSERT(coordinate.rows.isDefinite() && coordinate.columns.isDefinite
()); |
1108 ensureGridSize(coordinate.rows.resolvedFinalPosition().toInt(), coordinate.c
olumns.resolvedFinalPosition().toInt()); | 1109 ensureGridSize(coordinate.rows.resolvedFinalPosition().toInt(), coordinate.c
olumns.resolvedFinalPosition().toInt()); |
1109 | 1110 |
1110 for (GridSpan::iterator row = coordinate.rows.begin(); row != coordinate.row
s.end(); ++row) { | 1111 for (GridSpan::iterator row = coordinate.rows.begin(); row != coordinate.row
s.end(); ++row) { |
1111 for (GridSpan::iterator column = coordinate.columns.begin(); column != c
oordinate.columns.end(); ++column) | 1112 for (GridSpan::iterator column = coordinate.columns.begin(); column != c
oordinate.columns.end(); ++column) |
1112 m_grid[row.toInt()][column.toInt()].append(&child); | 1113 m_grid[row.toInt()][column.toInt()].append(&child); |
1113 } | 1114 } |
1114 | |
1115 RELEASE_ASSERT(!m_gridItemCoordinate.contains(&child)); | |
1116 m_gridItemCoordinate.set(&child, coordinate); | |
1117 } | 1115 } |
1118 | 1116 |
1119 void LayoutGrid::placeItemsOnGrid() | 1117 void LayoutGrid::placeItemsOnGrid() |
1120 { | 1118 { |
1121 if (!m_gridIsDirty) | 1119 if (!m_gridIsDirty) |
1122 return; | 1120 return; |
1123 | 1121 |
1124 ASSERT(m_gridItemCoordinate.isEmpty()); | 1122 ASSERT(m_gridItemCoordinate.isEmpty()); |
1125 | 1123 |
1126 populateExplicitGridAndOrderIterator(); | 1124 populateExplicitGridAndOrderIterator(); |
1127 | 1125 |
1128 // We clear the dirty bit here as the grid sizes have been updated. | 1126 // We clear the dirty bit here as the grid sizes have been updated. |
1129 m_gridIsDirty = false; | 1127 m_gridIsDirty = false; |
1130 | 1128 |
1131 Vector<LayoutBox*> autoMajorAxisAutoGridItems; | 1129 Vector<LayoutBox*> autoMajorAxisAutoGridItems; |
1132 Vector<LayoutBox*> specifiedMajorAxisAutoGridItems; | 1130 Vector<LayoutBox*> specifiedMajorAxisAutoGridItems; |
1133 for (LayoutBox* child = m_orderIterator.first(); child; child = m_orderItera
tor.next()) { | 1131 for (LayoutBox* child = m_orderIterator.first(); child; child = m_orderItera
tor.next()) { |
1134 if (child->isOutOfFlowPositioned()) | 1132 if (child->isOutOfFlowPositioned()) |
1135 continue; | 1133 continue; |
1136 | 1134 |
1137 GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromSt
yle(*style(), *child, ForRows); | 1135 GridCoordinate coordinate = cachedGridCoordinate(*child); |
1138 GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFro
mStyle(*style(), *child, ForColumns); | 1136 if (!coordinate.rows.isDefinite() || !coordinate.columns.isDefinite()) { |
1139 if (!rowPositions.isDefinite() || !columnPositions.isDefinite()) { | 1137 GridSpan majorAxisPositions = (autoPlacementMajorAxisDirection() ==
ForColumns) ? coordinate.columns : coordinate.rows; |
1140 GridSpan majorAxisPositions = (autoPlacementMajorAxisDirection() ==
ForColumns) ? columnPositions : rowPositions; | |
1141 if (!majorAxisPositions.isDefinite()) | 1138 if (!majorAxisPositions.isDefinite()) |
1142 autoMajorAxisAutoGridItems.append(child); | 1139 autoMajorAxisAutoGridItems.append(child); |
1143 else | 1140 else |
1144 specifiedMajorAxisAutoGridItems.append(child); | 1141 specifiedMajorAxisAutoGridItems.append(child); |
1145 continue; | 1142 continue; |
1146 } | 1143 } |
1147 insertItemIntoGrid(*child, GridCoordinate(rowPositions, columnPositions)
); | 1144 insertItemIntoGrid(*child, coordinate); |
1148 } | 1145 } |
1149 | 1146 |
1150 ASSERT(gridRowCount() >= GridResolvedPosition::explicitGridRowCount(*style()
)); | 1147 ASSERT(gridRowCount() >= GridResolvedPosition::explicitGridRowCount(*style()
)); |
1151 ASSERT(gridColumnCount() >= GridResolvedPosition::explicitGridColumnCount(*s
tyle())); | 1148 ASSERT(gridColumnCount() >= GridResolvedPosition::explicitGridColumnCount(*s
tyle())); |
1152 | 1149 |
1153 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); | 1150 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); |
1154 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); | 1151 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); |
1155 | 1152 |
1156 m_grid.shrinkToFit(); | 1153 m_grid.shrinkToFit(); |
| 1154 |
| 1155 #if ENABLE(ASSERT) |
| 1156 for (LayoutBox* child = m_orderIterator.first(); child; child = m_orderItera
tor.next()) { |
| 1157 if (child->isOutOfFlowPositioned()) |
| 1158 continue; |
| 1159 |
| 1160 GridCoordinate coordinate = cachedGridCoordinate(*child); |
| 1161 ASSERT(coordinate.rows.isDefinite() && coordinate.columns.isDefinite()); |
| 1162 } |
| 1163 #endif |
1157 } | 1164 } |
1158 | 1165 |
1159 void LayoutGrid::populateExplicitGridAndOrderIterator() | 1166 void LayoutGrid::populateExplicitGridAndOrderIterator() |
1160 { | 1167 { |
1161 OrderIteratorPopulator populator(m_orderIterator); | 1168 OrderIteratorPopulator populator(m_orderIterator); |
1162 | 1169 |
1163 size_t maximumRowIndex = std::max<size_t>(1, GridResolvedPosition::explicitG
ridRowCount(*style())); | 1170 size_t maximumRowIndex = std::max<size_t>(1, GridResolvedPosition::explicitG
ridRowCount(*style())); |
1164 size_t maximumColumnIndex = std::max<size_t>(1, GridResolvedPosition::explic
itGridColumnCount(*style())); | 1171 size_t maximumColumnIndex = std::max<size_t>(1, GridResolvedPosition::explic
itGridColumnCount(*style())); |
1165 | 1172 |
1166 ASSERT(m_gridItemsIndexesMap.isEmpty()); | 1173 ASSERT(m_gridItemsIndexesMap.isEmpty()); |
1167 size_t childIndex = 0; | 1174 size_t childIndex = 0; |
1168 for (LayoutBox* child = firstChildBox(); child; child = child->nextInFlowSib
lingBox()) { | 1175 for (LayoutBox* child = firstChildBox(); child; child = child->nextInFlowSib
lingBox()) { |
1169 if (child->isOutOfFlowPositioned()) | 1176 if (child->isOutOfFlowPositioned()) |
1170 continue; | 1177 continue; |
1171 | 1178 |
1172 populator.collectChild(child); | 1179 populator.collectChild(child); |
1173 m_gridItemsIndexesMap.set(child, childIndex++); | 1180 m_gridItemsIndexesMap.set(child, childIndex++); |
1174 | 1181 |
1175 // This function bypasses the cache (cachedGridCoordinate()) as it is us
ed to build it. | 1182 // This function bypasses the cache (cachedGridCoordinate()) as it is us
ed to build it. |
1176 GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromSt
yle(*style(), *child, ForRows); | 1183 GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromSt
yle(*style(), *child, ForRows); |
1177 GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFro
mStyle(*style(), *child, ForColumns); | 1184 GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFro
mStyle(*style(), *child, ForColumns); |
| 1185 m_gridItemCoordinate.set(child, GridCoordinate(rowPositions, columnPosit
ions)); |
1178 | 1186 |
1179 // |positions| is 0 if we need to run the auto-placement algorithm. | 1187 // |positions| is 0 if we need to run the auto-placement algorithm. |
1180 if (rowPositions.isDefinite()) { | 1188 if (rowPositions.isDefinite()) { |
1181 maximumRowIndex = std::max<size_t>(maximumRowIndex, rowPositions.res
olvedFinalPosition().toInt()); | 1189 maximumRowIndex = std::max<size_t>(maximumRowIndex, rowPositions.res
olvedFinalPosition().toInt()); |
1182 } else { | 1190 } else { |
1183 // Grow the grid for items with a definite row span, getting the lar
gest such span. | 1191 // Grow the grid for items with a definite row span, getting the lar
gest such span. |
1184 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromA
utoPlacementPosition(*style(), *child, ForRows, GridResolvedPosition(0)); | 1192 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromA
utoPlacementPosition(*style(), *child, ForRows, GridResolvedPosition(0)); |
1185 maximumRowIndex = std::max<size_t>(maximumRowIndex, positions.resolv
edFinalPosition().toInt()); | 1193 maximumRowIndex = std::max<size_t>(maximumRowIndex, positions.resolv
edFinalPosition().toInt()); |
1186 } | 1194 } |
1187 | 1195 |
(...skipping 23 matching lines...) Expand all Loading... |
1211 { | 1219 { |
1212 bool isForColumns = autoPlacementMajorAxisDirection() == ForColumns; | 1220 bool isForColumns = autoPlacementMajorAxisDirection() == ForColumns; |
1213 bool isGridAutoFlowDense = style()->isGridAutoFlowAlgorithmDense(); | 1221 bool isGridAutoFlowDense = style()->isGridAutoFlowAlgorithmDense(); |
1214 | 1222 |
1215 // Mapping between the major axis tracks (rows or columns) and the last auto
-placed item's position inserted on | 1223 // Mapping between the major axis tracks (rows or columns) and the last auto
-placed item's position inserted on |
1216 // that track. This is needed to implement "sparse" packing for items locked
to a given track. | 1224 // that track. This is needed to implement "sparse" packing for items locked
to a given track. |
1217 // See http://dev.w3.org/csswg/css-grid/#auto-placement-algo | 1225 // See http://dev.w3.org/csswg/css-grid/#auto-placement-algo |
1218 HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZe
roKeyHashTraits<unsigned>> minorAxisCursors; | 1226 HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZe
roKeyHashTraits<unsigned>> minorAxisCursors; |
1219 | 1227 |
1220 for (const auto& autoGridItem : autoGridItems) { | 1228 for (const auto& autoGridItem : autoGridItems) { |
1221 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositions
FromStyle(*style(), *autoGridItem, autoPlacementMajorAxisDirection()); | 1229 GridSpan majorAxisPositions = cachedGridSpan(*autoGridItem, autoPlacemen
tMajorAxisDirection()); |
| 1230 ASSERT(majorAxisPositions.isDefinite()); |
| 1231 ASSERT(!cachedGridSpan(*autoGridItem, autoPlacementMinorAxisDirection())
.isDefinite()); |
1222 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositions
FromAutoPlacementPosition(*style(), *autoGridItem, autoPlacementMinorAxisDirecti
on(), GridResolvedPosition(0)); | 1232 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositions
FromAutoPlacementPosition(*style(), *autoGridItem, autoPlacementMinorAxisDirecti
on(), GridResolvedPosition(0)); |
1223 unsigned majorAxisInitialPosition = majorAxisPositions.resolvedInitialPo
sition().toInt(); | 1233 unsigned majorAxisInitialPosition = majorAxisPositions.resolvedInitialPo
sition().toInt(); |
1224 | 1234 |
1225 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx
isPositions.resolvedInitialPosition().toInt(), isGridAutoFlowDense ? 0 : minorAx
isCursors.get(majorAxisInitialPosition)); | 1235 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx
isPositions.resolvedInitialPosition().toInt(), isGridAutoFlowDense ? 0 : minorAx
isCursors.get(majorAxisInitialPosition)); |
1226 OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorA
xisPositions.integerSpan(), minorAxisPositions.integerSpan()); | 1236 OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorA
xisPositions.integerSpan(), minorAxisPositions.integerSpan()); |
1227 if (!emptyGridArea) | 1237 if (!emptyGridArea) |
1228 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*
autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions); | 1238 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*
autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions); |
| 1239 |
| 1240 m_gridItemCoordinate.set(autoGridItem, *emptyGridArea); |
1229 insertItemIntoGrid(*autoGridItem, *emptyGridArea); | 1241 insertItemIntoGrid(*autoGridItem, *emptyGridArea); |
1230 | 1242 |
1231 if (!isGridAutoFlowDense) | 1243 if (!isGridAutoFlowDense) |
1232 minorAxisCursors.set(majorAxisInitialPosition, isForColumns ? emptyG
ridArea->rows.resolvedInitialPosition().toInt() : emptyGridArea->columns.resolve
dInitialPosition().toInt()); | 1244 minorAxisCursors.set(majorAxisInitialPosition, isForColumns ? emptyG
ridArea->rows.resolvedInitialPosition().toInt() : emptyGridArea->columns.resolve
dInitialPosition().toInt()); |
1233 } | 1245 } |
1234 } | 1246 } |
1235 | 1247 |
1236 void LayoutGrid::placeAutoMajorAxisItemsOnGrid(const Vector<LayoutBox*>& autoGri
dItems) | 1248 void LayoutGrid::placeAutoMajorAxisItemsOnGrid(const Vector<LayoutBox*>& autoGri
dItems) |
1237 { | 1249 { |
1238 std::pair<size_t, size_t> autoPlacementCursor = std::make_pair(0, 0); | 1250 std::pair<size_t, size_t> autoPlacementCursor = std::make_pair(0, 0); |
1239 bool isGridAutoFlowDense = style()->isGridAutoFlowAlgorithmDense(); | 1251 bool isGridAutoFlowDense = style()->isGridAutoFlowAlgorithmDense(); |
1240 | 1252 |
1241 for (const auto& autoGridItem : autoGridItems) { | 1253 for (const auto& autoGridItem : autoGridItems) { |
1242 placeAutoMajorAxisItemOnGrid(*autoGridItem, autoPlacementCursor); | 1254 placeAutoMajorAxisItemOnGrid(*autoGridItem, autoPlacementCursor); |
1243 | 1255 |
1244 // If grid-auto-flow is dense, reset auto-placement cursor. | 1256 // If grid-auto-flow is dense, reset auto-placement cursor. |
1245 if (isGridAutoFlowDense) { | 1257 if (isGridAutoFlowDense) { |
1246 autoPlacementCursor.first = 0; | 1258 autoPlacementCursor.first = 0; |
1247 autoPlacementCursor.second = 0; | 1259 autoPlacementCursor.second = 0; |
1248 } | 1260 } |
1249 } | 1261 } |
1250 } | 1262 } |
1251 | 1263 |
1252 void LayoutGrid::placeAutoMajorAxisItemOnGrid(LayoutBox& gridItem, std::pair<siz
e_t, size_t>& autoPlacementCursor) | 1264 void LayoutGrid::placeAutoMajorAxisItemOnGrid(LayoutBox& gridItem, std::pair<siz
e_t, size_t>& autoPlacementCursor) |
1253 { | 1265 { |
1254 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFrom
Style(*style(), gridItem, autoPlacementMinorAxisDirection()); | 1266 GridSpan minorAxisPositions = cachedGridSpan(gridItem, autoPlacementMinorAxi
sDirection()); |
1255 ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), gridIt
em, autoPlacementMajorAxisDirection()).isDefinite()); | 1267 ASSERT(!cachedGridSpan(gridItem, autoPlacementMajorAxisDirection()).isDefini
te()); |
1256 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFrom
AutoPlacementPosition(*style(), gridItem, autoPlacementMajorAxisDirection(), Gri
dResolvedPosition(0)); | 1268 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFrom
AutoPlacementPosition(*style(), gridItem, autoPlacementMajorAxisDirection(), Gri
dResolvedPosition(0)); |
1257 | 1269 |
1258 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColum
ns) ? gridColumnCount() : gridRowCount(); | 1270 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColum
ns) ? gridColumnCount() : gridRowCount(); |
1259 size_t majorAxisAutoPlacementCursor = autoPlacementMajorAxisDirection() == F
orColumns ? autoPlacementCursor.second : autoPlacementCursor.first; | 1271 size_t majorAxisAutoPlacementCursor = autoPlacementMajorAxisDirection() == F
orColumns ? autoPlacementCursor.second : autoPlacementCursor.first; |
1260 size_t minorAxisAutoPlacementCursor = autoPlacementMajorAxisDirection() == F
orColumns ? autoPlacementCursor.first : autoPlacementCursor.second; | 1272 size_t minorAxisAutoPlacementCursor = autoPlacementMajorAxisDirection() == F
orColumns ? autoPlacementCursor.first : autoPlacementCursor.second; |
1261 | 1273 |
1262 OwnPtr<GridCoordinate> emptyGridArea; | 1274 OwnPtr<GridCoordinate> emptyGridArea; |
1263 if (minorAxisPositions.isDefinite()) { | 1275 if (minorAxisPositions.isDefinite()) { |
1264 // Move to the next track in major axis if initial position in minor axi
s is before auto-placement cursor. | 1276 // Move to the next track in major axis if initial position in minor axi
s is before auto-placement cursor. |
1265 if (minorAxisPositions.resolvedInitialPosition().toInt() < minorAxisAuto
PlacementCursor) | 1277 if (minorAxisPositions.resolvedInitialPosition().toInt() < minorAxisAuto
PlacementCursor) |
(...skipping 26 matching lines...) Expand all Loading... |
1292 } | 1304 } |
1293 | 1305 |
1294 // As we're moving to the next track in the major axis we should res
et the auto-placement cursor in the minor axis. | 1306 // As we're moving to the next track in the major axis we should res
et the auto-placement cursor in the minor axis. |
1295 minorAxisAutoPlacementCursor = 0; | 1307 minorAxisAutoPlacementCursor = 0; |
1296 } | 1308 } |
1297 | 1309 |
1298 if (!emptyGridArea) | 1310 if (!emptyGridArea) |
1299 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g
ridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); | 1311 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g
ridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); |
1300 } | 1312 } |
1301 | 1313 |
| 1314 m_gridItemCoordinate.set(&gridItem, *emptyGridArea); |
1302 insertItemIntoGrid(gridItem, *emptyGridArea); | 1315 insertItemIntoGrid(gridItem, *emptyGridArea); |
1303 // Move auto-placement cursor to the new position. | 1316 // Move auto-placement cursor to the new position. |
1304 autoPlacementCursor.first = emptyGridArea->rows.resolvedInitialPosition().to
Int(); | 1317 autoPlacementCursor.first = emptyGridArea->rows.resolvedInitialPosition().to
Int(); |
1305 autoPlacementCursor.second = emptyGridArea->columns.resolvedInitialPosition(
).toInt(); | 1318 autoPlacementCursor.second = emptyGridArea->columns.resolvedInitialPosition(
).toInt(); |
1306 } | 1319 } |
1307 | 1320 |
1308 GridTrackSizingDirection LayoutGrid::autoPlacementMajorAxisDirection() const | 1321 GridTrackSizingDirection LayoutGrid::autoPlacementMajorAxisDirection() const |
1309 { | 1322 { |
1310 return style()->isGridAutoFlowDirectionColumn() ? ForColumns : ForRows; | 1323 return style()->isGridAutoFlowDirectionColumn() ? ForColumns : ForRows; |
1311 } | 1324 } |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2044 | 2057 |
2045 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 2058 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
2046 } | 2059 } |
2047 | 2060 |
2048 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) const | 2061 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) const |
2049 { | 2062 { |
2050 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 2063 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
2051 } | 2064 } |
2052 | 2065 |
2053 } // namespace blink | 2066 } // namespace blink |
OLD | NEW |