Chromium Code Reviews| 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 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1345 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); | 1345 child->setOverrideContainingBlockContentLogicalWidth(overrideContainingB lockContentLogicalWidth); |
| 1346 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); | 1346 child->setOverrideContainingBlockContentLogicalHeight(overrideContaining BlockContentLogicalHeight); |
| 1347 | 1347 |
| 1348 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded | 1348 // Stretching logic might force a child layout, so we need to run it bef ore the layoutIfNeeded |
| 1349 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly | 1349 // call to avoid unnecessary relayouts. This might imply that child marg ins, needed to correctly |
| 1350 // determine the available space before stretching, are not set yet. | 1350 // determine the available space before stretching, are not set yet. |
| 1351 applyStretchAlignmentToChildIfNeeded(*child); | 1351 applyStretchAlignmentToChildIfNeeded(*child); |
| 1352 | 1352 |
| 1353 child->layoutIfNeeded(); | 1353 child->layoutIfNeeded(); |
| 1354 | 1354 |
| 1355 // We need pending layouts to be done in order to compute auto-margins p roperly. | |
|
Manuel Rego
2015/09/24 11:38:26
Probably we could add an ASSERT in the methods
to
jfernandez
2015/09/25 13:47:02
Acknowledged.
| |
| 1356 updateAutoMarginsInColumnAxisIfNeeded(*child); | |
| 1357 updateAutoMarginsInRowAxisIfNeeded(*child); | |
| 1358 | |
| 1355 #if ENABLE(ASSERT) | 1359 #if ENABLE(ASSERT) |
| 1356 const GridCoordinate& coordinate = cachedGridCoordinate(*child); | 1360 const GridCoordinate& coordinate = cachedGridCoordinate(*child); |
| 1357 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); | 1361 ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.c olumnTracks.size()); |
| 1358 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); | 1362 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); |
| 1359 #endif | 1363 #endif |
| 1360 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); | 1364 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); |
| 1361 | 1365 |
| 1362 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is | 1366 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is |
| 1363 // not visible | 1367 // not visible |
| 1364 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight | 1368 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1601 LayoutUnit marginAfter; | 1605 LayoutUnit marginAfter; |
| 1602 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter, | 1606 child.computeMarginsForDirection(BlockDirection, this, child.containingBlock LogicalWidthForContent(), child.logicalHeight(), marginBefore, marginAfter, |
| 1603 child.style()->marginBeforeUsing(style()), | 1607 child.style()->marginBeforeUsing(style()), |
| 1604 child.style()->marginAfterUsing(style())); | 1608 child.style()->marginAfterUsing(style())); |
| 1605 | 1609 |
| 1606 return marginBefore + marginAfter; | 1610 return marginBefore + marginAfter; |
| 1607 } | 1611 } |
| 1608 | 1612 |
| 1609 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni t gridAreaBreadthForChild, const LayoutBox& child) const | 1613 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUni t gridAreaBreadthForChild, const LayoutBox& child) const |
| 1610 { | 1614 { |
| 1611 LayoutUnit childMarginLogicalHeight = marginLogicalHeightForChild(child); | |
| 1612 | |
| 1613 // Because we want to avoid multiple layouts, stretching logic might be perf ormed before | 1615 // Because we want to avoid multiple layouts, stretching logic might be perf ormed before |
| 1614 // children are laid out, so we can't use the child cached values. Hence, we need to | 1616 // children are laid out, so we can't use the child cached values. Hence, we need to |
| 1615 // compute margins in order to determine the available height before stretch ing. | 1617 // compute margins in order to determine the available height before stretch ing. |
| 1616 if (childMarginLogicalHeight == 0) | 1618 return gridAreaBreadthForChild - (child.needsLayout() ? computeMarginLogical HeightForChild(child) : marginLogicalHeightForChild(child)); |
| 1617 childMarginLogicalHeight = computeMarginLogicalHeightForChild(child); | |
| 1618 | |
| 1619 return gridAreaBreadthForChild - childMarginLogicalHeight; | |
| 1620 } | 1619 } |
| 1621 | 1620 |
| 1622 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La youtBox. | 1621 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La youtBox. |
| 1623 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) | 1622 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) |
| 1624 { | 1623 { |
| 1625 // We clear both width and height override values because we will decide now whether they | 1624 // We clear both width and height override values because we will decide now whether they |
| 1626 // are allowed or not, evaluating the conditions which might have changed si nce the old | 1625 // are allowed or not, evaluating the conditions which might have changed si nce the old |
| 1627 // values were set. | 1626 // values were set. |
| 1628 child.clearOverrideSize(); | 1627 child.clearOverrideSize(); |
| 1629 | 1628 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1656 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); | 1655 child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.b orderAndPaddingLogicalHeight()); |
| 1657 if (desiredLogicalHeight != child.logicalHeight()) { | 1656 if (desiredLogicalHeight != child.logicalHeight()) { |
| 1658 // TODO (lajava): Can avoid laying out here in some cases. See h ttps://webkit.org/b/87905. | 1657 // TODO (lajava): Can avoid laying out here in some cases. See h ttps://webkit.org/b/87905. |
| 1659 child.setLogicalHeight(0); | 1658 child.setLogicalHeight(0); |
| 1660 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); | 1659 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); |
| 1661 } | 1660 } |
| 1662 } | 1661 } |
| 1663 } | 1662 } |
| 1664 } | 1663 } |
| 1665 | 1664 |
| 1665 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
| 1666 bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const | |
| 1667 { | |
| 1668 if (isHorizontalWritingMode()) | |
| 1669 return child.style()->marginTop().isAuto() || child.style()->marginBotto m().isAuto(); | |
| 1670 return child.style()->marginLeft().isAuto() || child.style()->marginRight(). isAuto(); | |
| 1671 } | |
| 1672 | |
| 1673 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
| 1674 bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const | |
| 1675 { | |
| 1676 if (isHorizontalWritingMode()) | |
| 1677 return child.style()->marginLeft().isAuto() || child.style()->marginRigh t().isAuto(); | |
| 1678 return child.style()->marginTop().isAuto() || child.style()->marginBottom(). isAuto(); | |
| 1679 } | |
| 1680 | |
| 1681 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
| 1682 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) | |
| 1683 { | |
| 1684 ASSERT(!child.isOutOfFlowPositioned()); | |
| 1685 | |
| 1686 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalWidth() - child.logicalWidth(); | |
| 1687 if (availableAlignmentSpace <= 0) | |
| 1688 return; | |
| 1689 | |
| 1690 bool isHorizontal = isHorizontalWritingMode(); | |
| 1691 Length topOrLeft = isHorizontal ? child.style()->marginLeft() : child.style( )->marginTop(); | |
|
Manuel Rego
2015/09/24 11:38:26
To simplify the code and all the checks related to
jfernandez
2015/09/25 13:47:02
I think it wouldn't be an equivalent logic. Be awa
Manuel Rego
2015/09/25 16:00:58
BTW, I was thinking in style()->marginStart()
whic
| |
| 1692 Length bottomOrRight = isHorizontal ? child.style()->marginRight() : child.s tyle()->marginBottom(); | |
|
Manuel Rego
2015/09/24 11:38:27
Ditto.
jfernandez
2015/09/25 13:47:02
Replied.
| |
| 1693 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) { | |
| 1694 if (isHorizontal) { | |
| 1695 child.setMarginLeft(availableAlignmentSpace / 2); | |
| 1696 child.setMarginRight(availableAlignmentSpace / 2); | |
| 1697 } else { | |
| 1698 child.setMarginTop(availableAlignmentSpace / 2); | |
| 1699 child.setMarginBottom(availableAlignmentSpace / 2); | |
| 1700 } | |
|
Manuel Rego
2015/09/24 11:38:27
Probably here you could use setMarginStart().
jfernandez
2015/09/25 13:47:02
This could be true, but I'm not sure whether it'd
| |
| 1701 } else if (topOrLeft.isAuto()) { | |
| 1702 if (isHorizontal) | |
| 1703 child.setMarginLeft(availableAlignmentSpace); | |
| 1704 else | |
| 1705 child.setMarginTop(availableAlignmentSpace); | |
|
Manuel Rego
2015/09/24 11:38:27
Ditto.
jfernandez
2015/09/25 13:47:02
Replied.
| |
| 1706 } else if (bottomOrRight.isAuto()) { | |
| 1707 if (isHorizontal) | |
| 1708 child.setMarginRight(availableAlignmentSpace); | |
| 1709 else | |
| 1710 child.setMarginBottom(availableAlignmentSpace); | |
|
Manuel Rego
2015/09/24 11:38:27
Ditto.
jfernandez
2015/09/25 13:47:02
Replied.
| |
| 1711 } | |
| 1712 } | |
| 1713 | |
| 1714 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move d to LayoutBox. | |
| 1715 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) | |
| 1716 { | |
| 1717 ASSERT(!child.isOutOfFlowPositioned()); | |
| 1718 | |
| 1719 LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLog icalHeight() - child.logicalHeight(); | |
| 1720 if (availableAlignmentSpace <= 0) | |
| 1721 return; | |
| 1722 | |
| 1723 bool isHorizontal = isHorizontalWritingMode(); | |
| 1724 Length topOrLeft = isHorizontal ? child.style()->marginTop() : child.style() ->marginLeft(); | |
|
Manuel Rego
2015/09/24 11:38:26
The same than in the row axis method.
jfernandez
2015/09/25 13:47:02
Replied.
| |
| 1725 Length bottomOrRight = isHorizontal ? child.style()->marginBottom() : child. style()->marginRight(); | |
| 1726 if (topOrLeft.isAuto() && bottomOrRight.isAuto()) { | |
| 1727 if (isHorizontal) { | |
| 1728 child.setMarginTop(availableAlignmentSpace / 2); | |
| 1729 child.setMarginBottom(availableAlignmentSpace / 2); | |
| 1730 } else { | |
| 1731 child.setMarginLeft(availableAlignmentSpace / 2); | |
| 1732 child.setMarginRight(availableAlignmentSpace / 2); | |
| 1733 } | |
| 1734 } else if (topOrLeft.isAuto()) { | |
| 1735 if (isHorizontal) | |
| 1736 child.setMarginTop(availableAlignmentSpace); | |
| 1737 else | |
| 1738 child.setMarginLeft(availableAlignmentSpace); | |
| 1739 } else if (bottomOrRight.isAuto()) { | |
| 1740 if (isHorizontal) | |
| 1741 child.setMarginBottom(availableAlignmentSpace); | |
| 1742 else | |
| 1743 child.setMarginRight(availableAlignmentSpace); | |
| 1744 } | |
| 1745 } | |
| 1746 | |
| 1666 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const | 1747 GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const |
| 1667 { | 1748 { |
| 1668 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); | 1749 bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizon talWritingMode(); |
| 1669 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode(); | 1750 bool hasSameWritingMode = child.styleRef().writingMode() == styleRef().writi ngMode(); |
| 1670 | 1751 |
| 1671 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) { | 1752 switch (ComputedStyle::resolveAlignment(styleRef(), child.styleRef(), ItemPo sitionStretch)) { |
| 1672 case ItemPositionSelfStart: | 1753 case ItemPositionSelfStart: |
| 1673 // If orthogonal writing-modes, this computes to 'start'. | 1754 // If orthogonal writing-modes, this computes to 'start'. |
| 1674 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. | 1755 // FIXME: grid track sizing and positioning do not support orthogonal mo des yet. |
| 1675 // 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. | 1756 // 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... | |
| 1753 | 1834 |
| 1754 ASSERT_NOT_REACHED(); | 1835 ASSERT_NOT_REACHED(); |
| 1755 return GridAxisStart; | 1836 return GridAxisStart; |
| 1756 } | 1837 } |
| 1757 | 1838 |
| 1758 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const | 1839 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const |
| 1759 { | 1840 { |
| 1760 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1841 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
| 1761 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; | 1842 LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPositi on.toInt()]; |
| 1762 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); | 1843 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); |
| 1844 if (hasAutoMarginsInColumnAxis(child)) | |
| 1845 return startPosition; | |
| 1763 GridAxisPosition axisPosition = columnAxisPositionForChild(child); | 1846 GridAxisPosition axisPosition = columnAxisPositionForChild(child); |
| 1764 switch (axisPosition) { | 1847 switch (axisPosition) { |
| 1765 case GridAxisStart: | 1848 case GridAxisStart: |
| 1766 return startPosition; | 1849 return startPosition; |
| 1767 case GridAxisEnd: | 1850 case GridAxisEnd: |
| 1768 case GridAxisCenter: { | 1851 case GridAxisCenter: { |
| 1769 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; | 1852 LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPositi on.next().toInt()]; |
| 1770 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); | 1853 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().alignSelfOverflowAlignment(), endOfRow - startOfRow, child.logicalH eight() + child.marginLogicalHeight()); |
| 1771 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); | 1854 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); |
| 1772 } | 1855 } |
| 1773 } | 1856 } |
| 1774 | 1857 |
| 1775 ASSERT_NOT_REACHED(); | 1858 ASSERT_NOT_REACHED(); |
| 1776 return 0; | 1859 return 0; |
| 1777 } | 1860 } |
| 1778 | 1861 |
| 1779 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const | 1862 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const |
| 1780 { | 1863 { |
| 1781 const GridCoordinate& coordinate = cachedGridCoordinate(child); | 1864 const GridCoordinate& coordinate = cachedGridCoordinate(child); |
| 1782 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; | 1865 LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInit ialPosition.toInt()]; |
| 1783 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); | 1866 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); |
| 1867 if (hasAutoMarginsInRowAxis(child)) | |
| 1868 return startPosition; | |
| 1784 GridAxisPosition axisPosition = rowAxisPositionForChild(child); | 1869 GridAxisPosition axisPosition = rowAxisPositionForChild(child); |
| 1785 switch (axisPosition) { | 1870 switch (axisPosition) { |
| 1786 case GridAxisStart: | 1871 case GridAxisStart: |
| 1787 return startPosition; | 1872 return startPosition; |
| 1788 case GridAxisEnd: | 1873 case GridAxisEnd: |
| 1789 case GridAxisCenter: { | 1874 case GridAxisCenter: { |
| 1790 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()]; | 1875 LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFi nalPosition.next().toInt()]; |
| 1791 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth()); | 1876 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(chil d.styleRef().justifySelfOverflowAlignment(), endOfColumn - startOfColumn, child. logicalWidth() + child.marginLogicalWidth()); |
| 1792 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); | 1877 return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPos ition : offsetFromStartPosition / 2); |
| 1793 } | 1878 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1923 | 2008 |
| 1924 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 2009 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
| 1925 } | 2010 } |
| 1926 | 2011 |
| 1927 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) | 2012 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) |
| 1928 { | 2013 { |
| 1929 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 2014 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
| 1930 } | 2015 } |
| 1931 | 2016 |
| 1932 } // namespace blink | 2017 } // namespace blink |
| OLD | NEW |