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

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

Issue 1220043002: [CSS Grid Layout] Removing Content Alignment logic from track sizing alg (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Applied new suggested changes. Created 5 years, 5 months 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 | « Source/core/layout/LayoutGrid.h ('k') | 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 void ensureGrowthLimitIsBiggerThanBaseSize() 112 void ensureGrowthLimitIsBiggerThanBaseSize()
113 { 113 {
114 if (m_growthLimit != infinity && m_growthLimit < m_baseSize) 114 if (m_growthLimit != infinity && m_growthLimit < m_baseSize)
115 m_growthLimit = m_baseSize; 115 m_growthLimit = m_baseSize;
116 } 116 }
117 117
118 LayoutUnit m_baseSize; 118 LayoutUnit m_baseSize;
119 LayoutUnit m_growthLimit; 119 LayoutUnit m_growthLimit;
120 }; 120 };
121 121
122 struct ContentAlignmentData {
123 STACK_ALLOCATED();
124 public:
125 ContentAlignmentData() {};
126 ContentAlignmentData(LayoutUnit position, LayoutUnit distribution)
127 : positionOffset(position)
128 , distributionOffset(distribution)
129 {
130 }
131
132 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; }
133
134 LayoutUnit positionOffset = -1;
135 LayoutUnit distributionOffset = -1;
136 };
137
122 struct GridTrackForNormalization { 138 struct GridTrackForNormalization {
123 GridTrackForNormalization(const GridTrack& track, double flex) 139 GridTrackForNormalization(const GridTrack& track, double flex)
124 : m_track(&track) 140 : m_track(&track)
125 , m_flex(flex) 141 , m_flex(flex)
126 , m_normalizedFlexValue(track.baseSize() / flex) 142 , m_normalizedFlexValue(track.baseSize() / flex)
127 { 143 {
128 } 144 }
129 145
130 // Required by std::sort. 146 // Required by std::sort.
131 GridTrackForNormalization& operator=(const GridTrackForNormalization& o) 147 GridTrackForNormalization& operator=(const GridTrackForNormalization& o)
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 252 }
237 253
238 Vector<GridTrack> columnTracks; 254 Vector<GridTrack> columnTracks;
239 Vector<GridTrack> rowTracks; 255 Vector<GridTrack> rowTracks;
240 Vector<size_t> contentSizedTracksIndex; 256 Vector<size_t> contentSizedTracksIndex;
241 257
242 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free. 258 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free.
243 Vector<GridTrack*> filteredTracks; 259 Vector<GridTrack*> filteredTracks;
244 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; 260 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan;
245 Vector<GridTrack*> growBeyondGrowthLimitsTracks; 261 Vector<GridTrack*> growBeyondGrowthLimitsTracks;
246
247 LayoutUnit rowsPositionOffset;
248 LayoutUnit rowsDistributionOffset;
249 LayoutUnit columnsPositionOffset;
250 LayoutUnit columnsDistributionOffset;
251 }; 262 };
252 263
253 struct GridItemsSpanGroupRange { 264 struct GridItemsSpanGroupRange {
254 Vector<GridItemWithSpan>::iterator rangeStart; 265 Vector<GridItemWithSpan>::iterator rangeStart;
255 Vector<GridItemWithSpan>::iterator rangeEnd; 266 Vector<GridItemWithSpan>::iterator rangeEnd;
256 }; 267 };
257 268
258 LayoutGrid::LayoutGrid(Element* element) 269 LayoutGrid::LayoutGrid(Element* element)
259 : LayoutBlock(element) 270 : LayoutBlock(element)
260 , m_gridIsDirty(true) 271 , m_gridIsDirty(true)
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 ASSERT(!track.growthLimitIsInfinite()); 443 ASSERT(!track.growthLimitIsInfinite());
433 freeSpace -= track.baseSize(); 444 freeSpace -= track.baseSize();
434 } 445 }
435 446
436 const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->lo gicalHeight().isAuto() : gridElementIsShrinkToFit(); 447 const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->lo gicalHeight().isAuto() : gridElementIsShrinkToFit();
437 448
438 if (!hasUndefinedRemainingSpace && freeSpace <= 0) 449 if (!hasUndefinedRemainingSpace && freeSpace <= 0)
439 return; 450 return;
440 451
441 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro wthLimit value until freeSpace is exhausted. 452 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro wthLimit value until freeSpace is exhausted.
442 // Any 'auto-sized' (content based) track will be 'stretched' over their Max Breadth if required
443 // and there is space available, except if there are flexible track, which w ill occupy the whole
444 // available space.
445 bool needToStretch = flexibleSizedTracksIndex.isEmpty() && !sizingData.conte ntSizedTracksIndex.isEmpty()
446 && ((direction == ForColumns && style()->justifyContentDistribution() == ContentDistributionStretch)
447 || (direction == ForRows && style()->alignContentDistribution() == C ontentDistributionStretch));
448 const size_t tracksSize = tracks.size(); 453 const size_t tracksSize = tracks.size();
449 if (!hasUndefinedRemainingSpace) { 454 if (!hasUndefinedRemainingSpace) {
450 Vector<GridTrack*> tracksForDistribution(tracksSize); 455 Vector<GridTrack*> tracksForDistribution(tracksSize);
451 for (size_t i = 0; i < tracksSize; ++i) { 456 for (size_t i = 0; i < tracksSize; ++i) {
452 tracksForDistribution[i] = tracks.data() + i; 457 tracksForDistribution[i] = tracks.data() + i;
453 tracksForDistribution[i]->m_plannedIncrease = 0; 458 tracksForDistribution[i]->m_plannedIncrease = 0;
454 } 459 }
455 460
456 Vector<GridTrack*> tracksToStretch(sizingData.contentSizedTracksIndex.si ze()); 461 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr, sizingData, freeSpace);
457 if (needToStretch) {
458 unsigned i = 0;
459 for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
460 tracksToStretch[i++] = tracks.data() + trackIndex;
461 }
462 }
463
464 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, needToStr etch ? &tracksToStretch : nullptr, sizingData, freeSpace);
465 462
466 for (auto* track : tracksForDistribution) 463 for (auto* track : tracksForDistribution)
467 track->growBaseSize(track->m_plannedIncrease); 464 track->growBaseSize(track->m_plannedIncrease);
468 } else { 465 } else {
469 for (auto& track : tracks) 466 for (auto& track : tracks)
470 track.setBaseSize(track.growthLimit()); 467 track.setBaseSize(track.growthLimit());
471 } 468 }
472 469
473 if (flexibleSizedTracksIndex.isEmpty()) 470 if (flexibleSizedTracksIndex.isEmpty())
474 return; 471 return;
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 // the grid and its children are correctly laid out according to the new sty le rules. 1223 // the grid and its children are correctly laid out according to the new sty le rules.
1227 setNeedsLayout(LayoutInvalidationReason::GridChanged); 1224 setNeedsLayout(LayoutInvalidationReason::GridChanged);
1228 1225
1229 m_grid.resize(0); 1226 m_grid.resize(0);
1230 m_gridItemCoordinate.clear(); 1227 m_gridItemCoordinate.clear();
1231 m_gridItemsOverflowingGridArea.resize(0); 1228 m_gridItemsOverflowingGridArea.resize(0);
1232 m_gridItemsIndexesMap.clear(); 1229 m_gridItemsIndexesMap.clear();
1233 m_gridIsDirty = true; 1230 m_gridIsDirty = true;
1234 } 1231 }
1235 1232
1233 void LayoutGrid::applyStretchAlignmentToTracksIfNeeded(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit availableSpace)
1234 {
1235 if (availableSpace <= 0
1236 || (direction == ForColumns && styleRef().justifyContentDistribution() ! = ContentDistributionStretch)
1237 || (direction == ForRows && styleRef().alignContentDistribution() != Con tentDistributionStretch))
1238 return;
1239
1240 // We consider auto-sized tracks as content-sized (min-content, max-content, auto).
1241 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra cks : sizingData.rowTracks;
1242 Vector<unsigned> autoSizedTracksIndex;
1243 for (unsigned i = 0; i < tracks.size(); ++i) {
1244 const GridTrackSize& trackSize = gridTrackSize(direction, i);
1245 // If there is some flexible-sized track, they should have exhausted ava ilable space during sizing algorithm.
1246 ASSERT(!trackSize.maxTrackBreadth().isFlex());
1247 if (trackSize.isContentSized())
1248 autoSizedTracksIndex.append(i);
1249 }
1250
1251 unsigned numberOfAutoSizedTracks = autoSizedTracksIndex.size();
1252 if (numberOfAutoSizedTracks < 1)
1253 return;
1254
1255 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks;
1256 for (const auto& trackIndex : autoSizedTracksIndex) {
1257 GridTrack* track = tracks.data() + trackIndex;
1258 // FIXME: Respecting the constraints imposed by max-height/max-width.
1259 LayoutUnit baseSize = track->baseSize() + sizeToIncrease;
1260 track->setBaseSize(baseSize);
1261 }
1262 }
1263
1236 void LayoutGrid::layoutGridItems() 1264 void LayoutGrid::layoutGridItems()
1237 { 1265 {
1238 placeItemsOnGrid(); 1266 placeItemsOnGrid();
1239 1267
1240 LayoutUnit availableSpaceForColumns = availableLogicalWidth(); 1268 LayoutUnit availableSpaceForColumns = availableLogicalWidth();
1241 LayoutUnit availableSpaceForRows = availableLogicalHeight(IncludeMarginBorde rPadding); 1269 LayoutUnit availableSpaceForRows = availableLogicalHeight(IncludeMarginBorde rPadding);
1242 GridSizingData sizingData(gridColumnCount(), gridRowCount()); 1270 GridSizingData sizingData(gridColumnCount(), gridRowCount());
1243 computeUsedBreadthOfGridTracks(ForColumns, sizingData, availableSpaceForColu mns); 1271 computeUsedBreadthOfGridTracks(ForColumns, sizingData, availableSpaceForColu mns);
1244 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks )); 1272 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks ));
1245 computeUsedBreadthOfGridTracks(ForRows, sizingData, availableSpaceForRows); 1273 computeUsedBreadthOfGridTracks(ForRows, sizingData, availableSpaceForRows);
1246 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks)); 1274 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks));
1247 1275
1248 computeContentPositionAndDistributionColumnOffset(availableSpaceForColumns, sizingData); 1276 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData, availableSpace ForColumns);
1249 computeContentPositionAndDistributionRowOffset(availableSpaceForRows, sizing Data); 1277 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData, availableSpaceFor Rows);
1250 1278
1251 populateGridPositions(sizingData); 1279 populateGridPositions(sizingData, availableSpaceForColumns, availableSpaceFo rRows);
1252 m_gridItemsOverflowingGridArea.resize(0); 1280 m_gridItemsOverflowingGridArea.resize(0);
1253 1281
1254 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) { 1282 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) {
1255 if (child->isOutOfFlowPositioned()) { 1283 if (child->isOutOfFlowPositioned()) {
1256 child->containingBlock()->insertPositionedObject(child); 1284 child->containingBlock()->insertPositionedObject(child);
1257 continue; 1285 continue;
1258 } 1286 }
1259 1287
1260 // Because the grid area cannot be styled, we don't need to adjust 1288 // Because the grid area cannot be styled, we don't need to adjust
1261 // the grid breadth to account for 'box-sizing'. 1289 // the grid breadth to account for 'box-sizing'.
1262 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit(); 1290 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit();
1263 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit(); 1291 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit();
1264 1292
1265 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChild(*child, ForColumns, sizingData.columnTracks); 1293 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChildIncludingAlignmentOffsets(*child, ForColumns, sizingData);
1266 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChild(*child, ForRows, sizingData.rowTracks); 1294 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChildIncludingAlignmentOffsets(*child, ForRows, sizingData);
1267 1295
1268 SubtreeLayoutScope layoutScope(*child); 1296 SubtreeLayoutScope layoutScope(*child);
1269 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight())) 1297 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight()))
1270 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged); 1298 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged);
1271 1299
1272 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); 1300 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth);
1273 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); 1301 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight);
1274 1302
1275 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded 1303 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded
1276 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly 1304 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 GridCoordinate LayoutGrid::cachedGridCoordinate(const LayoutBox& gridItem) const 1419 GridCoordinate LayoutGrid::cachedGridCoordinate(const LayoutBox& gridItem) const
1392 { 1420 {
1393 ASSERT(m_gridItemCoordinate.contains(&gridItem)); 1421 ASSERT(m_gridItemCoordinate.contains(&gridItem));
1394 return m_gridItemCoordinate.get(&gridItem); 1422 return m_gridItemCoordinate.get(&gridItem);
1395 } 1423 }
1396 1424
1397 LayoutUnit LayoutGrid::gridAreaBreadthForChild(const LayoutBox& child, GridTrack SizingDirection direction, const Vector<GridTrack>& tracks) const 1425 LayoutUnit LayoutGrid::gridAreaBreadthForChild(const LayoutBox& child, GridTrack SizingDirection direction, const Vector<GridTrack>& tracks) const
1398 { 1426 {
1399 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1427 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1400 const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coor dinate.rows; 1428 const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coor dinate.rows;
1401 const Vector<LayoutUnit>& trackPositions = (direction == ForColumns) ? m_col umnPositions : m_rowPositions;
1402 if (span.resolvedFinalPosition.toInt() < trackPositions.size()) {
1403 LayoutUnit startOftrack = trackPositions[span.resolvedInitialPosition.to Int()];
1404 LayoutUnit endOfTrack = trackPositions[span.resolvedFinalPosition.toInt( )];
1405 return endOfTrack - startOftrack + tracks[span.resolvedFinalPosition.toI nt()].baseSize();
1406 }
1407 LayoutUnit gridAreaBreadth = 0; 1429 LayoutUnit gridAreaBreadth = 0;
1408 for (GridSpan::iterator trackPosition = span.begin(); trackPosition != span. end(); ++trackPosition) 1430 for (GridSpan::iterator trackPosition = span.begin(); trackPosition != span. end(); ++trackPosition)
1409 gridAreaBreadth += tracks[trackPosition.toInt()].baseSize(); 1431 gridAreaBreadth += tracks[trackPosition.toInt()].baseSize();
1410
1411 return gridAreaBreadth; 1432 return gridAreaBreadth;
1412 } 1433 }
1413 1434
1414 void LayoutGrid::populateGridPositions(const GridSizingData& sizingData) 1435 LayoutUnit LayoutGrid::gridAreaBreadthForChildIncludingAlignmentOffsets(const La youtBox& child, GridTrackSizingDirection direction, const GridSizingData& sizing Data) const
1415 { 1436 {
1416 unsigned numberOfColumnTracks = sizingData.columnTracks.size(); 1437 // We need the cached value when available because Content Distribution alig nment properties
1417 unsigned numberOfRowTracks = sizingData.rowTracks.size(); 1438 // may have some influence in the final grid area breadth.
1439 const Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.col umnTracks : sizingData.rowTracks;
1440 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1441 const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coor dinate.rows;
1442 const Vector<LayoutUnit>& linePositions = (direction == ForColumns) ? m_colu mnPositions : m_rowPositions;
1443 LayoutUnit initialTrackPosition = linePositions[span.resolvedInitialPosition .toInt()];
1444 LayoutUnit finalTrackPosition = linePositions[span.resolvedFinalPosition.toI nt()];
1445 // Track Positions vector stores the 'start' grid line of each track, so w h ave to add last track's baseSize.
1446 return finalTrackPosition - initialTrackPosition + tracks[span.resolvedFinal Position.toInt()].baseSize();
1447 }
1418 1448
1419 m_columnPositions.resize(numberOfColumnTracks + 1); 1449 void LayoutGrid::populateGridPositions(GridSizingData& sizingData, LayoutUnit av ailableSpaceForColumns, LayoutUnit availableSpaceForRows)
1420 m_columnPositions[0] = borderAndPaddingStart() + sizingData.columnsPositionO ffset; 1450 {
1421 for (unsigned i = 0; i < numberOfColumnTracks; ++i) 1451 // Since we add alignment offsets, grid lines are not always adjacent. Hence we will have to
1422 m_columnPositions[i + 1] = m_columnPositions[i] + sizingData.columnsDist ributionOffset + sizingData.columnTracks[i].baseSize(); 1452 // assume from now on that we just store positions of the initial grid lines of each track,
1453 // except the last one, which is the only one considered as a final grid lin e of a track.
1454 // FIXME: This will affect the computed style value of grid tracks size, sin ce we are
1455 // using these positions to compute them.
1423 1456
1424 m_rowPositions.resize(numberOfRowTracks + 1); 1457 unsigned numberOfTracks = sizingData.columnTracks.size();
1425 m_rowPositions[0] = borderAndPaddingBefore() + sizingData.rowsPositionOffset ; 1458 unsigned numberOfLines = numberOfTracks + 1;
1426 for (unsigned i = 0; i < numberOfRowTracks; ++i) 1459 unsigned lastLine = numberOfLines - 1;
1427 m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowsDistributionO ffset + sizingData.rowTracks[i].baseSize(); 1460 unsigned nextToLastLine = numberOfLines - 2;
1461 ContentAlignmentData offset = computeContentPositionAndDistributionOffset(Fo rColumns, availableSpaceForColumns, numberOfTracks);
1462 m_columnPositions.resize(numberOfLines);
1463 m_columnPositions[0] = borderAndPaddingStart() + offset.positionOffset;
1464 for (unsigned i = 0; i < lastLine; ++i)
1465 m_columnPositions[i + 1] = m_columnPositions[i] + offset.distributionOff set + sizingData.columnTracks[i].baseSize();
1466 m_columnPositions[lastLine] = m_columnPositions[nextToLastLine] + sizingData .columnTracks[nextToLastLine].baseSize();
1467
1468 numberOfTracks = sizingData.rowTracks.size();
1469 numberOfLines = numberOfTracks + 1;
1470 lastLine = numberOfLines - 1;
1471 nextToLastLine = numberOfLines - 2;
1472 offset = computeContentPositionAndDistributionOffset(ForRows, availableSpace ForRows, numberOfTracks);
1473 m_rowPositions.resize(numberOfLines);
1474 m_rowPositions[0] = borderAndPaddingBefore() + offset.positionOffset;
1475 for (unsigned i = 0; i < lastLine; ++i)
1476 m_rowPositions[i + 1] = m_rowPositions[i] + offset.distributionOffset + sizingData.rowTracks[i].baseSize();
1477 m_rowPositions[lastLine] = m_rowPositions[nextToLastLine] + sizingData.rowTr acks[nextToLastLine].baseSize();
1428 } 1478 }
1429 1479
1430 static LayoutUnit computeOverflowAlignmentOffset(OverflowAlignment overflow, Lay outUnit trackBreadth, LayoutUnit childBreadth) 1480 static LayoutUnit computeOverflowAlignmentOffset(OverflowAlignment overflow, Lay outUnit trackBreadth, LayoutUnit childBreadth)
1431 { 1481 {
1432 LayoutUnit offset = trackBreadth - childBreadth; 1482 LayoutUnit offset = trackBreadth - childBreadth;
1433 switch (overflow) { 1483 switch (overflow) {
1434 case OverflowAlignmentSafe: 1484 case OverflowAlignmentSafe:
1435 // If overflow is 'safe', we have to make sure we don't overflow the 'st art' 1485 // If overflow is 'safe', we have to make sure we don't overflow the 'st art'
1436 // edge (potentially cause some data loss as the overflow is unreachable ). 1486 // edge (potentially cause some data loss as the overflow is unreachable ).
1437 return std::max<LayoutUnit>(0, offset); 1487 return std::max<LayoutUnit>(0, offset);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 // crbug.com/234191 1683 // crbug.com/234191
1634 return GridAxisStart; 1684 return GridAxisStart;
1635 case ItemPositionAuto: 1685 case ItemPositionAuto:
1636 break; 1686 break;
1637 } 1687 }
1638 1688
1639 ASSERT_NOT_REACHED(); 1689 ASSERT_NOT_REACHED();
1640 return GridAxisStart; 1690 return GridAxisStart;
1641 } 1691 }
1642 1692
1643 LayoutUnit LayoutGrid::rowPositionForChild(const LayoutBox& child) const 1693 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const
1644 { 1694 {
1645 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1695 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1646 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; 1696 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()];
1647 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 1697 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
1648 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 1698 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
1649 switch (axisPosition) { 1699 switch (axisPosition) {
1650 case GridAxisStart: 1700 case GridAxisStart:
1651 return startPosition; 1701 return startPosition;
1652 case GridAxisEnd: 1702 case GridAxisEnd:
1653 case GridAxisCenter: { 1703 case GridAxisCenter: {
1654 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; 1704 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()];
1655 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); 1705 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight());
1656 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); 1706 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2);
1657 } 1707 }
1658 } 1708 }
1659 1709
1660 ASSERT_NOT_REACHED(); 1710 ASSERT_NOT_REACHED();
1661 return 0; 1711 return 0;
1662 } 1712 }
1663 1713
1664 LayoutUnit LayoutGrid::columnPositionForChild(const LayoutBox& child) const 1714 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const
1665 { 1715 {
1666 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1716 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1667 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; 1717 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()];
1668 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 1718 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
1669 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 1719 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
1670 switch (axisPosition) { 1720 switch (axisPosition) {
1671 case GridAxisStart: 1721 case GridAxisStart:
1672 return startPosition; 1722 return startPosition;
1673 case GridAxisEnd: 1723 case GridAxisEnd:
1674 case GridAxisCenter: { 1724 case GridAxisCenter: {
(...skipping 30 matching lines...) Expand all
1705 { 1755 {
1706 return isLeftToRight ? LayoutUnit() : availableSpace; 1756 return isLeftToRight ? LayoutUnit() : availableSpace;
1707 } 1757 }
1708 1758
1709 static inline LayoutUnit offsetToEndEdge(bool isLeftToRight, LayoutUnit availabl eSpace) 1759 static inline LayoutUnit offsetToEndEdge(bool isLeftToRight, LayoutUnit availabl eSpace)
1710 { 1760 {
1711 return !isLeftToRight ? LayoutUnit() : availableSpace; 1761 return !isLeftToRight ? LayoutUnit() : availableSpace;
1712 } 1762 }
1713 1763
1714 1764
1715 static bool contentDistributionOffset(LayoutUnit availableFreeSpace, ContentPosi tion& fallbackPosition, ContentDistributionType distribution, unsigned numberOfG ridTracks, LayoutUnit& positionOffset, LayoutUnit& distributionOffset) 1765 static ContentAlignmentData contentDistributionOffset(LayoutUnit availableFreeSp ace, ContentPosition& fallbackPosition, ContentDistributionType distribution, un signed numberOfGridTracks)
1716 { 1766 {
1717 if (distribution != ContentDistributionDefault && fallbackPosition == Conten tPositionAuto) 1767 if (distribution != ContentDistributionDefault && fallbackPosition == Conten tPositionAuto)
1718 fallbackPosition = resolveContentDistributionFallback(distribution); 1768 fallbackPosition = resolveContentDistributionFallback(distribution);
1719 1769
1720 if (availableFreeSpace <= 0) 1770 if (availableFreeSpace <= 0)
1721 return false; 1771 return {};
1722 1772
1773 LayoutUnit distributionOffset;
1723 switch (distribution) { 1774 switch (distribution) {
1724 case ContentDistributionSpaceBetween: 1775 case ContentDistributionSpaceBetween:
1725 if (numberOfGridTracks < 2) 1776 if (numberOfGridTracks < 2)
1726 return false; 1777 return {};
1727 distributionOffset = availableFreeSpace / (numberOfGridTracks - 1); 1778 return {0, availableFreeSpace / (numberOfGridTracks - 1)};
1728 positionOffset = 0;
1729 return true;
1730 case ContentDistributionSpaceAround: 1779 case ContentDistributionSpaceAround:
1731 if (numberOfGridTracks < 1) 1780 if (numberOfGridTracks < 1)
1732 return false; 1781 return {};
1733 distributionOffset = availableFreeSpace / numberOfGridTracks; 1782 distributionOffset = availableFreeSpace / numberOfGridTracks;
1734 positionOffset = distributionOffset / 2; 1783 return {distributionOffset / 2, distributionOffset};
1735 return true;
1736 case ContentDistributionSpaceEvenly: 1784 case ContentDistributionSpaceEvenly:
1737 distributionOffset = availableFreeSpace / (numberOfGridTracks + 1); 1785 distributionOffset = availableFreeSpace / (numberOfGridTracks + 1);
1738 positionOffset = distributionOffset; 1786 return {distributionOffset, distributionOffset};
1739 return true;
1740 case ContentDistributionStretch: 1787 case ContentDistributionStretch:
1741 distributionOffset = 0; 1788 return {0, 0};
1742 positionOffset = 0;
1743 return true;
1744 case ContentDistributionDefault: 1789 case ContentDistributionDefault:
1745 distributionOffset = 0; 1790 return {};
1746 positionOffset = 0;
1747 return false;
1748 } 1791 }
1749 1792
1750 ASSERT_NOT_REACHED(); 1793 ASSERT_NOT_REACHED();
1751 return false; 1794 return {};
1752 } 1795 }
1753 1796
1754 void LayoutGrid::computeContentPositionAndDistributionColumnOffset(LayoutUnit av ailableFreeSpace, GridSizingData& sizingData) const 1797 ContentAlignmentData LayoutGrid::computeContentPositionAndDistributionOffset(Gri dTrackSizingDirection direction, LayoutUnit availableFreeSpace, unsigned numberO fGridTracks) const
1755 { 1798 {
1756 ContentPosition position = styleRef().justifyContentPosition(); 1799 bool isRowAxis = direction == ForColumns;
1757 ContentDistributionType distribution = styleRef().justifyContentDistribution (); 1800 ContentPosition position = isRowAxis ? styleRef().justifyContentPosition() : styleRef().alignContentPosition();
1801 ContentDistributionType distribution = isRowAxis ? styleRef().justifyContent Distribution() : styleRef().alignContentDistribution();
1758 // If <content-distribution> value can't be applied, 'position' will become the associated 1802 // If <content-distribution> value can't be applied, 'position' will become the associated
1759 // <content-position> fallback value. 1803 // <content-position> fallback value.
1760 if (contentDistributionOffset(availableFreeSpace, position, distribution, si zingData.columnTracks.size(), sizingData.columnsPositionOffset, sizingData.colum nsDistributionOffset)) 1804 ContentAlignmentData contentAlignment = contentDistributionOffset(availableF reeSpace, position, distribution, numberOfGridTracks);
1761 return; 1805 if (contentAlignment.isValid())
1806 return contentAlignment;
1762 1807
1763 OverflowAlignment overflow = styleRef().justifyContentOverflowAlignment(); 1808 OverflowAlignment overflow = isRowAxis ? styleRef().justifyContentOverflowAl ignment() : styleRef().alignContentOverflowAlignment();
1764 if (overflow == OverflowAlignmentSafe && availableFreeSpace <= 0) 1809 if (availableFreeSpace <= 0 && overflow == OverflowAlignmentSafe)
1765 return; 1810 return {0, 0};
1766 1811
1767 switch (position) { 1812 switch (position) {
1768 case ContentPositionLeft: 1813 case ContentPositionLeft:
1769 sizingData.columnsPositionOffset = 0; 1814 // The align-content's axis is always orthogonal to the inline-axis.
1770 return; 1815 return {0, 0};
1771 case ContentPositionRight: 1816 case ContentPositionRight:
1772 sizingData.columnsPositionOffset = availableFreeSpace; 1817 if (isRowAxis)
1773 return; 1818 return {availableFreeSpace, 0};
1819 // The align-content's axis is always orthogonal to the inline-axis.
1820 return {0, 0};
1774 case ContentPositionCenter: 1821 case ContentPositionCenter:
1775 sizingData.columnsPositionOffset = availableFreeSpace / 2; 1822 return {availableFreeSpace / 2, 0};
1776 return; 1823 case ContentPositionFlexEnd: // Only used in flex layout, for other layout, it's equivalent to 'End'.
1777 case ContentPositionFlexEnd:
1778 // Only used in flex layout, for other layout, it's equivalent to 'end'.
1779 case ContentPositionEnd: 1824 case ContentPositionEnd:
1780 sizingData.columnsPositionOffset = offsetToEndEdge(style()->isLeftToRigh tDirection(), availableFreeSpace); 1825 if (isRowAxis)
1781 return; 1826 return {offsetToEndEdge(styleRef().isLeftToRightDirection(), availab leFreeSpace), 0};
1782 case ContentPositionFlexStart: 1827 return {availableFreeSpace, 0};
1783 // Only used in flex layout, for other layout, it's equivalent to 'start '. 1828 case ContentPositionFlexStart: // Only used in flex layout, for other layout , it's equivalent to 'Start'.
1784 case ContentPositionStart: 1829 case ContentPositionStart:
1785 sizingData.columnsPositionOffset = offsetToStartEdge(style()->isLeftToRi ghtDirection(), availableFreeSpace); 1830 if (isRowAxis)
1786 return; 1831 return {offsetToStartEdge(styleRef().isLeftToRightDirection(), avail ableFreeSpace), 0};
1832 return {0, 0};
1787 case ContentPositionBaseline: 1833 case ContentPositionBaseline:
1788 case ContentPositionLastBaseline: 1834 case ContentPositionLastBaseline:
1789 // FIXME: These two require implementing Baseline Alignment. For now, we always 'start' align the child. 1835 // FIXME: These two require implementing Baseline Alignment. For now, we always 'start' align the child.
1790 // crbug.com/234191 1836 // crbug.com/234191
1791 sizingData.columnsPositionOffset = offsetToStartEdge(style()->isLeftToRi ghtDirection(), availableFreeSpace); 1837 if (isRowAxis)
1792 return; 1838 return {offsetToStartEdge(styleRef().isLeftToRightDirection(), avail ableFreeSpace), 0};
1839 return {0, 0};
1793 case ContentPositionAuto: 1840 case ContentPositionAuto:
1794 break; 1841 break;
1795 } 1842 }
1796 1843
1797 ASSERT_NOT_REACHED(); 1844 ASSERT_NOT_REACHED();
1798 } 1845 return {0, 0};
1799
1800 void LayoutGrid::computeContentPositionAndDistributionRowOffset(LayoutUnit avail ableFreeSpace, GridSizingData& sizingData) const
1801 {
1802 ContentPosition position = styleRef().alignContentPosition();
1803 ContentDistributionType distribution = styleRef().alignContentDistribution() ;
1804 // If <content-distribution> value can't be applied, 'position' will become the associated
1805 // <content-position> fallback value.
1806 if (contentDistributionOffset(availableFreeSpace, position, distribution, si zingData.rowTracks.size(), sizingData.rowsPositionOffset, sizingData.rowsDistrib utionOffset))
1807 return;
1808
1809 OverflowAlignment overflow = styleRef().alignContentOverflowAlignment();
1810 if (overflow == OverflowAlignmentSafe && availableFreeSpace <= 0)
1811 return;
1812
1813 switch (position) {
1814 case ContentPositionLeft:
1815 // The align-content's axis is always orthogonal to the inline-axis.
1816 sizingData.rowsPositionOffset = 0;
1817 return;
1818 case ContentPositionRight:
1819 // The align-content's axis is always orthogonal to the inline-axis.
1820 sizingData.rowsPositionOffset = 0;
1821 return;
1822 case ContentPositionCenter:
1823 sizingData.rowsPositionOffset = availableFreeSpace / 2;
1824 return;
1825 case ContentPositionFlexEnd:
1826 // Only used in flex layout, for other layout, it's equivalent to 'End'.
1827 case ContentPositionEnd:
1828 sizingData.rowsPositionOffset = availableFreeSpace;
1829 return;
1830 case ContentPositionFlexStart:
1831 // Only used in flex layout, for other layout, it's equivalent to 'Start '.
1832 case ContentPositionStart:
1833 sizingData.rowsPositionOffset = 0;
1834 return;
1835 case ContentPositionBaseline:
1836 case ContentPositionLastBaseline:
1837 // FIXME: These two require implementing Baseline Alignment. For now, we always 'start' align the child.
1838 // crbug.com/234191
1839 sizingData.rowsPositionOffset = 0;
1840 return;
1841 case ContentPositionAuto:
1842 break;
1843 }
1844
1845 ASSERT_NOT_REACHED();
1846 } 1846 }
1847 1847
1848 LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child, GridSiz ingData& sizingData) const 1848 LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child, GridSiz ingData& sizingData) const
1849 { 1849 {
1850 LayoutUnit columnPosition = columnPositionForChild(child); 1850 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child);
1851 // We stored m_columnPositions's data ignoring the direction, hence we might need now 1851 // We stored m_columnPosition s's data ignoring the direction, hence we migh t need now
1852 // to translate positions from RTL to LTR, as it's more convenient for paint ing. 1852 // to translate positions from RTL to LTR, as it's more convenient for paint ing.
1853 if (!style()->isLeftToRightDirection()) 1853 if (!style()->isLeftToRightDirection()) {
1854 columnPosition = (m_columnPositions[m_columnPositions.size() - 1] + bord erAndPaddingLogicalLeft() + sizingData.columnsPositionOffset) - columnPosition - sizingData.columnsDistributionOffset - child.logicalWidth(); 1854 LayoutUnit alignmentOffset = m_columnPositions[0] - borderAndPaddingSta rt();
1855 LayoutUnit rightGridEdgePosition = m_columnPositions[m_columnPositions.s ize() - 1] + alignmentOffset + borderAndPaddingLogicalLeft();
1856 rowAxisOffset = rightGridEdgePosition - (rowAxisOffset + child.logicalWi dth());
1857 }
1855 1858
1856 return LayoutPoint(columnPosition, rowPositionForChild(child)); 1859 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child));
1857 } 1860 }
1858 1861
1859 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) 1862 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset)
1860 { 1863 {
1861 GridPainter(*this).paintChildren(paintInfo, paintOffset); 1864 GridPainter(*this).paintChildren(paintInfo, paintOffset);
1862 } 1865 }
1863 1866
1864 } // namespace blink 1867 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698