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 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB
lockContentLogicalWidth); | 1348 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB
lockContentLogicalWidth); |
1349 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining
BlockContentLogicalHeight); | 1349 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining
BlockContentLogicalHeight); |
1350 | 1350 |
1351 // Stretching logic might force a child layout, so we need to run it bef
ore the layoutIfNeeded | 1351 // Stretching logic might force a child layout, so we need to run it bef
ore the layoutIfNeeded |
1352 // call to avoid unnecessary relayouts. This might imply that child marg
ins, needed to correctly | 1352 // call to avoid unnecessary relayouts. This might imply that child marg
ins, needed to correctly |
1353 // determine the available space before stretching, are not set yet. | 1353 // determine the available space before stretching, are not set yet. |
1354 applyStretchAlignmentToChildIfNeeded(*child); | 1354 applyStretchAlignmentToChildIfNeeded(*child); |
1355 | 1355 |
1356 child->layoutIfNeeded(); | 1356 child->layoutIfNeeded(); |
1357 | 1357 |
| 1358 // We need pending layouts to be done in order to compute auto-margins p
roperly. |
| 1359 updateAutoMarginsInColumnAxisIfNeeded(*child); |
| 1360 updateAutoMarginsInRowAxisIfNeeded(*child); |
| 1361 |
1358 #if ENABLE(ASSERT) | 1362 #if ENABLE(ASSERT) |
1359 const GridCoordinate& coordinate = cachedGridCoordinate(*child); | 1363 const GridCoordinate& coordinate = cachedGridCoordinate(*child); |
1360 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c
olumnTracks.size()); | 1364 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c
olumnTracks.size()); |
1361 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT
racks.size()); | 1365 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT
racks.size()); |
1362 #endif | 1366 #endif |
1363 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); | 1367 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); |
1364 | 1368 |
1365 // Keep track of children overflowing their grid area as we might need t
o paint them even if the grid-area is | 1369 // Keep track of children overflowing their grid area as we might need t
o paint them even if the grid-area is |
1366 // not visible | 1370 // not visible |
1367 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight | 1371 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 LayoutUnit marginAfter; | 1608 LayoutUnit marginAfter; |
1605 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock
LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter, | 1609 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock
LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter, |
1606 child.style()->marginBeforeUsing(style()), | 1610 child.style()->marginBeforeUsing(style()), |
1607 child.style()->marginAfterUsing(style())); | 1611 child.style()->marginAfterUsing(style())); |
1608 | 1612 |
1609 return marginBefore + marginAfter; | 1613 return marginBefore + marginAfter; |
1610 } | 1614 } |
1611 | 1615 |
1612 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni
t gridAreaBreadthForChild, const LayoutBox& child) const | 1616 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni
t gridAreaBreadthForChild, const LayoutBox& child) const |
1613 { | 1617 { |
1614 LayoutUnit childMarginLogicalHeight = marginLogicalHeightForChild(child); | |
1615 | |
1616 // Because we want to avoid multiple layouts, stretching logic might be perf
ormed before | 1618 // Because we want to avoid multiple layouts, stretching logic might be perf
ormed before |
1617 // children are laid out, so we can't use the child cached values. Hence, we
need to | 1619 // children are laid out, so we can't use the child cached values. Hence, we
need to |
1618 // compute margins in order to determine the available height before stretch
ing. | 1620 // compute margins in order to determine the available height before stretch
ing. |
1619 if (childMarginLogicalHeight == 0) | 1621 return gridAreaBreadthForChild - (child.needsLayout() ? computeMarginLogical
HeightForChild(child) : marginLogicalHeightForChild(child)); |
1620 childMarginLogicalHeight = computeMarginLogicalHeightForChild(child); | |
1621 | |
1622 return gridAreaBreadthForChild - childMarginLogicalHeight; | |
1623 } | 1622 } |
1624 | 1623 |
1625 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La
youtBox. | 1624 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La
youtBox. |
1626 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) | 1625 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) |
1627 { | 1626 { |
1628 // We clear both width and height override values because we will decide now
whether they | 1627 // We clear both width and height override values because we will decide now
whether they |
1629 // are allowed or not, evaluating the conditions which might have changed si
nce the old | 1628 // are allowed or not, evaluating the conditions which might have changed si
nce the old |
1630 // values were set. | 1629 // values were set. |
1631 child.clearOverrideSize(); | 1630 child.clearOverrideSize(); |
1632 | 1631 |
(...skipping 26 matching lines...) Expand all Loading... |
1659 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b
orderAndPaddingLogicalHeight()); | 1658 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b
orderAndPaddingLogicalHeight()); |
1660 if (desiredLogicalHeight != child.logicalHeight()) { | 1659 if (desiredLogicalHeight != child.logicalHeight()) { |
1661 // TODO (lajava): Can avoid laying out here in some cases. See h
ttps://webkit.org/b/87905. | 1660 // TODO (lajava): Can avoid laying out here in some cases. See h
ttps://webkit.org/b/87905. |
1662 child.setLogicalHeight(0); | 1661 child.setLogicalHeight(0); |
1663 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); | 1662 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); |
1664 } | 1663 } |
1665 } | 1664 } |
1666 } | 1665 } |
1667 } | 1666 } |
1668 | 1667 |
| 1668 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. |
| 1669 bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const |
| 1670 { |
| 1671 if (isHorizontalWritingMode()) |
| 1672 return child.style()->marginTop().isAuto() || child.style()->marginBotto
m().isAuto(); |
| 1673 return child.style()->marginLeft().isAuto() || child.style()->marginRight().
isAuto(); |
| 1674 } |
| 1675 |
| 1676 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. |
| 1677 bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const |
| 1678 { |
| 1679 if (isHorizontalWritingMode()) |
| 1680 return child.style()->marginLeft().isAuto() || child.style()->marginRigh
t().isAuto(); |
| 1681 return child.style()->marginTop().isAuto() || child.style()->marginBottom().
isAuto(); |
| 1682 } |
| 1683 |
| 1684 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. |
| 1685 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) |
| 1686 { |
| 1687 ASSERT(!child.isOutOfFlowPositioned()); |
| 1688 |
| 1689 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog
icalWidth() - child.logicalWidth(); |
| 1690 if (availableAlignmentSpace <= 0) |
| 1691 return; |
| 1692 |
| 1693 Length marginStart = child.style()->marginStartUsing(style()); |
| 1694 Length marginEnd = child.style()->marginEndUsing(style()); |
| 1695 if (marginStart.isAuto() && marginEnd.isAuto()) { |
| 1696 child.setMarginStart(availableAlignmentSpace / 2, style()); |
| 1697 child.setMarginEnd(availableAlignmentSpace / 2, style()); |
| 1698 } else if (marginStart.isAuto()) { |
| 1699 child.setMarginStart(availableAlignmentSpace, style()); |
| 1700 } else if (marginEnd.isAuto()) { |
| 1701 child.setMarginEnd(availableAlignmentSpace, style()); |
| 1702 } |
| 1703 } |
| 1704 |
| 1705 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. |
| 1706 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) |
| 1707 { |
| 1708 ASSERT(!child.isOutOfFlowPositioned()); |
| 1709 |
| 1710 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog
icalHeight() - child.logicalHeight(); |
| 1711 if (availableAlignmentSpace <= 0) |
| 1712 return; |
| 1713 |
| 1714 Length marginBefore = child.style()->marginBeforeUsing(style()); |
| 1715 Length marginAfter = child.style()->marginAfterUsing(style()); |
| 1716 if (marginBefore.isAuto() && marginAfter.isAuto()) { |
| 1717 child.setMarginBefore(availableAlignmentSpace / 2, style()); |
| 1718 child.setMarginAfter(availableAlignmentSpace / 2, style()); |
| 1719 } else if (marginBefore.isAuto()) { |
| 1720 child.setMarginBefore(availableAlignmentSpace, style()); |
| 1721 } else if (marginAfter.isAuto()) { |
| 1722 child.setMarginAfter(availableAlignmentSpace, style()); |
| 1723 } |
| 1724 } |
| 1725 |
1669 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child)
const | 1726 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child)
const |
1670 { | 1727 { |
1671 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon
talWritingMode(); | 1728 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon
talWritingMode(); |
1672 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi
ngMode(); | 1729 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi
ngMode(); |
1673 | 1730 |
1674 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo
sitionStretch)) { | 1731 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo
sitionStretch)) { |
1675 case ItemPositionSelfStart: | 1732 case ItemPositionSelfStart: |
1676 // If orthogonal writing-modes, this computes to 'start'. | 1733 // If orthogonal writing-modes, this computes to 'start'. |
1677 // FIXME: grid track sizing and positioning do not support orthogonal mo
des yet. | 1734 // FIXME: grid track sizing and positioning do not support orthogonal mo
des yet. |
1678 // 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. | 1735 // 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 Loading... |
1756 | 1813 |
1757 ASSERT_NOT_REACHED(); | 1814 ASSERT_NOT_REACHED(); |
1758 return GridAxisStart; | 1815 return GridAxisStart; |
1759 } | 1816 } |
1760 | 1817 |
1761 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const | 1818 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const |
1762 { | 1819 { |
1763 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1820 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1764 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi
on.toInt()]; | 1821 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi
on.toInt()]; |
1765 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); | 1822 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); |
| 1823 if (hasAutoMarginsInColumnAxis(child)) |
| 1824 return startPosition; |
1766 GridAxisPosition axisPosition = columnAxisPositionForChild(child); | 1825 GridAxisPosition axisPosition = columnAxisPositionForChild(child); |
1767 switch (axisPosition) { | 1826 switch (axisPosition) { |
1768 case GridAxisStart: | 1827 case GridAxisStart: |
1769 return startPosition; | 1828 return startPosition; |
1770 case GridAxisEnd: | 1829 case GridAxisEnd: |
1771 case GridAxisCenter: { | 1830 case GridAxisCenter: { |
1772 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi
on.next().toInt()]; | 1831 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi
on.next().toInt()]; |
1773 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil
d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH
eight() + child.marginLogicalHeight()); | 1832 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil
d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH
eight() + child.marginLogicalHeight()); |
1774 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos
ition : offsetFromStartPosition / 2); | 1833 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos
ition : offsetFromStartPosition / 2); |
1775 } | 1834 } |
1776 } | 1835 } |
1777 | 1836 |
1778 ASSERT_NOT_REACHED(); | 1837 ASSERT_NOT_REACHED(); |
1779 return 0; | 1838 return 0; |
1780 } | 1839 } |
1781 | 1840 |
1782 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const | 1841 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const |
1783 { | 1842 { |
1784 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1843 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
1785 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit
ialPosition.toInt()]; | 1844 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit
ialPosition.toInt()]; |
1786 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); | 1845 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); |
| 1846 if (hasAutoMarginsInRowAxis(child)) |
| 1847 return startPosition; |
1787 GridAxisPosition axisPosition = rowAxisPositionForChild(child); | 1848 GridAxisPosition axisPosition = rowAxisPositionForChild(child); |
1788 switch (axisPosition) { | 1849 switch (axisPosition) { |
1789 case GridAxisStart: | 1850 case GridAxisStart: |
1790 return startPosition; | 1851 return startPosition; |
1791 case GridAxisEnd: | 1852 case GridAxisEnd: |
1792 case GridAxisCenter: { | 1853 case GridAxisCenter: { |
1793 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi
nalPosition.next().toInt()]; | 1854 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi
nalPosition.next().toInt()]; |
1794 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil
d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child.
logicalWidth() + child.marginLogicalWidth()); | 1855 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil
d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child.
logicalWidth() + child.marginLogicalWidth()); |
1795 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos
ition : offsetFromStartPosition / 2); | 1856 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos
ition : offsetFromStartPosition / 2); |
1796 } | 1857 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1926 | 1987 |
1927 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 1988 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
1928 } | 1989 } |
1929 | 1990 |
1930 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) | 1991 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) |
1931 { | 1992 { |
1932 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 1993 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
1933 } | 1994 } |
1934 | 1995 |
1935 } // namespace blink | 1996 } // namespace blink |
OLD | NEW |