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

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

Issue 1233983003: [CSS Grid Layout] Implement auto-margin alignment for grid (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@horizontal-stretch
Patch Set: 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 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 // the grid breadth to account for 'box-sizing'. 1261 // the grid breadth to account for 'box-sizing'.
1262 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit(); 1262 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOve rrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogica lWidth() : LayoutUnit();
1263 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit(); 1263 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOv errideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogi calHeight() : LayoutUnit();
1264 1264
1265 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChild(*child, ForColumns, sizingData.columnTracks); 1265 LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthF orChild(*child, ForColumns, sizingData.columnTracks);
1266 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChild(*child, ForRows, sizingData.rowTracks); 1266 LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadth ForChild(*child, ForRows, sizingData.rowTracks);
1267 1267
1268 SubtreeLayoutScope layoutScope(*child); 1268 SubtreeLayoutScope layoutScope(*child);
1269 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight())) 1269 if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingB lockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != ov errideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight()))
1270 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged); 1270 layoutScope.setNeedsLayout(child, LayoutInvalidationReason::GridChan ged);
1271 else
1272 resetAutoMarginsAndLogicalTopInColumnAxis(*child);
1271 1273
1272 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); 1274 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth);
1273 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); 1275 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight);
1274 1276
1275 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded 1277 // 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 1278 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly
1277 // determine the available space before stretching, are not set yet. 1279 // determine the available space before stretching, are not set yet.
1278 applyStretchAlignmentToChildIfNeeded(*child); 1280 applyStretchAlignmentToChildIfNeeded(*child);
1279 1281
1280 child->layoutIfNeeded(); 1282 child->layoutIfNeeded();
1281 1283
1284 // We need pending layouts to be done in order to compute auto-margins p roperly.
1285 updateAutoMarginsInColumnAxisIfNeeded(*child);
1286 updateAutoMarginsInRowAxisIfNeeded(*child);
1287
1282 #if ENABLE(ASSERT) 1288 #if ENABLE(ASSERT)
1283 const GridCoordinate& coordinate = cachedGridCoordinate(*child); 1289 const GridCoordinate& coordinate = cachedGridCoordinate(*child);
1284 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); 1290 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size());
1285 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); 1291 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size());
1286 #endif 1292 #endif
1287 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); 1293 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
1288 1294
1289 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is 1295 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is
1290 // not visible 1296 // not visible
1291 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight 1297 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeigh t(); 1584 bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeigh t();
1579 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); 1585 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight());
1580 if (childNeedsRelayout) { 1586 if (childNeedsRelayout) {
1581 child.setLogicalHeight(0); 1587 child.setLogicalHeight(0);
1582 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 1588 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1583 } 1589 }
1584 } 1590 }
1585 } 1591 }
1586 } 1592 }
1587 1593
1594 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1595 bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const
1596 {
1597 if (isHorizontalWritingMode())
1598 return child.style()->marginTop().isAuto() || child.style()->marginBotto m().isAuto();
1599 return child.style()->marginLeft().isAuto() || child.style()->marginRight(). isAuto();
1600 }
1601
1602 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1603 bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const
1604 {
1605 if (isHorizontalWritingMode())
1606 return child.style()->marginLeft().isAuto() || child.style()->marginRigh t().isAuto();
1607 return child.style()->marginTop().isAuto() || child.style()->marginBottom(). isAuto();
1608 }
1609
1610 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1611 void LayoutGrid::resetAutoMarginsAndLogicalTopInColumnAxis(LayoutBox& child)
1612 {
1613 if (hasAutoMarginsInColumnAxis(child) || child.needsLayout()) {
1614 child.clearOverrideLogicalContentHeight();
1615 child.updateLogicalHeight();
1616 if (isHorizontalWritingMode()) {
1617 if (child.style()->marginTop().isAuto())
1618 child.setMarginTop(0);
1619 if (child.style()->marginBottom().isAuto())
1620 child.setMarginBottom(0);
1621 } else {
1622 if (child.style()->marginLeft().isAuto())
1623 child.setMarginLeft(0);
1624 if (child.style()->marginRight().isAuto())
1625 child.setMarginRight(0);
1626 }
1627
1628 }
1629 }
1630
1631 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1632 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child)
1633 {
1634 ASSERT(!child.isOutOfFlowPositioned());
1635
1636 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalWidth() - child.logicalWidth();
1637 if (availableAlignmentSpace <= 0)
1638 return;
1639
1640 bool isHorizontal = isHorizontalWritingMode();
1641 Length topOrLeft = isHorizontal ? child.style()->marginLeft() : child.style( )->marginTop();
1642 Length bottomOrRight = isHorizontal ? child.style()->marginRight() : child.s tyle()->marginBottom();
1643 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) {
1644 if (isHorizontal) {
1645 child.setMarginLeft(availableAlignmentSpace / 2);
1646 child.setMarginRight(availableAlignmentSpace / 2);
1647 } else {
1648 child.setMarginTop(availableAlignmentSpace / 2);
1649 child.setMarginBottom(availableAlignmentSpace / 2);
1650 }
1651 } else if (topOrLeft.isAuto()) {
1652 if (isHorizontal)
1653 child.setMarginLeft(availableAlignmentSpace);
1654 else
1655 child.setMarginTop(availableAlignmentSpace);
1656 } else if (bottomOrRight.isAuto()) {
1657 if (isHorizontal)
1658 child.setMarginRight(availableAlignmentSpace);
1659 else
1660 child.setMarginBottom(availableAlignmentSpace);
1661 }
1662 }
1663
1664 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox.
1665 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child)
1666 {
1667 ASSERT(!child.isOutOfFlowPositioned());
1668
1669 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalHeight() - child.logicalHeight();
1670 if (availableAlignmentSpace <= 0)
1671 return;
1672
1673 bool isHorizontal = isHorizontalWritingMode();
1674 Length topOrLeft = isHorizontal ? child.style()->marginTop() : child.style() ->marginLeft();
1675 Length bottomOrRight = isHorizontal ? child.style()->marginBottom() : child. style()->marginRight();
1676 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) {
1677 if (isHorizontal) {
1678 child.setMarginTop(availableAlignmentSpace / 2);
1679 child.setMarginBottom(availableAlignmentSpace / 2);
1680 } else {
1681 child.setMarginLeft(availableAlignmentSpace / 2);
1682 child.setMarginRight(availableAlignmentSpace / 2);
1683 }
1684 } else if (topOrLeft.isAuto()) {
1685 if (isHorizontal)
1686 child.setMarginTop(availableAlignmentSpace);
1687 else
1688 child.setMarginLeft(availableAlignmentSpace);
1689 } else if (bottomOrRight.isAuto()) {
1690 if (isHorizontal)
1691 child.setMarginBottom(availableAlignmentSpace);
1692 else
1693 child.setMarginRight(availableAlignmentSpace);
1694 }
1695 }
1696
1588 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const 1697 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const
1589 { 1698 {
1590 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); 1699 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode();
1591 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode(); 1700 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode();
1592 1701
1593 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) { 1702 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) {
1594 case ItemPositionSelfStart: 1703 case ItemPositionSelfStart:
1595 // If orthogonal writing-modes, this computes to 'start'. 1704 // If orthogonal writing-modes, this computes to 'start'.
1596 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. 1705 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet.
1597 // self-start is based on the child's block axis direction. That's why w e need to check against the grid container's block flow. 1706 // self-start is based on the child's block axis direction. That's why w e need to check against the grid container's block flow.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 1784
1676 ASSERT_NOT_REACHED(); 1785 ASSERT_NOT_REACHED();
1677 return GridAxisStart; 1786 return GridAxisStart;
1678 } 1787 }
1679 1788
1680 LayoutUnit LayoutGrid::rowPositionForChild(const LayoutBox& child) const 1789 LayoutUnit LayoutGrid::rowPositionForChild(const LayoutBox& child) const
1681 { 1790 {
1682 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1791 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1683 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; 1792 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()];
1684 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 1793 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
1794 if (hasAutoMarginsInColumnAxis(child))
1795 return startPosition;
1685 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 1796 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
1686 switch (axisPosition) { 1797 switch (axisPosition) {
1687 case GridAxisStart: 1798 case GridAxisStart:
1688 return startPosition; 1799 return startPosition;
1689 case GridAxisEnd: 1800 case GridAxisEnd:
1690 case GridAxisCenter: { 1801 case GridAxisCenter: {
1691 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; 1802 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()];
1692 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); 1803 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight());
1693 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); 1804 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2);
1694 } 1805 }
1695 } 1806 }
1696 1807
1697 ASSERT_NOT_REACHED(); 1808 ASSERT_NOT_REACHED();
1698 return 0; 1809 return 0;
1699 } 1810 }
1700 1811
1701 LayoutUnit LayoutGrid::columnPositionForChild(const LayoutBox& child) const 1812 LayoutUnit LayoutGrid::columnPositionForChild(const LayoutBox& child) const
1702 { 1813 {
1703 const GridCoordinate& coordinate = cachedGridCoordinate(child); 1814 const GridCoordinate& coordinate = cachedGridCoordinate(child);
1704 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; 1815 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()];
1705 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 1816 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
1817 if (hasAutoMarginsInRowAxis(child))
1818 return startPosition;
1706 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 1819 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
1707 switch (axisPosition) { 1820 switch (axisPosition) {
1708 case GridAxisStart: 1821 case GridAxisStart:
1709 return startPosition; 1822 return startPosition;
1710 case GridAxisEnd: 1823 case GridAxisEnd:
1711 case GridAxisCenter: { 1824 case GridAxisCenter: {
1712 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()]; 1825 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()];
1713 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth()); 1826 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth());
1714 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); 1827 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2);
1715 } 1828 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 2005
1893 return LayoutPoint(columnPosition, rowPositionForChild(child)); 2006 return LayoutPoint(columnPosition, rowPositionForChild(child));
1894 } 2007 }
1895 2008
1896 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) 2009 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset)
1897 { 2010 {
1898 GridPainter(*this).paintChildren(paintInfo, paintOffset); 2011 GridPainter(*this).paintChildren(paintInfo, paintOffset);
1899 } 2012 }
1900 2013
1901 } // namespace blink 2014 } // 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