Changeset 292973 in webkit
- Timestamp:
- Apr 18, 2022 2:44:04 PM (3 months ago)
- Location:
- trunk
- Files:
-
- 8 added
- 8 edited
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-001-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-001.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-002-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-002.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-003-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-003.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-004-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-baseline-004.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/rendering/GridBaselineAlignment.cpp (modified) (8 diffs)
-
Source/WebCore/rendering/GridBaselineAlignment.h (modified) (4 diffs)
-
Source/WebCore/rendering/GridLayoutFunctions.h (modified) (1 diff)
-
Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp (modified) (4 diffs)
-
Source/WebCore/rendering/GridTrackSizingAlgorithm.h (modified) (1 diff)
-
Source/WebCore/rendering/RenderGrid.cpp (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/imported/w3c/ChangeLog
r292953 r292973 1 2022-04-18 Matt Woodrow <mattwoodrow@apple.com> 2 3 Implement support for aligning baselines through subgrids 4 https://bugs.webkit.org/show_bug.cgi?id=238643 5 6 Reviewed by Javier Fernandez. 7 8 * web-platform-tests/css/css-grid/subgrid/baseline-002-expected.html: Added. 9 * web-platform-tests/css/css-grid/subgrid/baseline-002.html: Added. 10 * web-platform-tests/css/css-grid/subgrid/baseline-003-expected.html: Added. 11 * web-platform-tests/css/css-grid/subgrid/baseline-003.html: Added. 12 * web-platform-tests/css/css-grid/subgrid/baseline-004-expected.html: Added. 13 * web-platform-tests/css/css-grid/subgrid/baseline-004.html: Added. 14 * web-platform-tests/css/css-grid/subgrid/baseline-005-expected.html: Added. 15 * web-platform-tests/css/css-grid/subgrid/baseline-005.html: Added. 16 17 Added new WPT variants of the baseline tests, for the case where the introspected subgrid 18 has padding that affects the baseline position, and for the case where the subgrid uses an 19 orthogonal writing mode. 20 1 21 2022-04-18 Martin Robinson <mrobinson@webkit.org> 2 22 -
trunk/Source/WebCore/ChangeLog
r292967 r292973 1 2022-04-18 Matt Woodrow <mattwoodrow@apple.com> 2 3 Implement support for aligning baselines through subgrids 4 https://bugs.webkit.org/show_bug.cgi?id=238643 5 6 Reviewed by Javier Fernandez. 7 8 Implement baseline sharing recursion into subgrids 9 10 Tests: imported/w3c/web-platform-tests/css/css-grid/subgrid/baseline-002.html 11 imported/w3c/web-platform-tests/css/css-grid/subgrid/baseline-003.html 12 imported/w3c/web-platform-tests/css/css-grid/subgrid/baseline-004.html 13 imported/w3c/web-platform-tests/css/css-grid/subgrid/baseline-005.html 14 15 * rendering/GridBaselineAlignment.cpp: 16 (WebCore::GridBaselineAlignment::ascentForChild const): 17 (WebCore::GridBaselineAlignment::descentForChild const): 18 (WebCore::GridBaselineAlignment::updateBaselineAlignmentContext): 19 (WebCore::BaselineGroup::BaselineGroup): 20 (WebCore::BaselineGroup::update): 21 (WebCore::BaselineContext::BaselineContext): 22 (WebCore::BaselineContext::updateSharedGroup): 23 * rendering/GridBaselineAlignment.h: 24 (WebCore::BaselineGroup::maxAscent const): 25 (WebCore::BaselineGroup::maxDescent const): Deleted. 26 * rendering/GridLayoutFunctions.h: 27 * rendering/GridTrackSizingAlgorithm.cpp: 28 (WebCore::GridTrackSizingAlgorithm::canParticipateInBaselineAlignment const): 29 (WebCore::GridTrackSizingAlgorithm::updateBaselineAlignmentContext): 30 (WebCore::GridTrackSizingAlgorithm::baselineOffsetForChild const): 31 (WebCore::GridTrackSizingAlgorithm::cacheBaselineAlignedItem): 32 * rendering/GridTrackSizingAlgorithm.h: 33 * rendering/RenderGrid.cpp: 34 (WebCore::cacheBaselineAlignedChildren): 35 (WebCore::RenderGrid::computeIntrinsicLogicalWidths const): 36 (WebCore::RenderGrid::performGridItemsPreLayout const): 37 (WebCore::RenderGrid::alignSelfForChild const): 38 (WebCore::RenderGrid::justifySelfForChild const): 39 (WebCore::RenderGrid::columnAxisBaselineOffsetForChild const): 40 (WebCore::RenderGrid::rowAxisBaselineOffsetForChild const): 41 42 Moves the code for collecting baseline aligned children into a shared helper function, and adds 43 support for recursing into subgrid children (restricted to the axes that subgrid was applied). 44 45 Fixes align/justifySelfForChild to check if the child is a subgrid and overrides the result to 'stretch', so 46 that we're correctly stretching subgrids, not the children of subgrids (covered by new tests). 47 1 48 2022-04-18 Tyler Wilcock <tyler_w@apple.com> 2 49 -
trunk/Source/WebCore/rendering/GridBaselineAlignment.cpp
r278185 r292973 69 69 // We take border-box's under edge if no valid baseline. 70 70 if (baseline == -1) { 71 ASSERT(!child.needsLayout()); 71 72 if (isHorizontalBaselineAxis(baselineAxis)) 72 73 return isFlippedWritingMode(m_blockFlow) ? child.size().width().toInt() + margin : margin; … … 78 79 LayoutUnit GridBaselineAlignment::descentForChild(const RenderBox& child, LayoutUnit ascent, GridAxis baselineAxis) const 79 80 { 81 ASSERT(!child.needsLayout()); 80 82 if (isParallelToBaselineAxisForChild(child, baselineAxis)) 81 83 return child.marginLogicalHeight() + child.logicalHeight() - ascent; … … 123 125 // its grid container. 124 126 LayoutUnit ascent = ascentForChild(child, baselineAxis); 125 LayoutUnit descent = descentForChild(child, ascent, baselineAxis);126 127 if (isDescentBaselineForChild(child, baselineAxis)) 127 std::swap(ascent, descent);128 ascent = descentForChild(child, ascent, baselineAxis); 128 129 129 130 // Looking up for a shared alignment context perpendicular to the … … 135 136 // Looking for a compatible baseline-sharing group. 136 137 if (addResult.isNewEntry) 137 addResult.iterator->value = makeUnique<BaselineContext>(child, preference, ascent , descent);138 addResult.iterator->value = makeUnique<BaselineContext>(child, preference, ascent); 138 139 else { 139 140 auto* context = addResult.iterator->value.get(); 140 context->updateSharedGroup(child, preference, ascent , descent);141 context->updateSharedGroup(child, preference, ascent); 141 142 } 142 143 } … … 160 161 161 162 BaselineGroup::BaselineGroup(WritingMode blockFlow, ItemPosition childPreference) 162 : m_maxAscent(0), m_ maxDescent(0), m_items()163 : m_maxAscent(0), m_items() 163 164 { 164 165 m_blockFlow = blockFlow; … … 166 167 } 167 168 168 void BaselineGroup::update(const RenderBox& child, LayoutUnit ascent , LayoutUnit descent)169 void BaselineGroup::update(const RenderBox& child, LayoutUnit ascent) 169 170 { 170 171 if (m_items.add(&child).isNewEntry) { 171 172 m_maxAscent = std::max(m_maxAscent, ascent); 172 m_maxDescent = std::max(m_maxDescent, descent);173 173 } 174 174 } … … 210 210 } 211 211 212 BaselineContext::BaselineContext(const RenderBox& child, ItemPosition preference, LayoutUnit ascent , LayoutUnit descent)213 { 214 ASSERT(isBaselinePosition(preference)); 215 updateSharedGroup(child, preference, ascent , descent);212 BaselineContext::BaselineContext(const RenderBox& child, ItemPosition preference, LayoutUnit ascent) 213 { 214 ASSERT(isBaselinePosition(preference)); 215 updateSharedGroup(child, preference, ascent); 216 216 } 217 217 … … 222 222 } 223 223 224 void BaselineContext::updateSharedGroup(const RenderBox& child, ItemPosition preference, LayoutUnit ascent , LayoutUnit descent)224 void BaselineContext::updateSharedGroup(const RenderBox& child, ItemPosition preference, LayoutUnit ascent) 225 225 { 226 226 ASSERT(isBaselinePosition(preference)); 227 227 BaselineGroup& group = findCompatibleSharedGroup(child, preference); 228 group.update(child, ascent , descent);228 group.update(child, ascent); 229 229 } 230 230 -
trunk/Source/WebCore/rendering/GridBaselineAlignment.h
r276356 r292973 50 50 class BaselineGroup { 51 51 public: 52 // It stores an item (if not already present) and update the max_ascent a nd max_descent associated to this52 // It stores an item (if not already present) and update the max_ascent associated to this 53 53 // baseline-sharing group. 54 void update(const RenderBox&, LayoutUnit ascent , LayoutUnit descent);54 void update(const RenderBox&, LayoutUnit ascent); 55 55 LayoutUnit maxAscent() const { return m_maxAscent; } 56 LayoutUnit maxDescent() const { return m_maxDescent; }57 56 int size() const { return m_items.size(); } 58 57 … … 76 75 ItemPosition m_preference; 77 76 LayoutUnit m_maxAscent; 78 LayoutUnit m_maxDescent;79 77 HashSet<const RenderBox*> m_items; 80 78 }; … … 100 98 WTF_MAKE_FAST_ALLOCATED; 101 99 public: 102 BaselineContext(const RenderBox& child, ItemPosition preference, LayoutUnit ascent , LayoutUnit descent);100 BaselineContext(const RenderBox& child, ItemPosition preference, LayoutUnit ascent); 103 101 const BaselineGroup& sharedGroup(const RenderBox& child, ItemPosition preference) const; 104 102 … … 106 104 // We pass the item's baseline-preference to avoid dependencies with the LayoutGrid class, which is the one 107 105 // managing the alignment behavior of the Grid Items. 108 void updateSharedGroup(const RenderBox& child, ItemPosition preference, LayoutUnit ascent , LayoutUnit descent);106 void updateSharedGroup(const RenderBox& child, ItemPosition preference, LayoutUnit ascent); 109 107 110 108 private: -
trunk/Source/WebCore/rendering/GridLayoutFunctions.h
r290879 r292973 35 35 class RenderGrid; 36 36 37 enum GridAxis { GridRowAxis, GridColumnAxis }; 37 enum GridAxis { 38 GridRowAxis = 1 << 0, 39 GridColumnAxis = 1 << 1 40 }; 38 41 39 42 namespace GridLayoutFunctions { -
trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp
r292465 r292973 910 910 return true; 911 911 912 // FIXME: We don't currently allow items within subgrids that need to 913 // synthesize a baseline, since we need a layout to have been completed 914 // and performGridItemsPreLayout on the outer grid doesn't layout subgrid 915 // items. 916 if (child.parent() != renderGrid()) 917 return false; 918 912 919 // Baseline cyclic dependencies only happen in grid areas with 913 920 // intrinsically-sized tracks. … … 927 934 ASSERT(wasSetup()); 928 935 ASSERT(canParticipateInBaselineAlignment(child, baselineAxis)); 929 ASSERT(!child.needsLayout());930 936 931 937 ItemPosition align = m_renderGrid->selfAlignmentForChild(baselineAxis, child).position(); … … 936 942 LayoutUnit GridTrackSizingAlgorithm::baselineOffsetForChild(const RenderBox& child, GridAxis baselineAxis) const 937 943 { 944 // If we haven't yet initialized this axis (which can be the case if we're doing 945 // prelayout of a subgrid), then we can't know the baseline offset. 946 if (tracks(gridDirectionForAxis(baselineAxis)).isEmpty()) 947 return LayoutUnit(); 948 938 949 if (!participateInBaselineAlignment(child, baselineAxis)) 939 950 return LayoutUnit(); … … 952 963 void GridTrackSizingAlgorithm::cacheBaselineAlignedItem(const RenderBox& item, GridAxis axis) 953 964 { 954 ASSERT(m_renderGrid->isBaselineAlignmentForChild(item, axis)); 965 ASSERT(downcast<RenderGrid>(item.parent())->isBaselineAlignmentForChild(item, axis)); 966 967 if (GridLayoutFunctions::isOrthogonalParent(*m_renderGrid, *item.parent())) 968 axis = axis == GridColumnAxis ? GridRowAxis : GridColumnAxis; 969 955 970 if (axis == GridColumnAxis) 956 971 m_columnBaselineItemsMap.add(&item, true); -
trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h
r292465 r292973 123 123 Grid& mutableGrid() const { return m_grid; } 124 124 125 const RenderGrid* renderGrid() { return m_renderGrid; };125 const RenderGrid* renderGrid() const { return m_renderGrid; }; 126 126 127 127 LayoutUnit minContentSize() const { return m_minContentSize; }; -
trunk/Source/WebCore/rendering/RenderGrid.cpp
r292524 r292973 193 193 } 194 194 195 template<typename F> 196 static void cacheBaselineAlignedChildren(const RenderGrid& grid, GridTrackSizingAlgorithm& algorithm, uint32_t axes, F& callback) 197 { 198 for (auto* child = grid.firstChildBox(); child; child = child->nextSiblingBox()) { 199 if (child->isOutOfFlowPositioned() || child->isLegend()) 200 continue; 201 202 callback(child); 203 204 // We keep a cache of items with baseline as alignment values so that we only compute the baseline shims for 205 // such items. This cache is needed for performance related reasons due to the cost of evaluating the item's 206 // participation in a baseline context during the track sizing algorithm. 207 uint32_t innerAxes = 0; 208 RenderGrid* inner = is<RenderGrid>(child) ? downcast<RenderGrid>(child) : nullptr; 209 210 if (axes & GridColumnAxis) { 211 if (inner && inner->isSubgridInParentDirection(ForRows)) 212 innerAxes |= GridLayoutFunctions::isOrthogonalChild(grid, *child) ? GridRowAxis : GridColumnAxis; 213 else if (grid.isBaselineAlignmentForChild(*child, GridColumnAxis)) 214 algorithm.cacheBaselineAlignedItem(*child, GridColumnAxis); 215 } 216 217 if (axes & GridRowAxis) { 218 if (inner && inner->isSubgridInParentDirection(ForColumns)) 219 innerAxes |= GridLayoutFunctions::isOrthogonalChild(grid, *child) ? GridColumnAxis : GridRowAxis; 220 else if (grid.isBaselineAlignmentForChild(*child, GridRowAxis)) 221 algorithm.cacheBaselineAlignedItem(*child, GridRowAxis); 222 } 223 224 if (innerAxes) 225 cacheBaselineAlignedChildren(*inner, algorithm, innerAxes, callback); 226 } 227 } 228 195 229 Vector<RenderBox*> RenderGrid::computeAspectRatioDependentAndBaselineItems() 196 230 { … … 201 235 m_hasAspectRatioBlockSizeDependentItem = false; 202 236 203 for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { 204 if (child->isOutOfFlowPositioned() || child->isLegend()) 205 continue; 206 207 // Grid's layout logic controls the grid item's override height, hence we need to 208 // clear any override height set previously, so it doesn't interfere in current layout 209 // execution. Grid never uses the override width, that's why we don't need to clear it. 210 child->clearOverridingLogicalHeight(); 211 237 auto computeOrthogonalAndDependentItems = [&](RenderBox* child) { 212 238 // Grid's layout logic controls the grid item's override height, hence we need to 213 239 // clear any override height set previously, so it doesn't interfere in current layout … … 225 251 m_hasAspectRatioBlockSizeDependentItem = true; 226 252 } 227 228 // We keep a cache of items with baseline as aligcnment values so that we only compute the baseline shims for 229 // such items. This cache is needed for performance related reasons due to the cost of evaluating the item's 230 // participation in a baseline context during the track sizing algorithm. 231 if (isBaselineAlignmentForChild(*child, GridColumnAxis)) 232 m_trackSizingAlgorithm.cacheBaselineAlignedItem(*child, GridColumnAxis); 233 if (isBaselineAlignmentForChild(*child, GridRowAxis)) 234 m_trackSizingAlgorithm.cacheBaselineAlignedItem(*child, GridRowAxis); 235 } 236 253 }; 254 255 cacheBaselineAlignedChildren(*this, m_trackSizingAlgorithm, GridRowAxis | GridColumnAxis, computeOrthogonalAndDependentItems); 237 256 return dependentGridItems; 238 257 } … … 478 497 algorithm.copyBaselineItemsCache(m_trackSizingAlgorithm, GridRowAxis); 479 498 else { 480 for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { 481 if (child->isOutOfFlowPositioned()) 482 continue; 483 if (isBaselineAlignmentForChild(*child, GridRowAxis)) 484 algorithm.cacheBaselineAlignedItem(*child, GridRowAxis); 485 } 499 auto emptyCallback = [](RenderBox*) { }; 500 cacheBaselineAlignedChildren(*this, algorithm, GridRowAxis, emptyCallback); 486 501 } 487 502 … … 784 799 // baseline or not, which may imply a cyclic sizing dependency. 785 800 // FIXME: Can we avoid it ? 801 // FIXME: We also want to layout baseline aligned items within subgrids, but 802 // we don't currently have a way to do that here. 786 803 if (isBaselineAlignmentForChild(*child)) { 787 804 updateGridAreaLogicalSize(*child, algorithm.estimatedGridAreaBreadthForChild(*child, ForColumns), algorithm.estimatedGridAreaBreadthForChild(*child, ForRows)); … … 1227 1244 StyleSelfAlignmentData RenderGrid::alignSelfForChild(const RenderBox& child, StretchingMode stretchingMode, const RenderStyle* gridStyle) const 1228 1245 { 1229 if (is SubgridInParentDirection(ForRows))1246 if (is<RenderGrid>(child) && downcast<RenderGrid>(child).isSubgridInParentDirection(ForRows)) 1230 1247 return { ItemPosition::Stretch, OverflowAlignment::Default }; 1231 1248 if (!gridStyle) … … 1237 1254 StyleSelfAlignmentData RenderGrid::justifySelfForChild(const RenderBox& child, StretchingMode stretchingMode, const RenderStyle* gridStyle) const 1238 1255 { 1239 if (is SubgridInParentDirection(ForColumns))1256 if (is<RenderGrid>(child) && downcast<RenderGrid>(child).isSubgridInParentDirection(ForColumns)) 1240 1257 return { ItemPosition::Stretch, OverflowAlignment::Default }; 1241 1258 if (!gridStyle) … … 1458 1475 LayoutUnit RenderGrid::columnAxisBaselineOffsetForChild(const RenderBox& child) const 1459 1476 { 1477 if (isSubgridRows()) { 1478 RenderGrid* outer = downcast<RenderGrid>(parent()); 1479 if (GridLayoutFunctions::isOrthogonalChild(*outer, *this)) 1480 return outer->rowAxisBaselineOffsetForChild(child); 1481 return outer->columnAxisBaselineOffsetForChild(child); 1482 } 1460 1483 return m_trackSizingAlgorithm.baselineOffsetForChild(child, GridColumnAxis); 1461 1484 } … … 1463 1486 LayoutUnit RenderGrid::rowAxisBaselineOffsetForChild(const RenderBox& child) const 1464 1487 { 1488 if (isSubgridColumns()) { 1489 RenderGrid* outer = downcast<RenderGrid>(parent()); 1490 if (GridLayoutFunctions::isOrthogonalChild(*outer, *this)) 1491 return outer->columnAxisBaselineOffsetForChild(child); 1492 return outer->rowAxisBaselineOffsetForChild(child); 1493 } 1465 1494 return m_trackSizingAlgorithm.baselineOffsetForChild(child, GridRowAxis); 1466 1495 }
Note: See TracChangeset
for help on using the changeset viewer.