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

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

Issue 1407633003: [css-grid] Implementation of Baseline Self-Alignment (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Improving the skipped tesst by solving some rounding issues Created 3 years, 8 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 | « third_party/WebKit/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
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/layout/LayoutGrid.h" 26 #include "core/layout/LayoutGrid.h"
27 27
28 #include <algorithm>
29 #include <memory>
28 #include "core/frame/UseCounter.h" 30 #include "core/frame/UseCounter.h"
29 #include "core/layout/LayoutState.h" 31 #include "core/layout/LayoutState.h"
30 #include "core/layout/TextAutosizer.h" 32 #include "core/layout/TextAutosizer.h"
31 #include "core/paint/GridPainter.h" 33 #include "core/paint/GridPainter.h"
32 #include "core/paint/PaintLayer.h" 34 #include "core/paint/PaintLayer.h"
33 #include "core/style/ComputedStyle.h" 35 #include "core/style/ComputedStyle.h"
34 #include "core/style/GridArea.h" 36 #include "core/style/GridArea.h"
35 #include "platform/LengthFunctions.h" 37 #include "platform/LengthFunctions.h"
38 #include "platform/text/WritingMode.h"
36 #include "wtf/PtrUtil.h" 39 #include "wtf/PtrUtil.h"
37 #include <algorithm>
38 #include <memory>
39 40
40 namespace blink { 41 namespace blink {
41 42
42 struct ContentAlignmentData { 43 struct ContentAlignmentData {
43 STACK_ALLOCATED(); 44 STACK_ALLOCATED();
44 45
45 public: 46 public:
46 ContentAlignmentData(){}; 47 ContentAlignmentData(){};
47 ContentAlignmentData(LayoutUnit position, LayoutUnit distribution) 48 ContentAlignmentData(LayoutUnit position, LayoutUnit distribution)
48 : positionOffset(position), distributionOffset(distribution) {} 49 : positionOffset(position), distributionOffset(distribution) {}
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 TrackSizing, availableSpace, freeSpace); 161 TrackSizing, availableSpace, freeSpace);
161 m_trackSizingAlgorithm.run(); 162 m_trackSizingAlgorithm.run();
162 163
163 #if DCHECK_IS_ON() 164 #if DCHECK_IS_ON()
164 DCHECK(m_trackSizingAlgorithm.tracksAreWiderThanMinTrackBreadth()); 165 DCHECK(m_trackSizingAlgorithm.tracksAreWiderThanMinTrackBreadth());
165 #endif 166 #endif
166 } 167 }
167 168
168 void LayoutGrid::repeatTracksSizingIfNeeded(LayoutUnit availableSpaceForColumns, 169 void LayoutGrid::repeatTracksSizingIfNeeded(LayoutUnit availableSpaceForColumns,
169 LayoutUnit availableSpaceForRows) { 170 LayoutUnit availableSpaceForRows) {
171 // Baseline alignment may change item's intrinsic size, hence changing its
172 // min-content contribution.
173 // https://drafts.csswg.org/css-align-3/#baseline-align-content
174 // https://drafts.csswg.org/css-align-3/#baseline-align-self
175 bool baselineAffectIntrinsicWidth = baselineMayAffectIntrinsicWidth();
176 bool baselineAffectIntrinsicHeight = baselineMayAffectIntrinsicHeight();
177
170 // In orthogonal flow cases column track's size is determined by using the 178 // In orthogonal flow cases column track's size is determined by using the
171 // computed row track's size, which it was estimated during the first cycle of 179 // computed row track's size, which it was estimated during the first cycle of
172 // the sizing algorithm. 180 // the sizing algorithm.
173 // Hence we need to repeat computeUsedBreadthOfGridTracks for both, columns 181 bool hasAnyOrthogonal =
174 // and rows, to determine the final values. 182 m_trackSizingAlgorithm.grid().hasAnyOrthogonalGridItem();
175 // TODO (lajava): orthogonal flows is just one of the cases which may require 183
184 // TODO (lajava): these are just some of the cases which may require
176 // a new cycle of the sizing algorithm; there may be more. In addition, not 185 // a new cycle of the sizing algorithm; there may be more. In addition, not
177 // all the cases with orthogonal flows require this extra cycle; we need a 186 // all the cases with orthogonal flows require this extra cycle; we need a
178 // more specific condition to detect whether child's min-content contribution 187 // more specific condition to detect whether child's min-content contribution
179 // has changed or not. 188 // has changed or not.
180 if (m_grid.hasAnyOrthogonalGridItem()) { 189 if (!baselineAffectIntrinsicWidth && !baselineAffectIntrinsicHeight &&
181 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns); 190 !hasAnyOrthogonal)
182 computeTrackSizesForDefiniteSize(ForRows, availableSpaceForRows); 191 return;
192
193 // TODO (lajava): Whenever the min-content contribution of a grid item changes
194 // we may need to update the grid container's intrinsic width. The new
195 // intrinsic width may also affect the extra Track Sizing algorithm cycles we
196 // are about to execute.
197 // https://crbug.com/704713
198 // https://github.com/w3c/csswg-drafts/issues/1039
199
200 // Hence we need to repeat computeUsedBreadthOfGridTracks for both, columns
201 // and rows, to determine the final values.
202 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
203 computeTrackSizesForDefiniteSize(ForRows, availableSpaceForRows);
204
205 if (baselineAffectIntrinsicHeight) {
206 setLogicalHeight(computeTrackBasedLogicalHeight() +
207 borderAndPaddingLogicalHeight() +
208 scrollbarLogicalHeight());
183 } 209 }
184 } 210 }
185 211
186 void LayoutGrid::layoutBlock(bool relayoutChildren) { 212 void LayoutGrid::layoutBlock(bool relayoutChildren) {
187 ASSERT(needsLayout()); 213 ASSERT(needsLayout());
188 214
189 // We cannot perform a simplifiedLayout() on a dirty grid that 215 // We cannot perform a simplifiedLayout() on a dirty grid that
190 // has positioned items to be laid out. 216 // has positioned items to be laid out.
191 if (!relayoutChildren && 217 if (!relayoutChildren &&
192 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) && 218 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) &&
193 simplifiedLayout()) 219 simplifiedLayout())
194 return; 220 return;
195 221
222 m_rowAxisAlignmentContext.clear();
223 m_colAxisAlignmentContext.clear();
224
196 SubtreeLayoutScope layoutScope(*this); 225 SubtreeLayoutScope layoutScope(*this);
197 226
198 { 227 {
199 // LayoutState needs this deliberate scope to pop before updating scroll 228 // LayoutState needs this deliberate scope to pop before updating scroll
200 // information (which may trigger relayout). 229 // information (which may trigger relayout).
201 LayoutState state(*this); 230 LayoutState state(*this);
202 231
203 LayoutSize previousSize = size(); 232 LayoutSize previousSize = size();
204 233
205 // We need to clear both own and containingBlock override sizes to 234 // We need to clear both own and containingBlock override sizes to
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); 281 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
253 updateLogicalHeight(); 282 updateLogicalHeight();
254 283
255 // Once grid's indefinite height is resolved, we can compute the 284 // Once grid's indefinite height is resolved, we can compute the
256 // available free space for Content Alignment. 285 // available free space for Content Alignment.
257 if (!cachedHasDefiniteLogicalHeight()) { 286 if (!cachedHasDefiniteLogicalHeight()) {
258 m_trackSizingAlgorithm.freeSpace(ForRows) = 287 m_trackSizingAlgorithm.freeSpace(ForRows) =
259 logicalHeight() - trackBasedLogicalHeight; 288 logicalHeight() - trackBasedLogicalHeight;
260 } 289 }
261 290
291 // TODO (lajava): We need to compute baselines after step 2 so
292 // items with a relative size (percentages) can resolve it before
293 // determining its baseline. However, we only set item's grid area
294 // (via override sizes) as part of the content-sized tracks sizing
295 // logic. Hence, items located at fixed or flexible tracks can't
296 // resolve correctly their size at this stage, which may lead to
297 // an incorrect computation of their shared context's baseline.
298 computeBaselineAlignmentContext();
299
262 // 3- If the min-content contribution of any grid items have changed based 300 // 3- If the min-content contribution of any grid items have changed based
263 // on the row sizes calculated in step 2, steps 1 and 2 are repeated with 301 // on the row sizes calculated in step 2, steps 1 and 2 are repeated with
264 // the new min-content contribution (once only). 302 // the new min-content contribution (once only).
265 repeatTracksSizingIfNeeded(availableSpaceForColumns, 303 repeatTracksSizingIfNeeded(availableSpaceForColumns,
266 contentLogicalHeight()); 304 contentLogicalHeight());
267 305
268 // Grid container should have the minimum height of a line if it's editable. 306 // Grid container should have the minimum height of a line if it's editable.
269 // That doesn't affect track sizing though. 307 // That doesn't affect track sizing though.
270 if (hasLineIfEmpty()) 308 if (hasLineIfEmpty())
271 setLogicalHeight( 309 setLogicalHeight(
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 .toInt(); 1611 .toInt();
1574 } 1612 }
1575 1613
1576 static int synthesizedBaselineFromBorderBox(const LayoutBox& box, 1614 static int synthesizedBaselineFromBorderBox(const LayoutBox& box,
1577 LineDirectionMode direction) { 1615 LineDirectionMode direction) {
1578 return (direction == HorizontalLine ? box.size().height() 1616 return (direction == HorizontalLine ? box.size().height()
1579 : box.size().width()) 1617 : box.size().width())
1580 .toInt(); 1618 .toInt();
1581 } 1619 }
1582 1620
1583 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it might be
1584 // refactored somehow.
1585 int LayoutGrid::baselinePosition(FontBaseline, 1621 int LayoutGrid::baselinePosition(FontBaseline,
1586 bool, 1622 bool,
1587 LineDirectionMode direction, 1623 LineDirectionMode direction,
1588 LinePositionMode mode) const { 1624 LinePositionMode mode) const {
1589 DCHECK_EQ(mode, PositionOnContainingLine); 1625 DCHECK_EQ(mode, PositionOnContainingLine);
1590 int baseline = firstLineBoxBaseline(); 1626 int baseline = firstLineBoxBaseline();
1591 // We take content-box's bottom if no valid baseline. 1627 // We take content-box's bottom if no valid baseline.
1592 if (baseline == -1) 1628 if (baseline == -1)
1593 baseline = synthesizedBaselineFromContentBox(*this, direction); 1629 baseline = synthesizedBaselineFromContentBox(*this, direction);
1594 1630
1595 return baseline + beforeMarginInLineDirection(direction); 1631 return baseline + beforeMarginInLineDirection(direction);
1596 } 1632 }
1597 1633
1598 bool LayoutGrid::isInlineBaselineAlignedChild(const LayoutBox* child) const {
1599 return alignSelfForChild(*child).position() == ItemPositionBaseline &&
1600 !isOrthogonalChild(*child) && !hasAutoMarginsInColumnAxis(*child);
1601 }
1602
1603 int LayoutGrid::firstLineBoxBaseline() const { 1634 int LayoutGrid::firstLineBoxBaseline() const {
1604 if (isWritingModeRoot() || !m_grid.hasGridItems()) 1635 if (isWritingModeRoot() || !m_grid.hasGridItems())
1605 return -1; 1636 return -1;
1606 const LayoutBox* baselineChild = nullptr; 1637 const LayoutBox* baselineChild = nullptr;
1607 const LayoutBox* firstChild = nullptr; 1638 const LayoutBox* firstChild = nullptr;
1608 bool isBaselineAligned = false; 1639 bool isBaselineAligned = false;
1609 // Finding the first grid item in grid order. 1640 // Finding the first grid item in grid order.
1610 for (size_t column = 0; 1641 for (size_t column = 0;
1611 !isBaselineAligned && column < m_grid.numTracks(ForColumns); column++) { 1642 !isBaselineAligned && column < m_grid.numTracks(ForColumns); column++) {
1612 for (size_t index = 0; index < m_grid.cell(0, column).size(); index++) { 1643 for (size_t index = 0; index < m_grid.cell(0, column).size(); index++) {
1613 const LayoutBox* child = m_grid.cell(0, column)[index]; 1644 const LayoutBox* child = m_grid.cell(0, column)[index];
1614 DCHECK(!child->isOutOfFlowPositioned()); 1645 DCHECK(!child->isOutOfFlowPositioned());
1615 // If an item participates in baseline alignmen, we select such item. 1646 // If an item participates in baseline alignment, we select such item.
1616 if (isInlineBaselineAlignedChild(child)) { 1647 if (isBaselineAlignmentForChild(*child)) {
1617 // TODO (lajava): self-baseline and content-baseline alignment 1648 // TODO (lajava): self-baseline and content-baseline alignment
1618 // still not implemented. 1649 // still not implemented.
1619 baselineChild = child; 1650 baselineChild = child;
1620 isBaselineAligned = true; 1651 isBaselineAligned = true;
1621 break; 1652 break;
1622 } 1653 }
1623 if (!baselineChild) { 1654 if (!baselineChild) {
1624 // Use dom order for items in the same cell. 1655 // Use dom order for items in the same cell.
1625 if (!firstChild || (m_grid.gridItemPaintOrder(*child) < 1656 if (!firstChild || (m_grid.gridItemPaintOrder(*child) <
1626 m_grid.gridItemPaintOrder(*firstChild))) 1657 m_grid.gridItemPaintOrder(*firstChild)))
(...skipping 29 matching lines...) Expand all
1656 int LayoutGrid::inlineBlockBaseline(LineDirectionMode direction) const { 1687 int LayoutGrid::inlineBlockBaseline(LineDirectionMode direction) const {
1657 int baseline = firstLineBoxBaseline(); 1688 int baseline = firstLineBoxBaseline();
1658 if (baseline != -1) 1689 if (baseline != -1)
1659 return baseline; 1690 return baseline;
1660 1691
1661 int marginHeight = 1692 int marginHeight =
1662 (direction == HorizontalLine ? marginTop() : marginRight()).toInt(); 1693 (direction == HorizontalLine ? marginTop() : marginRight()).toInt();
1663 return synthesizedBaselineFromContentBox(*this, direction) + marginHeight; 1694 return synthesizedBaselineFromContentBox(*this, direction) + marginHeight;
1664 } 1695 }
1665 1696
1697 bool LayoutGrid::isHorizontalGridAxis(GridAxis axis) const {
1698 return axis == GridRowAxis ? isHorizontalWritingMode()
1699 : !isHorizontalWritingMode();
1700 }
1701
1702 bool LayoutGrid::isParallelToBlockAxisForChild(const LayoutBox& child,
1703 GridAxis axis) const {
1704 return axis == GridColumnAxis ? !isOrthogonalChild(child)
1705 : isOrthogonalChild(child);
1706 }
1707
1708 bool LayoutGrid::isDescentBaselineForChild(const LayoutBox& child,
1709 GridAxis baselineAxis) const {
1710 return isHorizontalGridAxis(baselineAxis) &&
1711 ((child.styleRef().isFlippedBlocksWritingMode() &&
1712 !styleRef().isFlippedBlocksWritingMode()) ||
1713 (child.styleRef().isFlippedLinesWritingMode() &&
1714 styleRef().isFlippedBlocksWritingMode()));
1715 }
1716
1717 bool LayoutGrid::isBaselineAlignmentForChild(const LayoutBox& child,
1718 GridAxis baselineAxis) const {
1719 bool isColumnAxisBaseline = baselineAxis == GridColumnAxis;
1720 ItemPosition align = isColumnAxisBaseline
1721 ? alignSelfForChild(child).position()
1722 : justifySelfForChild(child).position();
1723 bool hasAutoMargins = isColumnAxisBaseline ? hasAutoMarginsInColumnAxis(child)
1724 : hasAutoMarginsInRowAxis(child);
1725 return isBaselinePosition(align) && !hasAutoMargins;
1726 }
1727
1728 const BaselineGroup& LayoutGrid::getBaselineGroupForChild(
1729 const LayoutBox& child,
1730 GridAxis baselineAxis) const {
1731 DCHECK(isBaselineAlignmentForChild(child, baselineAxis));
1732 auto& grid = m_trackSizingAlgorithm.grid();
1733 bool isColumnAxisBaseline = baselineAxis == GridColumnAxis;
1734 bool isRowAxisContext = isColumnAxisBaseline;
1735 const auto& span = isRowAxisContext ? grid.gridItemSpan(child, ForRows)
1736 : grid.gridItemSpan(child, ForColumns);
1737 auto& contextsMap =
1738 isRowAxisContext ? m_rowAxisAlignmentContext : m_colAxisAlignmentContext;
1739 auto* context = contextsMap.at(span.startLine());
1740 DCHECK(context);
1741 ItemPosition align = isColumnAxisBaseline
1742 ? alignSelfForChild(child).position()
1743 : justifySelfForChild(child).position();
1744 return context->getSharedGroup(child, align);
1745 }
1746
1747 LayoutUnit LayoutGrid::marginOverForChild(const LayoutBox& child,
1748 GridAxis axis) const {
1749 return isHorizontalGridAxis(axis) ? child.marginRight() : child.marginTop();
1750 }
1751
1752 LayoutUnit LayoutGrid::marginUnderForChild(const LayoutBox& child,
1753 GridAxis axis) const {
1754 return isHorizontalGridAxis(axis) ? child.marginLeft() : child.marginBottom();
1755 }
1756
1757 LayoutUnit LayoutGrid::logicalAscentForChild(const LayoutBox& child,
1758 GridAxis baselineAxis) const {
1759 LayoutUnit ascent = ascentForChild(child, baselineAxis);
1760 return isDescentBaselineForChild(child, baselineAxis)
1761 ? descentForChild(child, ascent, baselineAxis)
1762 : ascent;
1763 }
1764
1765 LayoutUnit LayoutGrid::ascentForChild(const LayoutBox& child,
1766 GridAxis baselineAxis) const {
1767 LayoutUnit margin = isDescentBaselineForChild(child, baselineAxis)
1768 ? marginUnderForChild(child, baselineAxis)
1769 : marginOverForChild(child, baselineAxis);
1770 int baseline = isParallelToBlockAxisForChild(child, baselineAxis)
1771 ? child.firstLineBoxBaseline()
1772 : -1;
1773 // We take border-box's under edge if no valid baseline.
1774 if (baseline == -1) {
1775 if (isHorizontalGridAxis(baselineAxis)) {
1776 return styleRef().isFlippedBlocksWritingMode()
1777 ? child.size().width().toInt() + margin
1778 : margin;
1779 }
1780 return child.size().height() + margin;
1781 }
1782 return LayoutUnit(baseline) + margin;
1783 }
1784
1785 LayoutUnit LayoutGrid::descentForChild(const LayoutBox& child,
1786 LayoutUnit ascent,
1787 GridAxis baselineAxis) const {
1788 if (isParallelToBlockAxisForChild(child, baselineAxis))
1789 return child.marginLogicalHeight() + child.logicalHeight() - ascent;
1790 return child.marginLogicalWidth() + child.logicalWidth() - ascent;
1791 }
1792
1793 bool LayoutGrid::isBaselineContextComputed(GridAxis baselineAxis) const {
1794 return baselineAxis == GridColumnAxis ? !m_rowAxisAlignmentContext.isEmpty()
1795 : !m_colAxisAlignmentContext.isEmpty();
1796 }
1797
1798 bool LayoutGrid::baselineMayAffectIntrinsicWidth() const {
1799 if (!styleRef().logicalWidth().isIntrinsicOrAuto())
1800 return false;
1801 for (const auto& context : m_colAxisAlignmentContext) {
1802 for (const auto& group : context.value->sharedGroups()) {
1803 if (group.size() > 1)
1804 return true;
1805 }
1806 }
1807 return false;
1808 }
1809
1810 bool LayoutGrid::baselineMayAffectIntrinsicHeight() const {
1811 if (!styleRef().logicalHeight().isIntrinsicOrAuto())
1812 return false;
1813 for (const auto& context : m_rowAxisAlignmentContext) {
1814 for (const auto& group : context.value->sharedGroups()) {
1815 if (group.size() > 1)
1816 return true;
1817 }
1818 }
1819 return false;
1820 }
1821
1822 void LayoutGrid::computeBaselineAlignmentContext() {
1823 for (auto* child = firstInFlowChildBox(); child;
1824 child = child->nextInFlowSiblingBox()) {
1825 updateBaselineAlignmentContextIfNeeded(*child, GridRowAxis);
1826 updateBaselineAlignmentContextIfNeeded(*child, GridColumnAxis);
1827 }
1828 }
1829
1830 void LayoutGrid::updateBaselineAlignmentContextIfNeeded(LayoutBox& child,
1831 GridAxis baselineAxis) {
1832 // TODO (lajava): We must ensure this method is not called as part of an
1833 // intrinsic size computation.
1834 if (!isBaselineAlignmentForChild(child, baselineAxis))
1835 return;
1836
1837 child.layoutIfNeeded();
1838
1839 // Determine Ascent and Descent values of this child with respect to
1840 // its grid container.
1841 LayoutUnit ascent = ascentForChild(child, baselineAxis);
1842 LayoutUnit descent = descentForChild(child, ascent, baselineAxis);
1843 if (isDescentBaselineForChild(child, baselineAxis))
1844 std::swap(ascent, descent);
1845
1846 // Looking up for a shared alignment context perpendicular to the
1847 // baseline axis.
1848 auto& grid = m_trackSizingAlgorithm.grid();
1849 bool isColumnAxisBaseline = baselineAxis == GridColumnAxis;
1850 bool isRowAxisContext = isColumnAxisBaseline;
1851 const auto& span = isRowAxisContext ? grid.gridItemSpan(child, ForRows)
1852 : grid.gridItemSpan(child, ForColumns);
1853 auto& contextsMap =
1854 isRowAxisContext ? m_rowAxisAlignmentContext : m_colAxisAlignmentContext;
1855 auto addResult = contextsMap.insert(span.startLine(), nullptr);
1856
1857 // Looking for a compatible baseline-sharing group.
1858 ItemPosition align = isColumnAxisBaseline
1859 ? alignSelfForChild(child).position()
1860 : justifySelfForChild(child).position();
1861 if (addResult.isNewEntry) {
1862 addResult.storedValue->value =
1863 WTF::makeUnique<BaselineContext>(child, align, ascent, descent);
1864 } else {
1865 auto* context = addResult.storedValue->value.get();
1866 context->updateSharedGroup(child, align, ascent, descent);
1867 }
1868 }
1869
1870 LayoutUnit LayoutGrid::columnAxisBaselineOffsetForChild(
1871 const LayoutBox& child) const {
1872 if (!isBaselineAlignmentForChild(child, GridColumnAxis))
1873 return LayoutUnit();
1874 auto& group = getBaselineGroupForChild(child, GridColumnAxis);
1875 if (group.size() > 1)
1876 return group.maxAscent() - logicalAscentForChild(child, GridColumnAxis);
1877 return LayoutUnit();
1878 }
1879
1880 LayoutUnit LayoutGrid::rowAxisBaselineOffsetForChild(
1881 const LayoutBox& child) const {
1882 if (!isBaselineAlignmentForChild(child, GridRowAxis))
1883 return LayoutUnit();
1884 auto& group = getBaselineGroupForChild(child, GridRowAxis);
1885 if (group.size() > 1)
1886 return group.maxAscent() - logicalAscentForChild(child, GridRowAxis);
1887 return LayoutUnit();
1888 }
1889
1666 GridAxisPosition LayoutGrid::columnAxisPositionForChild( 1890 GridAxisPosition LayoutGrid::columnAxisPositionForChild(
1667 const LayoutBox& child) const { 1891 const LayoutBox& child) const {
1668 bool hasSameWritingMode = 1892 bool hasSameWritingMode =
1669 child.styleRef().getWritingMode() == styleRef().getWritingMode(); 1893 child.styleRef().getWritingMode() == styleRef().getWritingMode();
1670 bool childIsLTR = child.styleRef().isLeftToRightDirection(); 1894 bool childIsLTR = child.styleRef().isLeftToRightDirection();
1671 1895
1672 switch (alignSelfForChild(child).position()) { 1896 switch (alignSelfForChild(child).position()) {
1673 case ItemPositionSelfStart: 1897 case ItemPositionSelfStart:
1674 // TODO (lajava): Should we implement this logic in a generic utility 1898 // TODO (lajava): Should we implement this logic in a generic utility
1675 // function? 1899 // function?
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 // Only used in flex layout, otherwise equivalent to 'end'. 1949 // Only used in flex layout, otherwise equivalent to 'end'.
1726 case ItemPositionFlexEnd: 1950 case ItemPositionFlexEnd:
1727 // Aligns the alignment subject to be flush with the alignment container's 1951 // Aligns the alignment subject to be flush with the alignment container's
1728 // 'end' edge (block-end) in the column axis. 1952 // 'end' edge (block-end) in the column axis.
1729 case ItemPositionEnd: 1953 case ItemPositionEnd:
1730 return GridAxisEnd; 1954 return GridAxisEnd;
1731 case ItemPositionStretch: 1955 case ItemPositionStretch:
1732 return GridAxisStart; 1956 return GridAxisStart;
1733 case ItemPositionBaseline: 1957 case ItemPositionBaseline:
1734 case ItemPositionLastBaseline: 1958 case ItemPositionLastBaseline:
1735 // FIXME: These two require implementing Baseline Alignment. For now, we
1736 // always 'start' align the child. crbug.com/234191
1737 return GridAxisStart; 1959 return GridAxisStart;
1738 case ItemPositionAuto: 1960 case ItemPositionAuto:
1739 case ItemPositionNormal: 1961 case ItemPositionNormal:
1740 break; 1962 break;
1741 } 1963 }
1742 1964
1743 NOTREACHED(); 1965 NOTREACHED();
1744 return GridAxisStart; 1966 return GridAxisStart;
1745 } 1967 }
1746 1968
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 // Only used in flex layout, otherwise equivalent to 'end'. 2026 // Only used in flex layout, otherwise equivalent to 'end'.
1805 case ItemPositionFlexEnd: 2027 case ItemPositionFlexEnd:
1806 // Aligns the alignment subject to be flush with the alignment container's 2028 // Aligns the alignment subject to be flush with the alignment container's
1807 // 'end' edge (inline-end) in the row axis. 2029 // 'end' edge (inline-end) in the row axis.
1808 case ItemPositionEnd: 2030 case ItemPositionEnd:
1809 return GridAxisEnd; 2031 return GridAxisEnd;
1810 case ItemPositionStretch: 2032 case ItemPositionStretch:
1811 return GridAxisStart; 2033 return GridAxisStart;
1812 case ItemPositionBaseline: 2034 case ItemPositionBaseline:
1813 case ItemPositionLastBaseline: 2035 case ItemPositionLastBaseline:
1814 // FIXME: These two require implementing Baseline Alignment. For now, we
1815 // always 'start' align the child. crbug.com/234191
1816 return GridAxisStart; 2036 return GridAxisStart;
1817 case ItemPositionAuto: 2037 case ItemPositionAuto:
1818 case ItemPositionNormal: 2038 case ItemPositionNormal:
1819 break; 2039 break;
1820 } 2040 }
1821 2041
1822 NOTREACHED(); 2042 NOTREACHED();
1823 return GridAxisStart; 2043 return GridAxisStart;
1824 } 2044 }
1825 2045
1826 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const { 2046 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const {
1827 const GridSpan& rowsSpan = 2047 const GridSpan& rowsSpan =
1828 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForRows); 2048 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForRows);
1829 size_t childStartLine = rowsSpan.startLine(); 2049 size_t childStartLine = rowsSpan.startLine();
1830 LayoutUnit startOfRow = m_rowPositions[childStartLine]; 2050 LayoutUnit startOfRow = m_rowPositions[childStartLine];
1831 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 2051 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
1832 if (hasAutoMarginsInColumnAxis(child)) 2052 if (hasAutoMarginsInColumnAxis(child))
1833 return startPosition; 2053 return startPosition;
1834 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 2054 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
1835 switch (axisPosition) { 2055 switch (axisPosition) {
1836 case GridAxisStart: 2056 case GridAxisStart:
1837 return startPosition; 2057 return startPosition + columnAxisBaselineOffsetForChild(child);
1838 case GridAxisEnd: 2058 case GridAxisEnd:
1839 case GridAxisCenter: { 2059 case GridAxisCenter: {
1840 size_t childEndLine = rowsSpan.endLine(); 2060 size_t childEndLine = rowsSpan.endLine();
1841 LayoutUnit endOfRow = m_rowPositions[childEndLine]; 2061 LayoutUnit endOfRow = m_rowPositions[childEndLine];
1842 // m_rowPositions include distribution offset (because of content 2062 // m_rowPositions include distribution offset (because of content
1843 // alignment) and gutters so we need to subtract them to get the actual 2063 // alignment) and gutters so we need to subtract them to get the actual
1844 // end position for a given row (this does not have to be done for the 2064 // end position for a given row (this does not have to be done for the
1845 // last track as there are no more m_columnPositions after it). 2065 // last track as there are no more m_columnPositions after it).
1846 LayoutUnit trackGap = gridGapForDirection(ForRows, TrackSizing); 2066 LayoutUnit trackGap = gridGapForDirection(ForRows, TrackSizing);
1847 if (childEndLine < m_rowPositions.size() - 1) { 2067 if (childEndLine < m_rowPositions.size() - 1) {
(...skipping 21 matching lines...) Expand all
1869 const GridSpan& columnsSpan = 2089 const GridSpan& columnsSpan =
1870 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForColumns); 2090 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForColumns);
1871 size_t childStartLine = columnsSpan.startLine(); 2091 size_t childStartLine = columnsSpan.startLine();
1872 LayoutUnit startOfColumn = m_columnPositions[childStartLine]; 2092 LayoutUnit startOfColumn = m_columnPositions[childStartLine];
1873 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 2093 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
1874 if (hasAutoMarginsInRowAxis(child)) 2094 if (hasAutoMarginsInRowAxis(child))
1875 return startPosition; 2095 return startPosition;
1876 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 2096 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
1877 switch (axisPosition) { 2097 switch (axisPosition) {
1878 case GridAxisStart: 2098 case GridAxisStart:
1879 return startPosition; 2099 return startPosition + rowAxisBaselineOffsetForChild(child);
1880 case GridAxisEnd: 2100 case GridAxisEnd:
1881 case GridAxisCenter: { 2101 case GridAxisCenter: {
1882 size_t childEndLine = columnsSpan.endLine(); 2102 size_t childEndLine = columnsSpan.endLine();
1883 LayoutUnit endOfColumn = m_columnPositions[childEndLine]; 2103 LayoutUnit endOfColumn = m_columnPositions[childEndLine];
1884 // m_columnPositions include distribution offset (because of content 2104 // m_columnPositions include distribution offset (because of content
1885 // alignment) and gutters so we need to subtract them to get the actual 2105 // alignment) and gutters so we need to subtract them to get the actual
1886 // end position for a given column (this does not have to be done for the 2106 // end position for a given column (this does not have to be done for the
1887 // last track as there are no more m_columnPositions after it). 2107 // last track as there are no more m_columnPositions after it).
1888 LayoutUnit trackGap = gridGapForDirection(ForColumns, TrackSizing); 2108 LayoutUnit trackGap = gridGapForDirection(ForColumns, TrackSizing);
1889 if (childEndLine < m_columnPositions.size() - 1) { 2109 if (childEndLine < m_columnPositions.size() - 1) {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 if (direction == ForRows) 2323 if (direction == ForRows)
2104 return grid.numTracks(ForRows); 2324 return grid.numTracks(ForRows);
2105 2325
2106 return grid.numTracks(ForRows) 2326 return grid.numTracks(ForRows)
2107 ? grid.numTracks(ForColumns) 2327 ? grid.numTracks(ForColumns)
2108 : GridPositionsResolver::explicitGridColumnCount( 2328 : GridPositionsResolver::explicitGridColumnCount(
2109 styleRef(), grid.autoRepeatTracks(ForColumns)); 2329 styleRef(), grid.autoRepeatTracks(ForColumns));
2110 } 2330 }
2111 2331
2112 } // namespace blink 2332 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698