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

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: Do no update the intrinsic size. Created 3 years, 9 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();
svillar 2017/03/24 10:52:05 Nit: no need for a variable here, we just use this
jfernandez 2017/03/24 14:15:18 Well, I admit it's not strictly necessary but IMHO
175 // TODO (lajava): orthogonal flows is just one of the cases which may require 183
184 bool intrinsicWidthMayHaveChanged =
185 baselineAffectIntrinsicWidth || hasAnyOrthogonal;
186 if (!intrinsicWidthMayHaveChanged && !baselineAffectIntrinsicHeight)
187 return;
188
189 // 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 190 // 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 191 // 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 192 // more specific condition to detect whether child's min-content contribution
179 // has changed or not. 193 // has changed or not.
180 if (m_grid.hasAnyOrthogonalGridItem()) { 194 if (!intrinsicWidthMayHaveChanged && !baselineAffectIntrinsicHeight)
181 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns); 195 return;
182 computeTrackSizesForDefiniteSize(ForRows, availableSpaceForRows); 196
197 // TODO (lajava): Whenever the min-content contribution of a grid item changes
198 // we may need to update the grid container's intrinsic width. The new
199 // intrinsic width may also affect the extra Track Sizing algorithm cycles we
200 // are about to execute.
201 // https://crbug.com/704713
202 // https://github.com/w3c/csswg-drafts/issues/1039
203
204 // Hence we need to repeat computeUsedBreadthOfGridTracks for both, columns
205 // and rows, to determine the final values.
206 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
207 computeTrackSizesForDefiniteSize(ForRows, availableSpaceForRows);
208
209 if (baselineAffectIntrinsicHeight) {
210 setLogicalHeight(computeTrackBasedLogicalHeight() +
211 borderAndPaddingLogicalHeight() +
212 scrollbarLogicalHeight());
183 } 213 }
184 } 214 }
185 215
186 void LayoutGrid::layoutBlock(bool relayoutChildren) { 216 void LayoutGrid::layoutBlock(bool relayoutChildren) {
187 ASSERT(needsLayout()); 217 ASSERT(needsLayout());
188 218
189 // We cannot perform a simplifiedLayout() on a dirty grid that 219 // We cannot perform a simplifiedLayout() on a dirty grid that
190 // has positioned items to be laid out. 220 // has positioned items to be laid out.
191 if (!relayoutChildren && 221 if (!relayoutChildren &&
192 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) && 222 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) &&
193 simplifiedLayout()) 223 simplifiedLayout())
194 return; 224 return;
195 225
226 m_rowAxisAlignmentContext.clear();
227 m_colAxisAlignmentContext.clear();
228
196 SubtreeLayoutScope layoutScope(*this); 229 SubtreeLayoutScope layoutScope(*this);
197 230
198 { 231 {
199 // LayoutState needs this deliberate scope to pop before updating scroll 232 // LayoutState needs this deliberate scope to pop before updating scroll
200 // information (which may trigger relayout). 233 // information (which may trigger relayout).
201 LayoutState state(*this); 234 LayoutState state(*this);
202 235
203 LayoutSize previousSize = size(); 236 LayoutSize previousSize = size();
204 237
205 // We need to clear both own and containingBlock override sizes to 238 // 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(); 285 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
253 updateLogicalHeight(); 286 updateLogicalHeight();
254 287
255 // Once grid's indefinite height is resolved, we can compute the 288 // Once grid's indefinite height is resolved, we can compute the
256 // available free space for Content Alignment. 289 // available free space for Content Alignment.
257 if (!cachedHasDefiniteLogicalHeight()) { 290 if (!cachedHasDefiniteLogicalHeight()) {
258 m_trackSizingAlgorithm.freeSpace(ForRows) = 291 m_trackSizingAlgorithm.freeSpace(ForRows) =
259 logicalHeight() - trackBasedLogicalHeight; 292 logicalHeight() - trackBasedLogicalHeight;
260 } 293 }
261 294
295 // TODO (lajava): We need to compute baselines after step 2 so
296 // items with a relative size (percentages) can resolve it before
297 // determining its baseline. However, we only set item's grid area
298 // (via override sizes) as part of the content-sized tracks sizing
299 // logic. Hence, items located at fixed or flexible tracks can't
300 // resolve correctly their size at this stage, which may lead to
301 // an incorrect computation of their shared context's baseline.
302 computeBaselineAlignmentContext();
svillar 2017/03/24 10:52:05 I have just realized that we do this before applyi
jfernandez 2017/03/24 14:15:18 Yes, indeed. It's a really good point and I admit
303
262 // 3- If the min-content contribution of any grid items have changed based 304 // 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 305 // on the row sizes calculated in step 2, steps 1 and 2 are repeated with
264 // the new min-content contribution (once only). 306 // the new min-content contribution (once only).
265 repeatTracksSizingIfNeeded(availableSpaceForColumns, 307 repeatTracksSizingIfNeeded(availableSpaceForColumns,
266 contentLogicalHeight()); 308 contentLogicalHeight());
267 309
268 // Grid container should have the minimum height of a line if it's editable. 310 // Grid container should have the minimum height of a line if it's editable.
269 // That doesn't affect track sizing though. 311 // That doesn't affect track sizing though.
270 if (hasLineIfEmpty()) 312 if (hasLineIfEmpty())
271 setLogicalHeight( 313 setLogicalHeight(
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 .toInt(); 1615 .toInt();
1574 } 1616 }
1575 1617
1576 static int synthesizedBaselineFromBorderBox(const LayoutBox& box, 1618 static int synthesizedBaselineFromBorderBox(const LayoutBox& box,
1577 LineDirectionMode direction) { 1619 LineDirectionMode direction) {
1578 return (direction == HorizontalLine ? box.size().height() 1620 return (direction == HorizontalLine ? box.size().height()
1579 : box.size().width()) 1621 : box.size().width())
1580 .toInt(); 1622 .toInt();
1581 } 1623 }
1582 1624
1583 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it might be
1584 // refactored somehow.
1585 int LayoutGrid::baselinePosition(FontBaseline, 1625 int LayoutGrid::baselinePosition(FontBaseline,
1586 bool, 1626 bool,
1587 LineDirectionMode direction, 1627 LineDirectionMode direction,
1588 LinePositionMode mode) const { 1628 LinePositionMode mode) const {
1589 DCHECK_EQ(mode, PositionOnContainingLine); 1629 DCHECK_EQ(mode, PositionOnContainingLine);
1590 int baseline = firstLineBoxBaseline(); 1630 int baseline = firstLineBoxBaseline();
1591 // We take content-box's bottom if no valid baseline. 1631 // We take content-box's bottom if no valid baseline.
1592 if (baseline == -1) 1632 if (baseline == -1)
1593 baseline = synthesizedBaselineFromContentBox(*this, direction); 1633 baseline = synthesizedBaselineFromContentBox(*this, direction);
1594 1634
1595 return baseline + beforeMarginInLineDirection(direction); 1635 return baseline + beforeMarginInLineDirection(direction);
1596 } 1636 }
1597 1637
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 { 1638 int LayoutGrid::firstLineBoxBaseline() const {
1604 if (isWritingModeRoot() || !m_grid.hasGridItems()) 1639 if (isWritingModeRoot() || !m_grid.hasGridItems())
1605 return -1; 1640 return -1;
1606 const LayoutBox* baselineChild = nullptr; 1641 const LayoutBox* baselineChild = nullptr;
1607 const LayoutBox* firstChild = nullptr; 1642 const LayoutBox* firstChild = nullptr;
1608 bool isBaselineAligned = false; 1643 bool isBaselineAligned = false;
1609 // Finding the first grid item in grid order. 1644 // Finding the first grid item in grid order.
1610 for (size_t column = 0; 1645 for (size_t column = 0;
1611 !isBaselineAligned && column < m_grid.numTracks(ForColumns); column++) { 1646 !isBaselineAligned && column < m_grid.numTracks(ForColumns); column++) {
1612 for (size_t index = 0; index < m_grid.cell(0, column).size(); index++) { 1647 for (size_t index = 0; index < m_grid.cell(0, column).size(); index++) {
1613 const LayoutBox* child = m_grid.cell(0, column)[index]; 1648 const LayoutBox* child = m_grid.cell(0, column)[index];
1614 DCHECK(!child->isOutOfFlowPositioned()); 1649 DCHECK(!child->isOutOfFlowPositioned());
1615 // If an item participates in baseline alignmen, we select such item. 1650 // If an item participates in baseline alignment, we select such item.
1616 if (isInlineBaselineAlignedChild(child)) { 1651 if (isBaselineAlignmentForChild(*child)) {
1617 // TODO (lajava): self-baseline and content-baseline alignment 1652 // TODO (lajava): self-baseline and content-baseline alignment
1618 // still not implemented. 1653 // still not implemented.
1619 baselineChild = child; 1654 baselineChild = child;
1620 isBaselineAligned = true; 1655 isBaselineAligned = true;
1621 break; 1656 break;
1622 } 1657 }
1623 if (!baselineChild) { 1658 if (!baselineChild) {
1624 // Use dom order for items in the same cell. 1659 // Use dom order for items in the same cell.
1625 if (!firstChild || (m_grid.gridItemPaintOrder(*child) < 1660 if (!firstChild || (m_grid.gridItemPaintOrder(*child) <
1626 m_grid.gridItemPaintOrder(*firstChild))) 1661 m_grid.gridItemPaintOrder(*firstChild)))
(...skipping 29 matching lines...) Expand all
1656 int LayoutGrid::inlineBlockBaseline(LineDirectionMode direction) const { 1691 int LayoutGrid::inlineBlockBaseline(LineDirectionMode direction) const {
1657 int baseline = firstLineBoxBaseline(); 1692 int baseline = firstLineBoxBaseline();
1658 if (baseline != -1) 1693 if (baseline != -1)
1659 return baseline; 1694 return baseline;
1660 1695
1661 int marginHeight = 1696 int marginHeight =
1662 (direction == HorizontalLine ? marginTop() : marginRight()).toInt(); 1697 (direction == HorizontalLine ? marginTop() : marginRight()).toInt();
1663 return synthesizedBaselineFromContentBox(*this, direction) + marginHeight; 1698 return synthesizedBaselineFromContentBox(*this, direction) + marginHeight;
1664 } 1699 }
1665 1700
1701 bool LayoutGrid::isHorizontalGridAxis(GridAxis axis) const {
1702 return axis == GridRowAxis ? isHorizontalWritingMode()
1703 : !isHorizontalWritingMode();
1704 }
1705
1706 bool LayoutGrid::isParallelToBlockAxisForChild(const LayoutBox& child,
1707 GridAxis axis) const {
1708 return axis == GridColumnAxis ? !isOrthogonalChild(child)
1709 : isOrthogonalChild(child);
1710 }
1711
1712 bool LayoutGrid::isDescentBaselineForChild(const LayoutBox& child,
1713 GridAxis baselineAxis) const {
1714 return isHorizontalGridAxis(baselineAxis) &&
1715 !styleRef().isFlippedBlocksWritingMode();
1716 }
1717
1718 bool LayoutGrid::isBaselineAlignmentForChild(const LayoutBox& child,
1719 GridAxis baselineAxis) const {
1720 bool isColumnAxisBaseline = baselineAxis == GridColumnAxis;
1721 ItemPosition align = isColumnAxisBaseline
1722 ? alignSelfForChild(child).position()
1723 : justifySelfForChild(child).position();
1724 bool hasAutoMargins = isColumnAxisBaseline ? hasAutoMarginsInColumnAxis(child)
1725 : hasAutoMarginsInRowAxis(child);
1726 return isBaselinePosition(align) && !hasAutoMargins;
1727 }
svillar 2017/03/24 10:52:05 I wonder if these four utility methods could be pa
jfernandez 2017/03/24 14:15:18 Yeah, I wondered the same and actually tried to mo
1728
1729 const BaselineGroup& LayoutGrid::getBaselineGroupForChild(
1730 const LayoutBox& child,
1731 GridAxis baselineAxis) const {
1732 DCHECK(isBaselineAlignmentForChild(child, baselineAxis));
1733 auto& grid = m_trackSizingAlgorithm.grid();
1734 bool isColumnAxisBaseline = baselineAxis == GridColumnAxis;
1735 bool isRowAxisContext = isColumnAxisBaseline;
1736 const auto& span = isRowAxisContext ? grid.gridItemSpan(child, ForRows)
1737 : grid.gridItemSpan(child, ForColumns);
1738 auto& contextsMap =
1739 isRowAxisContext ? m_rowAxisAlignmentContext : m_colAxisAlignmentContext;
1740 auto* context = contextsMap.at(span.startLine());
1741 DCHECK(context);
1742 ItemPosition align = isColumnAxisBaseline
1743 ? alignSelfForChild(child).position()
1744 : justifySelfForChild(child).position();
1745 return context->getSharedGroup(child, align);
1746 }
1747
1748 LayoutUnit LayoutGrid::marginOverForChild(const LayoutBox& child,
1749 GridAxis axis) const {
1750 return isHorizontalGridAxis(axis) ? child.marginRight() : child.marginTop();
1751 }
1752
1753 LayoutUnit LayoutGrid::logicalAscentForChild(const LayoutBox& child,
1754 GridAxis baselineAxis) const {
1755 LayoutUnit ascent = ascentForChild(child, baselineAxis);
1756 return isDescentBaselineForChild(child, baselineAxis)
1757 ? descentForChild(child, ascent, baselineAxis)
1758 : ascent;
1759 }
1760
1761 LayoutUnit LayoutGrid::ascentForChild(const LayoutBox& child,
1762 GridAxis baselineAxis) const {
1763 int baseline = isParallelToBlockAxisForChild(child, baselineAxis)
1764 ? child.firstLineBoxBaseline()
1765 : -1;
1766 // We take border-box's bottom if no valid baseline.
1767 if (baseline == -1) {
1768 baseline = isHorizontalGridAxis(baselineAxis)
1769 ? child.size().width().toInt()
1770 : child.size().height().toInt();
1771 }
1772 return LayoutUnit(baseline) + marginOverForChild(child, baselineAxis);
1773 }
1774
1775 LayoutUnit LayoutGrid::descentForChild(const LayoutBox& child,
1776 LayoutUnit ascent,
1777 GridAxis baselineAxis) const {
1778 if (isParallelToBlockAxisForChild(child, baselineAxis))
1779 return child.marginLogicalHeight() + child.logicalHeight() - ascent;
1780 return child.marginLogicalWidth() + child.logicalWidth() - ascent;
1781 }
1782
1783 bool LayoutGrid::isBaselineContextComputed(GridAxis baselineAxis) const {
1784 return baselineAxis == GridColumnAxis ? !m_rowAxisAlignmentContext.isEmpty()
1785 : !m_colAxisAlignmentContext.isEmpty();
1786 }
1787
svillar 2017/03/24 10:52:05 Same question here for the above 5 methods. Do you
jfernandez 2017/03/24 14:15:18 Already explained before, but I'd definitively lik
1788 bool LayoutGrid::baselineMayAffectIntrinsicWidth() const {
1789 if (!styleRef().logicalWidth().isIntrinsicOrAuto())
1790 return false;
1791 for (const auto& context : m_colAxisAlignmentContext) {
1792 for (const auto& group : context.value->sharedGroups()) {
1793 if (group.size() > 1)
1794 return true;
1795 }
1796 }
1797 return false;
1798 }
1799
1800 bool LayoutGrid::baselineMayAffectIntrinsicHeight() const {
1801 if (!styleRef().logicalHeight().isIntrinsicOrAuto())
1802 return false;
1803 for (const auto& context : m_rowAxisAlignmentContext) {
1804 for (const auto& group : context.value->sharedGroups()) {
1805 if (group.size() > 1)
1806 return true;
1807 }
1808 }
1809 return false;
1810 }
1811
1812 void LayoutGrid::computeBaselineAlignmentContext() {
1813 for (auto* child = firstInFlowChildBox(); child;
1814 child = child->nextInFlowSiblingBox()) {
1815 updateBaselineAlignmentContextIfNeeded(*child, GridRowAxis);
1816 updateBaselineAlignmentContextIfNeeded(*child, GridColumnAxis);
1817 }
1818 }
1819
1820 void LayoutGrid::updateBaselineAlignmentContextIfNeeded(LayoutBox& child,
1821 GridAxis baselineAxis) {
1822 // DCHECK(m_trackSizingAlgorithm.isTrackSizingOperation());
svillar 2017/03/24 10:52:05 Remove this check if it does not apply.
jfernandez 2017/03/24 14:15:18 Well, I'd like to have this check. However, unfort
1823 if (!isBaselineAlignmentForChild(child, baselineAxis))
1824 return;
1825
1826 child.layoutIfNeeded();
1827
1828 // Determine Ascent and Descent values of this child with respect to
1829 // its grid container.
1830 LayoutUnit ascent = ascentForChild(child, baselineAxis);
1831 LayoutUnit descent = descentForChild(child, ascent, baselineAxis);
1832 if (isDescentBaselineForChild(child, baselineAxis))
1833 std::swap(ascent, descent);
1834
1835 // Looking up for a shared alignment context perpendicular to the
1836 // baseline axis.
1837 auto& grid = m_trackSizingAlgorithm.grid();
1838 bool isColumnAxisBaseline = baselineAxis == GridColumnAxis;
1839 bool isRowAxisContext = isColumnAxisBaseline;
1840 const auto& span = isRowAxisContext ? grid.gridItemSpan(child, ForRows)
1841 : grid.gridItemSpan(child, ForColumns);
1842 auto& contextsMap =
1843 isRowAxisContext ? m_rowAxisAlignmentContext : m_colAxisAlignmentContext;
1844 auto addResult = contextsMap.insert(span.startLine(), nullptr);
1845
1846 // Looking for a compatible baseline-sharing group.
1847 ItemPosition align = isColumnAxisBaseline
1848 ? alignSelfForChild(child).position()
1849 : justifySelfForChild(child).position();
1850 if (addResult.isNewEntry) {
1851 addResult.storedValue->value =
1852 WTF::makeUnique<BaselineContext>(child, align, ascent, descent);
1853 } else {
1854 auto* context = addResult.storedValue->value.get();
1855 context->updateSharedGroup(child, align, ascent, descent);
1856 }
1857 }
1858
1859 LayoutUnit LayoutGrid::columnAxisBaselineOffsetForChild(
1860 const LayoutBox& child) const {
1861 if (!isBaselineAlignmentForChild(child, GridColumnAxis))
1862 return LayoutUnit();
1863 auto& group = getBaselineGroupForChild(child, GridColumnAxis);
1864 if (group.size() > 1)
1865 return group.maxAscent() - logicalAscentForChild(child, GridColumnAxis);
1866 return LayoutUnit();
1867 }
1868
1869 LayoutUnit LayoutGrid::rowAxisBaselineOffsetForChild(
1870 const LayoutBox& child) const {
1871 if (!isBaselineAlignmentForChild(child, GridRowAxis))
1872 return LayoutUnit();
1873 auto& group = getBaselineGroupForChild(child, GridRowAxis);
1874 if (group.size() > 1)
1875 return group.maxAscent() - logicalAscentForChild(child, GridRowAxis);
1876 return LayoutUnit();
1877 }
1878
1666 GridAxisPosition LayoutGrid::columnAxisPositionForChild( 1879 GridAxisPosition LayoutGrid::columnAxisPositionForChild(
1667 const LayoutBox& child) const { 1880 const LayoutBox& child) const {
1668 bool hasSameWritingMode = 1881 bool hasSameWritingMode =
1669 child.styleRef().getWritingMode() == styleRef().getWritingMode(); 1882 child.styleRef().getWritingMode() == styleRef().getWritingMode();
1670 bool childIsLTR = child.styleRef().isLeftToRightDirection(); 1883 bool childIsLTR = child.styleRef().isLeftToRightDirection();
1671 1884
1672 switch (alignSelfForChild(child).position()) { 1885 switch (alignSelfForChild(child).position()) {
1673 case ItemPositionSelfStart: 1886 case ItemPositionSelfStart:
1674 // TODO (lajava): Should we implement this logic in a generic utility 1887 // TODO (lajava): Should we implement this logic in a generic utility
1675 // function? 1888 // function?
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 // Only used in flex layout, otherwise equivalent to 'end'. 1938 // Only used in flex layout, otherwise equivalent to 'end'.
1726 case ItemPositionFlexEnd: 1939 case ItemPositionFlexEnd:
1727 // Aligns the alignment subject to be flush with the alignment container's 1940 // Aligns the alignment subject to be flush with the alignment container's
1728 // 'end' edge (block-end) in the column axis. 1941 // 'end' edge (block-end) in the column axis.
1729 case ItemPositionEnd: 1942 case ItemPositionEnd:
1730 return GridAxisEnd; 1943 return GridAxisEnd;
1731 case ItemPositionStretch: 1944 case ItemPositionStretch:
1732 return GridAxisStart; 1945 return GridAxisStart;
1733 case ItemPositionBaseline: 1946 case ItemPositionBaseline:
1734 case ItemPositionLastBaseline: 1947 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; 1948 return GridAxisStart;
1738 case ItemPositionAuto: 1949 case ItemPositionAuto:
1739 case ItemPositionNormal: 1950 case ItemPositionNormal:
1740 break; 1951 break;
1741 } 1952 }
1742 1953
1743 ASSERT_NOT_REACHED(); 1954 ASSERT_NOT_REACHED();
1744 return GridAxisStart; 1955 return GridAxisStart;
1745 } 1956 }
1746 1957
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 // Only used in flex layout, otherwise equivalent to 'end'. 2015 // Only used in flex layout, otherwise equivalent to 'end'.
1805 case ItemPositionFlexEnd: 2016 case ItemPositionFlexEnd:
1806 // Aligns the alignment subject to be flush with the alignment container's 2017 // Aligns the alignment subject to be flush with the alignment container's
1807 // 'end' edge (inline-end) in the row axis. 2018 // 'end' edge (inline-end) in the row axis.
1808 case ItemPositionEnd: 2019 case ItemPositionEnd:
1809 return GridAxisEnd; 2020 return GridAxisEnd;
1810 case ItemPositionStretch: 2021 case ItemPositionStretch:
1811 return GridAxisStart; 2022 return GridAxisStart;
1812 case ItemPositionBaseline: 2023 case ItemPositionBaseline:
1813 case ItemPositionLastBaseline: 2024 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; 2025 return GridAxisStart;
1817 case ItemPositionAuto: 2026 case ItemPositionAuto:
1818 case ItemPositionNormal: 2027 case ItemPositionNormal:
1819 break; 2028 break;
1820 } 2029 }
1821 2030
1822 ASSERT_NOT_REACHED(); 2031 ASSERT_NOT_REACHED();
1823 return GridAxisStart; 2032 return GridAxisStart;
1824 } 2033 }
1825 2034
1826 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const { 2035 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const {
1827 const GridSpan& rowsSpan = 2036 const GridSpan& rowsSpan =
1828 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForRows); 2037 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForRows);
1829 size_t childStartLine = rowsSpan.startLine(); 2038 size_t childStartLine = rowsSpan.startLine();
1830 LayoutUnit startOfRow = m_rowPositions[childStartLine]; 2039 LayoutUnit startOfRow = m_rowPositions[childStartLine];
1831 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 2040 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
1832 if (hasAutoMarginsInColumnAxis(child)) 2041 if (hasAutoMarginsInColumnAxis(child))
1833 return startPosition; 2042 return startPosition;
1834 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 2043 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
1835 switch (axisPosition) { 2044 switch (axisPosition) {
1836 case GridAxisStart: 2045 case GridAxisStart:
1837 return startPosition; 2046 return startPosition + columnAxisBaselineOffsetForChild(child);
1838 case GridAxisEnd: 2047 case GridAxisEnd:
1839 case GridAxisCenter: { 2048 case GridAxisCenter: {
1840 size_t childEndLine = rowsSpan.endLine(); 2049 size_t childEndLine = rowsSpan.endLine();
1841 LayoutUnit endOfRow = m_rowPositions[childEndLine]; 2050 LayoutUnit endOfRow = m_rowPositions[childEndLine];
1842 // m_rowPositions include distribution offset (because of content 2051 // m_rowPositions include distribution offset (because of content
1843 // alignment) and gutters so we need to subtract them to get the actual 2052 // 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 2053 // 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). 2054 // last track as there are no more m_columnPositions after it).
1846 LayoutUnit trackGap = gridGapForDirection(ForRows, TrackSizing); 2055 LayoutUnit trackGap = gridGapForDirection(ForRows, TrackSizing);
1847 if (childEndLine < m_rowPositions.size() - 1) { 2056 if (childEndLine < m_rowPositions.size() - 1) {
(...skipping 21 matching lines...) Expand all
1869 const GridSpan& columnsSpan = 2078 const GridSpan& columnsSpan =
1870 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForColumns); 2079 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForColumns);
1871 size_t childStartLine = columnsSpan.startLine(); 2080 size_t childStartLine = columnsSpan.startLine();
1872 LayoutUnit startOfColumn = m_columnPositions[childStartLine]; 2081 LayoutUnit startOfColumn = m_columnPositions[childStartLine];
1873 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 2082 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
1874 if (hasAutoMarginsInRowAxis(child)) 2083 if (hasAutoMarginsInRowAxis(child))
1875 return startPosition; 2084 return startPosition;
1876 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 2085 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
1877 switch (axisPosition) { 2086 switch (axisPosition) {
1878 case GridAxisStart: 2087 case GridAxisStart:
1879 return startPosition; 2088 return startPosition + rowAxisBaselineOffsetForChild(child);
1880 case GridAxisEnd: 2089 case GridAxisEnd:
1881 case GridAxisCenter: { 2090 case GridAxisCenter: {
1882 size_t childEndLine = columnsSpan.endLine(); 2091 size_t childEndLine = columnsSpan.endLine();
1883 LayoutUnit endOfColumn = m_columnPositions[childEndLine]; 2092 LayoutUnit endOfColumn = m_columnPositions[childEndLine];
1884 // m_columnPositions include distribution offset (because of content 2093 // m_columnPositions include distribution offset (because of content
1885 // alignment) and gutters so we need to subtract them to get the actual 2094 // 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 2095 // 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). 2096 // last track as there are no more m_columnPositions after it).
1888 LayoutUnit trackGap = gridGapForDirection(ForColumns, TrackSizing); 2097 LayoutUnit trackGap = gridGapForDirection(ForColumns, TrackSizing);
1889 if (childEndLine < m_columnPositions.size() - 1) { 2098 if (childEndLine < m_columnPositions.size() - 1) {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 if (direction == ForRows) 2312 if (direction == ForRows)
2104 return grid.numTracks(ForRows); 2313 return grid.numTracks(ForRows);
2105 2314
2106 return grid.numTracks(ForRows) 2315 return grid.numTracks(ForRows)
2107 ? grid.numTracks(ForColumns) 2316 ? grid.numTracks(ForColumns)
2108 : GridPositionsResolver::explicitGridColumnCount( 2317 : GridPositionsResolver::explicitGridColumnCount(
2109 styleRef(), grid.autoRepeatTracks(ForColumns)); 2318 styleRef(), grid.autoRepeatTracks(ForColumns));
2110 } 2319 }
2111 2320
2112 } // namespace blink 2321 } // 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