Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutGrid.cpp

Issue 1465153004: [css-grid] Avoid duplicated calls to resolution code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698