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

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: Applied suggested changes. Created 4 years, 1 month 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
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
(...skipping 14 matching lines...) Expand all
25 25
26 #include "core/layout/LayoutGrid.h" 26 #include "core/layout/LayoutGrid.h"
27 27
28 #include "core/layout/LayoutState.h" 28 #include "core/layout/LayoutState.h"
29 #include "core/layout/TextAutosizer.h" 29 #include "core/layout/TextAutosizer.h"
30 #include "core/paint/GridPainter.h" 30 #include "core/paint/GridPainter.h"
31 #include "core/paint/PaintLayer.h" 31 #include "core/paint/PaintLayer.h"
32 #include "core/style/ComputedStyle.h" 32 #include "core/style/ComputedStyle.h"
33 #include "core/style/GridArea.h" 33 #include "core/style/GridArea.h"
34 #include "platform/LengthFunctions.h" 34 #include "platform/LengthFunctions.h"
35 #include "platform/text/WritingMode.h"
35 #include "wtf/PtrUtil.h" 36 #include "wtf/PtrUtil.h"
36 #include <algorithm> 37 #include <algorithm>
37 #include <memory> 38 #include <memory>
38 39
39 namespace blink { 40 namespace blink {
40 41
41 static const int infinity = -1; 42 static const int infinity = -1;
42 43
43 class GridItemWithSpan; 44 class GridItemWithSpan;
44 45
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 ContentAlignmentData(){}; 134 ContentAlignmentData(){};
134 ContentAlignmentData(LayoutUnit position, LayoutUnit distribution) 135 ContentAlignmentData(LayoutUnit position, LayoutUnit distribution)
135 : positionOffset(position), distributionOffset(distribution) {} 136 : positionOffset(position), distributionOffset(distribution) {}
136 137
137 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; } 138 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; }
138 139
139 LayoutUnit positionOffset = LayoutUnit(-1); 140 LayoutUnit positionOffset = LayoutUnit(-1);
140 LayoutUnit distributionOffset = LayoutUnit(-1); 141 LayoutUnit distributionOffset = LayoutUnit(-1);
141 }; 142 };
142 143
144 class BaselineGroup {
145 public:
146 BaselineGroup() {}
147
148 void update(LayoutUnit ascent, LayoutUnit descent) {
149 m_maxAscent = std::max(m_maxAscent, ascent);
150 m_maxDescent = std::max(m_maxDescent, descent);
151 m_size++;
152 }
153 LayoutUnit maxAscent() const { return m_maxAscent; }
154 LayoutUnit maxDescent() const { return m_maxDescent; }
155 LayoutUnit size() const { return m_size; }
156
157 private:
158 LayoutUnit m_maxAscent;
159 LayoutUnit m_maxDescent;
160 LayoutUnit m_size;
svillar 2016/11/25 14:44:48 Not clear to me what this m_size is and why we inc
161 };
162
163 class BaselineContext {
164 public:
165 BaselineContext(const LayoutBox& child,
166 ItemPosition preference,
167 LayoutUnit ascent,
168 LayoutUnit descent) {
169 updateSharedGroup(child, preference, ascent, descent);
170 }
171
172 const BaselineGroup& getSharedGroup(const LayoutBox& child,
173 ItemPosition preference) const {
174 if (isAscentBaseline(child.styleRef().getWritingMode(), preference))
175 return m_ascentSharedGroup;
176 return m_descentSharedGroup;
177 }
178
179 void updateSharedGroup(const LayoutBox& child,
180 ItemPosition preference,
181 LayoutUnit ascent,
182 LayoutUnit descent) {
183 if (isAscentBaseline(child.styleRef().getWritingMode(), preference))
184 m_ascentSharedGroup.update(ascent, descent);
185 else
186 m_descentSharedGroup.update(ascent, descent);
187 }
188
189 private:
190 bool isAscentBaseline(WritingMode blockDirection,
191 ItemPosition preference) const {
192 return ((blockDirection == TopToBottomWritingMode &&
193 preference == ItemPositionBaseline) ||
194 (blockDirection == LeftToRightWritingMode &&
195 preference == ItemPositionBaseline) ||
196 (blockDirection == RightToLeftWritingMode &&
197 preference == ItemPositionLastBaseline));
198 }
199
200 BaselineGroup m_ascentSharedGroup;
201 BaselineGroup m_descentSharedGroup;
202 };
203
143 enum TrackSizeRestriction { 204 enum TrackSizeRestriction {
144 AllowInfinity, 205 AllowInfinity,
145 ForbidInfinity, 206 ForbidInfinity,
146 }; 207 };
147 208
148 class LayoutGrid::GridIterator { 209 class LayoutGrid::GridIterator {
149 WTF_MAKE_NONCOPYABLE(GridIterator); 210 WTF_MAKE_NONCOPYABLE(GridIterator);
150 211
151 public: 212 public:
152 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g 213 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 301 }
241 302
242 private: 303 private:
243 const GridRepresentation& m_grid; 304 const GridRepresentation& m_grid;
244 GridTrackSizingDirection m_direction; 305 GridTrackSizingDirection m_direction;
245 size_t m_rowIndex; 306 size_t m_rowIndex;
246 size_t m_columnIndex; 307 size_t m_columnIndex;
247 size_t m_childIndex; 308 size_t m_childIndex;
248 }; 309 };
249 310
311 typedef HashMap<unsigned,
312 std::unique_ptr<BaselineContext>,
313 DefaultHash<unsigned>::Hash,
314 WTF::UnsignedWithZeroKeyHashTraits<unsigned>>
315 BaselineContextsMap;
316
250 struct LayoutGrid::GridSizingData { 317 struct LayoutGrid::GridSizingData {
251 WTF_MAKE_NONCOPYABLE(GridSizingData); 318 WTF_MAKE_NONCOPYABLE(GridSizingData);
252 STACK_ALLOCATED(); 319 STACK_ALLOCATED();
253 320
254 public: 321 public:
255 GridSizingData(size_t gridColumnCount, size_t gridRowCount) 322 GridSizingData(size_t gridColumnCount, size_t gridRowCount)
256 : columnTracks(gridColumnCount), rowTracks(gridRowCount) {} 323 : columnTracks(gridColumnCount), rowTracks(gridRowCount) {}
257 324
258 Vector<GridTrack> columnTracks; 325 Vector<GridTrack> columnTracks;
259 Vector<GridTrack> rowTracks; 326 Vector<GridTrack> rowTracks;
260 Vector<size_t> contentSizedTracksIndex; 327 Vector<size_t> contentSizedTracksIndex;
261 328
329 BaselineContextsMap rowAxisAlignmentContext;
330 BaselineContextsMap colAxisAlignmentContext;
331
262 // Performance optimization: hold onto these Vectors until the end of Layout 332 // Performance optimization: hold onto these Vectors until the end of Layout
263 // to avoid repeated malloc / free. 333 // to avoid repeated malloc / free.
264 Vector<GridTrack*> filteredTracks; 334 Vector<GridTrack*> filteredTracks;
265 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; 335 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan;
266 Vector<GridTrack*> growBeyondGrowthLimitsTracks; 336 Vector<GridTrack*> growBeyondGrowthLimitsTracks;
267 337
268 LayoutUnit& freeSpace(GridTrackSizingDirection direction) { 338 LayoutUnit& freeSpace(GridTrackSizingDirection direction) {
269 return direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; 339 return direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows;
270 } 340 }
271 341
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 track.setGrowthLimit( 853 track.setGrowthLimit(
784 computeUsedBreadthOfMaxLength(trackSize, track.baseSize(), maxSize)); 854 computeUsedBreadthOfMaxLength(trackSize, track.baseSize(), maxSize));
785 track.setInfinitelyGrowable(false); 855 track.setInfinitelyGrowable(false);
786 856
787 if (trackSize.isFitContent()) { 857 if (trackSize.isFitContent()) {
788 GridLength gridLength = trackSize.fitContentTrackBreadth(); 858 GridLength gridLength = trackSize.fitContentTrackBreadth();
789 if (!gridLength.hasPercentage() || hasDefiniteFreeSpace) 859 if (!gridLength.hasPercentage() || hasDefiniteFreeSpace)
790 track.setGrowthLimitCap(valueForLength(gridLength.length(), maxSize)); 860 track.setGrowthLimitCap(valueForLength(gridLength.length(), maxSize));
791 } 861 }
792 862
793 if (trackSize.isContentSized()) 863 if (trackSize.isContentSized()) {
794 sizingData.contentSizedTracksIndex.append(i); 864 sizingData.contentSizedTracksIndex.append(i);
865 } else if (!m_gridItemArea.isEmpty()) {
svillar 2016/11/25 14:44:48 I am not sure this condition is correct. Why are w
866 GridIterator iterator(m_grid, direction, i);
867 while (LayoutBox* gridItem = iterator.nextGridItem()) {
868 if (isBaselineAlignment(*gridItem) &&
869 (sizingData.sizingOperation != IntrinsicSizeComputation ||
870 direction == ForRows))
871 gridItem->layoutIfNeeded();
872 updateBaselineAlignmentContextIfNeeded(*gridItem, sizingData);
873 }
874 }
795 if (trackSize.maxTrackBreadth().isFlex()) 875 if (trackSize.maxTrackBreadth().isFlex())
796 flexibleSizedTracksIndex.append(i); 876 flexibleSizedTracksIndex.append(i);
797 } 877 }
798 878
799 // 2. Resolve content-based TrackSizingFunctions. 879 // 2. Resolve content-based TrackSizingFunctions.
800 if (!sizingData.contentSizedTracksIndex.isEmpty()) 880 if (!sizingData.contentSizedTracksIndex.isEmpty())
801 resolveContentBasedTrackSizingFunctions(direction, sizingData); 881 resolveContentBasedTrackSizingFunctions(direction, sizingData);
802 882
803 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = LayoutUnit(); 883 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = LayoutUnit();
804 884
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 // sizes (AvailableSpaceIndefinite). 1177 // sizes (AvailableSpaceIndefinite).
1098 if ((sizingOperation == IntrinsicSizeComputation) || 1178 if ((sizingOperation == IntrinsicSizeComputation) ||
1099 (direction == ForRows && !cachedHasDefiniteLogicalHeight())) { 1179 (direction == ForRows && !cachedHasDefiniteLogicalHeight())) {
1100 if (minTrackBreadth.hasPercentage()) 1180 if (minTrackBreadth.hasPercentage())
1101 minTrackBreadth = Length(Auto); 1181 minTrackBreadth = Length(Auto);
1102 if (maxTrackBreadth.hasPercentage()) 1182 if (maxTrackBreadth.hasPercentage())
1103 maxTrackBreadth = Length(Auto); 1183 maxTrackBreadth = Length(Auto);
1104 } 1184 }
1105 } 1185 }
1106 1186
1107 // Flex sizes are invalid as a min sizing function. However we still can have 1187 // Flex sizes are invalid as a min sizing function. However we still can
1188 // have
svillar 2016/11/25 14:44:48 Something has happened to this comment
1108 // a flexible |minTrackBreadth| if the track had a flex size directly (e.g. 1189 // a flexible |minTrackBreadth| if the track had a flex size directly (e.g.
1109 // "1fr"), the spec says that in this case it implies an automatic minimum. 1190 // "1fr"), the spec says that in this case it implies an automatic minimum.
1110 if (minTrackBreadth.isFlex()) 1191 if (minTrackBreadth.isFlex())
1111 minTrackBreadth = Length(Auto); 1192 minTrackBreadth = Length(Auto);
1112 1193
1113 return GridTrackSize(minTrackBreadth, maxTrackBreadth); 1194 return GridTrackSize(minTrackBreadth, maxTrackBreadth);
1114 } 1195 }
1115 1196
1116 bool LayoutGrid::isOrthogonalChild(const LayoutBox& child) const { 1197 bool LayoutGrid::isOrthogonalChild(const LayoutBox& child) const {
1117 return child.isHorizontalWritingMode() != isHorizontalWritingMode(); 1198 return child.isHorizontalWritingMode() != isHorizontalWritingMode();
(...skipping 11 matching lines...) Expand all
1129 LayoutUnit(-1)); 1210 LayoutUnit(-1));
1130 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 1211 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1131 } 1212 }
1132 1213
1133 // We need to clear the stretched height to properly compute logical height 1214 // We need to clear the stretched height to properly compute logical height
1134 // during layout. 1215 // during layout.
1135 if (child.needsLayout()) 1216 if (child.needsLayout())
1136 child.clearOverrideLogicalContentHeight(); 1217 child.clearOverrideLogicalContentHeight();
1137 1218
1138 child.layoutIfNeeded(); 1219 child.layoutIfNeeded();
1139 return child.logicalHeight() + child.marginLogicalHeight(); 1220 LayoutUnit baselineOffset =
1221 updateBaselineAlignmentContextIfNeeded(child, sizingData);
1222 return baselineOffset > 0
1223 ? baselineOffset
1224 : child.logicalHeight() + child.marginLogicalHeight();
svillar 2016/11/25 14:44:48 Nit: what about if (auto baselineOffset = update.
1140 } 1225 }
1141 1226
1142 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild( 1227 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild(
1143 const LayoutBox& child, 1228 const LayoutBox& child,
1144 GridTrackSizingDirection direction) const { 1229 GridTrackSizingDirection direction) const {
1145 return !isOrthogonalChild(child) 1230 return !isOrthogonalChild(child)
1146 ? direction 1231 ? direction
1147 : (direction == ForColumns ? ForRows : ForColumns); 1232 : (direction == ForColumns ? ForRows : ForColumns);
1148 } 1233 }
1149 1234
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 1310
1226 // All orthogonal flow boxes were already laid out during an early layout 1311 // All orthogonal flow boxes were already laid out during an early layout
1227 // phase performed in FrameView::performLayout. 1312 // phase performed in FrameView::performLayout.
1228 // It's true that grid track sizing was not completed at that time and it may 1313 // It's true that grid track sizing was not completed at that time and it may
1229 // afffect the final height of a grid item, but since it's forbidden to 1314 // afffect the final height of a grid item, but since it's forbidden to
1230 // perform a layout during intrinsic width computation, we have to use that 1315 // perform a layout during intrinsic width computation, we have to use that
1231 // computed height for now. 1316 // computed height for now.
1232 if (direction == ForColumns && 1317 if (direction == ForColumns &&
1233 sizingData.sizingOperation == IntrinsicSizeComputation) { 1318 sizingData.sizingOperation == IntrinsicSizeComputation) {
1234 DCHECK(isOrthogonalChild(child)); 1319 DCHECK(isOrthogonalChild(child));
1235 return child.logicalHeight() + child.marginLogicalHeight(); 1320 LayoutUnit baselineOffset =
1321 updateBaselineAlignmentContextIfNeeded(child, sizingData);
1322 return baselineOffset > 0
1323 ? baselineOffset
1324 : child.logicalHeight() + child.marginLogicalHeight();
svillar 2016/11/25 14:44:48 Looks like exactly the same code, would it make se
1236 } 1325 }
1237 1326
1238 if (updateOverrideContainingBlockContentSizeForChild( 1327 if (updateOverrideContainingBlockContentSizeForChild(
1239 child, childInlineDirection, sizingData)) 1328 child, childInlineDirection, sizingData))
1240 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); 1329 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1241 return logicalHeightForChild(child, sizingData); 1330 return logicalHeightForChild(child, sizingData);
1242 } 1331 }
1243 1332
1244 DISABLE_CFI_PERF 1333 DISABLE_CFI_PERF
1245 LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, 1334 LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child,
(...skipping 1493 matching lines...) Expand 10 before | Expand all | Expand 10 after
2739 return LayoutUnit(); 2828 return LayoutUnit();
2740 } 2829 }
2741 2830
2742 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to 2831 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to
2743 // LayoutBox. 2832 // LayoutBox.
2744 LayoutUnit LayoutGrid::marginLogicalHeightForChild( 2833 LayoutUnit LayoutGrid::marginLogicalHeightForChild(
2745 const LayoutBox& child) const { 2834 const LayoutBox& child) const {
2746 return isHorizontalWritingMode() ? child.marginHeight() : child.marginWidth(); 2835 return isHorizontalWritingMode() ? child.marginHeight() : child.marginWidth();
2747 } 2836 }
2748 2837
2838 LayoutUnit LayoutGrid::marginLogicalWidthForChild(
2839 const LayoutBox& child) const {
2840 return isHorizontalWritingMode() ? child.marginWidth() : child.marginHeight();
2841 }
2842
2749 LayoutUnit LayoutGrid::computeMarginLogicalSizeForChild( 2843 LayoutUnit LayoutGrid::computeMarginLogicalSizeForChild(
2750 MarginDirection forDirection, 2844 MarginDirection forDirection,
2751 const LayoutBox& child) const { 2845 const LayoutBox& child) const {
2752 if (!child.styleRef().hasMargin()) 2846 if (!child.styleRef().hasMargin())
2753 return LayoutUnit(); 2847 return LayoutUnit();
2754 2848
2755 bool isRowAxis = forDirection == InlineDirection; 2849 bool isRowAxis = forDirection == InlineDirection;
2756 LayoutUnit marginStart; 2850 LayoutUnit marginStart;
2757 LayoutUnit marginEnd; 2851 LayoutUnit marginEnd;
2758 LayoutUnit logicalSize = 2852 LayoutUnit logicalSize =
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 3016
2923 static int synthesizedBaselineFromBorderBox(const LayoutBox& box, 3017 static int synthesizedBaselineFromBorderBox(const LayoutBox& box,
2924 LineDirectionMode direction) { 3018 LineDirectionMode direction) {
2925 return (direction == HorizontalLine ? box.size().height() 3019 return (direction == HorizontalLine ? box.size().height()
2926 : box.size().width()) 3020 : box.size().width())
2927 .toInt(); 3021 .toInt();
2928 } 3022 }
2929 3023
2930 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it might be 3024 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it might be
2931 // refactored somehow. 3025 // refactored somehow.
3026 bool LayoutGrid::isBaselineAlignment(const LayoutBox& child) const {
3027 bool isChildInlineFlowAlongRowAxis = !isOrthogonalChild(child);
svillar 2016/11/25 14:44:48 I don't understand this variable name. isParallelC
3028 ItemPosition align = isChildInlineFlowAlongRowAxis
3029 ? alignSelfForChild(child).position()
3030 : justifySelfForChild(child).position();
3031 bool hasAutoMargins = isChildInlineFlowAlongRowAxis
3032 ? hasAutoMarginsInColumnAxis(child)
3033 : hasAutoMarginsInRowAxis(child);
3034 return (
3035 (align == ItemPositionBaseline || align == ItemPositionLastBaseline) &&
3036 !hasAutoMargins);
3037 }
3038
3039 LayoutUnit LayoutGrid::updateBaselineAlignmentContextIfNeeded(
3040 LayoutBox& child,
3041 GridSizingData& sizingData) const {
3042 if (!isBaselineAlignment(child))
3043 return LayoutUnit();
3044
3045 bool isChildInlineFlowAlongRowAxis = !isOrthogonalChild(child);
3046 ItemPosition align = isChildInlineFlowAlongRowAxis
3047 ? alignSelfForChild(child).position()
3048 : justifySelfForChild(child).position();
3049 const GridSpan& span = isChildInlineFlowAlongRowAxis
3050 ? cachedGridSpan(child, ForRows)
3051 : cachedGridSpan(child, ForColumns);
3052 LayoutUnit ascent = firstLineBoxBaselineForChild(child);
3053 LayoutUnit descent = descentBaselineForChild(child, ascent);
3054 BaselineContextsMap& baselineContexts =
3055 isChildInlineFlowAlongRowAxis ? sizingData.rowAxisAlignmentContext
3056 : sizingData.colAxisAlignmentContext;
3057 BaselineContext* context = nullptr;
3058 BaselineContextsMap::AddResult addResult = baselineContexts.add(
3059 span.startLine(), std::unique_ptr<BaselineContext>());
3060 if (addResult.isNewEntry) {
3061 context = new BaselineContext(child, align, ascent, descent);
3062 addResult.storedValue->value = wrapUnique(context);
3063 } else {
3064 context = addResult.storedValue->value.get();
3065 context->updateSharedGroup(child, align, ascent, descent);
3066 }
3067 auto group = context->getSharedGroup(child, align);
3068 return group.maxAscent() + group.maxDescent();
3069 }
3070
3071 LayoutUnit LayoutGrid::firstLineBoxBaselineForChild(
3072 const LayoutBox& child) const {
3073 LayoutUnit baseline(child.firstLineBoxBaseline());
3074 // We take content-box's bottom if no valid baseline.
3075 if (baseline == -1)
3076 baseline = LayoutBlock::logicalHeightForChild(child);
3077 return baseline + marginBeforeForChild(child);
3078 }
3079
3080 LayoutUnit LayoutGrid::descentBaselineForChild(const LayoutBox& child,
3081 LayoutUnit ascent) const {
3082 bool isChildInlineFlowAlongRowAxis = !isOrthogonalChild(child);
3083 return isChildInlineFlowAlongRowAxis
3084 ? (marginLogicalHeightForChild(child) +
3085 LayoutBlock::logicalHeightForChild(child)) -
3086 ascent
3087 : (marginLogicalWidthForChild(child) +
3088 logicalWidthForChild(child)) -
3089 ascent;
3090 }
3091
3092 LayoutUnit LayoutGrid::columnAxisBaselineOffsetForChild(
3093 const LayoutBox& child,
3094 const GridSizingData& sizingData) const {
3095 // only parallel items participating in baseline alignment along
svillar 2016/11/25 14:44:48 Nit: capital letter -> Only
3096 // the grid's row axis have an offset in the column axis.
3097 if (!isInlineBaselineAlignedChild(child))
3098 return LayoutUnit();
3099
3100 const GridSpan& span = cachedGridSpan(child, ForRows);
3101 const BaselineContext* context =
3102 sizingData.rowAxisAlignmentContext.get(span.startLine());
3103 DCHECK(context);
3104 const BaselineGroup& group =
3105 context->getSharedGroup(child, alignSelfForChild(child).position());
3106 // TODO (lajava): We could just return LayoutUnit() if there is only
3107 // 1 child in the group.
3108 return group.maxAscent() - firstLineBoxBaselineForChild(child);
3109 }
3110
3111 LayoutUnit LayoutGrid::rowAxisBaselineOffsetForChild(
3112 const LayoutBox& child,
3113 const GridSizingData& sizingData) const {
3114 // only orthogonal items participating in baseline alignment along
3115 // the grid's column axis have an offset in the row axis.
3116 if (!isBlockBaselineAlignedChild(child))
3117 return LayoutUnit();
3118
3119 const GridSpan& span = cachedGridSpan(child, ForColumns);
3120 const BaselineContext* context =
3121 sizingData.colAxisAlignmentContext.get(span.startLine());
3122 DCHECK(context);
3123 const BaselineGroup& group =
3124 context->getSharedGroup(child, justifySelfForChild(child).position());
3125 // TODO (lajava): We could just return LayoutUnit() if there is only
3126 // 1 child in the group.
3127 return group.maxAscent() - firstLineBoxBaselineForChild(child);
3128 }
3129
2932 int LayoutGrid::baselinePosition(FontBaseline, 3130 int LayoutGrid::baselinePosition(FontBaseline,
2933 bool, 3131 bool,
2934 LineDirectionMode direction, 3132 LineDirectionMode direction,
2935 LinePositionMode mode) const { 3133 LinePositionMode mode) const {
2936 DCHECK_EQ(mode, PositionOnContainingLine); 3134 DCHECK_EQ(mode, PositionOnContainingLine);
2937 int baseline = firstLineBoxBaseline(); 3135 int baseline = firstLineBoxBaseline();
2938 // We take content-box's bottom if no valid baseline. 3136 // We take content-box's bottom if no valid baseline.
2939 if (baseline == -1) 3137 if (baseline == -1)
2940 baseline = synthesizedBaselineFromContentBox(*this, direction); 3138 baseline = synthesizedBaselineFromContentBox(*this, direction);
2941 3139
2942 return baseline + beforeMarginInLineDirection(direction); 3140 return baseline + beforeMarginInLineDirection(direction);
2943 } 3141 }
2944 3142
2945 bool LayoutGrid::isInlineBaselineAlignedChild(const LayoutBox* child) const { 3143 bool LayoutGrid::isInlineBaselineAlignedChild(const LayoutBox& child) const {
2946 return alignSelfForChild(*child).position() == ItemPositionBaseline && 3144 return !isOrthogonalChild(child) && isBaselineAlignment(child);
2947 !isOrthogonalChild(*child) && !hasAutoMarginsInColumnAxis(*child); 3145 }
3146
3147 bool LayoutGrid::isBlockBaselineAlignedChild(const LayoutBox& child) const {
3148 return isOrthogonalChild(child) && isBaselineAlignment(child);
2948 } 3149 }
2949 3150
2950 int LayoutGrid::firstLineBoxBaseline() const { 3151 int LayoutGrid::firstLineBoxBaseline() const {
2951 if (isWritingModeRoot() || m_grid.isEmpty()) 3152 if (isWritingModeRoot() || m_grid.isEmpty())
2952 return -1; 3153 return -1;
2953 const LayoutBox* baselineChild = nullptr; 3154 const LayoutBox* baselineChild = nullptr;
2954 const LayoutBox* firstChild = nullptr; 3155 const LayoutBox* firstChild = nullptr;
2955 bool isBaselineAligned = false; 3156 bool isBaselineAligned = false;
2956 // Finding the first grid item in grid order. 3157 // Finding the first grid item in grid order.
2957 for (size_t column = 0; !isBaselineAligned && column < m_grid[0].size(); 3158 for (size_t column = 0; !isBaselineAligned && column < m_grid[0].size();
2958 column++) { 3159 column++) {
2959 for (size_t index = 0; index < m_grid[0][column].size(); index++) { 3160 for (size_t index = 0; index < m_grid[0][column].size(); index++) {
2960 const LayoutBox* child = m_grid[0][column][index]; 3161 const LayoutBox* child = m_grid[0][column][index];
2961 DCHECK(!child->isOutOfFlowPositioned()); 3162 DCHECK(!child->isOutOfFlowPositioned());
2962 // If an item participates in baseline alignmen, we select such item. 3163 // If an item participates in baseline alignment, we select such item.
2963 if (isInlineBaselineAlignedChild(child)) { 3164 if (isInlineBaselineAlignedChild(*child)) {
2964 // TODO (lajava): self-baseline and content-baseline alignment 3165 // TODO (lajava): self-baseline and content-baseline alignment
2965 // still not implemented. 3166 // still not implemented.
2966 baselineChild = child; 3167 baselineChild = child;
2967 isBaselineAligned = true; 3168 isBaselineAligned = true;
2968 break; 3169 break;
2969 } 3170 }
2970 if (!baselineChild) { 3171 if (!baselineChild) {
2971 // Use dom order for items in the same cell. 3172 // Use dom order for items in the same cell.
2972 if (!firstChild || (m_gridItemsIndexesMap.get(child) < 3173 if (!firstChild || (m_gridItemsIndexesMap.get(child) <
2973 m_gridItemsIndexesMap.get(firstChild))) 3174 m_gridItemsIndexesMap.get(firstChild)))
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3072 // Only used in flex layout, otherwise equivalent to 'end'. 3273 // Only used in flex layout, otherwise equivalent to 'end'.
3073 case ItemPositionFlexEnd: 3274 case ItemPositionFlexEnd:
3074 // Aligns the alignment subject to be flush with the alignment container's 3275 // Aligns the alignment subject to be flush with the alignment container's
3075 // 'end' edge (block-end) in the column axis. 3276 // 'end' edge (block-end) in the column axis.
3076 case ItemPositionEnd: 3277 case ItemPositionEnd:
3077 return GridAxisEnd; 3278 return GridAxisEnd;
3078 case ItemPositionStretch: 3279 case ItemPositionStretch:
3079 return GridAxisStart; 3280 return GridAxisStart;
3080 case ItemPositionBaseline: 3281 case ItemPositionBaseline:
3081 case ItemPositionLastBaseline: 3282 case ItemPositionLastBaseline:
3082 // FIXME: These two require implementing Baseline Alignment. For now, we
3083 // always 'start' align the child. crbug.com/234191
3084 return GridAxisStart; 3283 return GridAxisStart;
3085 case ItemPositionAuto: 3284 case ItemPositionAuto:
3086 case ItemPositionNormal: 3285 case ItemPositionNormal:
3087 break; 3286 break;
3088 } 3287 }
3089 3288
3090 ASSERT_NOT_REACHED(); 3289 ASSERT_NOT_REACHED();
3091 return GridAxisStart; 3290 return GridAxisStart;
3092 } 3291 }
3093 3292
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3151 // Only used in flex layout, otherwise equivalent to 'end'. 3350 // Only used in flex layout, otherwise equivalent to 'end'.
3152 case ItemPositionFlexEnd: 3351 case ItemPositionFlexEnd:
3153 // Aligns the alignment subject to be flush with the alignment container's 3352 // Aligns the alignment subject to be flush with the alignment container's
3154 // 'end' edge (inline-end) in the row axis. 3353 // 'end' edge (inline-end) in the row axis.
3155 case ItemPositionEnd: 3354 case ItemPositionEnd:
3156 return GridAxisEnd; 3355 return GridAxisEnd;
3157 case ItemPositionStretch: 3356 case ItemPositionStretch:
3158 return GridAxisStart; 3357 return GridAxisStart;
3159 case ItemPositionBaseline: 3358 case ItemPositionBaseline:
3160 case ItemPositionLastBaseline: 3359 case ItemPositionLastBaseline:
3161 // FIXME: These two require implementing Baseline Alignment. For now, we
3162 // always 'start' align the child. crbug.com/234191
3163 return GridAxisStart; 3360 return GridAxisStart;
3164 case ItemPositionAuto: 3361 case ItemPositionAuto:
3165 case ItemPositionNormal: 3362 case ItemPositionNormal:
3166 break; 3363 break;
3167 } 3364 }
3168 3365
3169 ASSERT_NOT_REACHED(); 3366 ASSERT_NOT_REACHED();
3170 return GridAxisStart; 3367 return GridAxisStart;
3171 } 3368 }
3172 3369
3173 LayoutUnit LayoutGrid::columnAxisOffsetForChild( 3370 LayoutUnit LayoutGrid::columnAxisOffsetForChild(
3174 const LayoutBox& child, 3371 const LayoutBox& child,
3175 GridSizingData& sizingData) const { 3372 GridSizingData& sizingData) const {
3176 const GridSpan& rowsSpan = cachedGridSpan(child, ForRows); 3373 const GridSpan& rowsSpan = cachedGridSpan(child, ForRows);
3177 size_t childStartLine = rowsSpan.startLine(); 3374 size_t childStartLine = rowsSpan.startLine();
3178 LayoutUnit startOfRow = m_rowPositions[childStartLine]; 3375 LayoutUnit startOfRow = m_rowPositions[childStartLine];
3179 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 3376 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
3180 if (hasAutoMarginsInColumnAxis(child)) 3377 if (hasAutoMarginsInColumnAxis(child))
3181 return startPosition; 3378 return startPosition;
3182 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 3379 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
3183 switch (axisPosition) { 3380 switch (axisPosition) {
3184 case GridAxisStart: 3381 case GridAxisStart:
3185 return startPosition; 3382 return startPosition +
3383 columnAxisBaselineOffsetForChild(child, sizingData);
3186 case GridAxisEnd: 3384 case GridAxisEnd:
3187 case GridAxisCenter: { 3385 case GridAxisCenter: {
3188 size_t childEndLine = rowsSpan.endLine(); 3386 size_t childEndLine = rowsSpan.endLine();
3189 LayoutUnit endOfRow = m_rowPositions[childEndLine]; 3387 LayoutUnit endOfRow = m_rowPositions[childEndLine];
3190 // m_rowPositions include distribution offset (because of content 3388 // m_rowPositions include distribution offset (because of content
3191 // alignment) and gutters so we need to subtract them to get the actual 3389 // alignment) and gutters so we need to subtract them to get the actual
3192 // end position for a given row (this does not have to be done for the 3390 // end position for a given row (this does not have to be done for the
3193 // last track as there are no more m_columnPositions after it). 3391 // last track as there are no more m_columnPositions after it).
3194 LayoutUnit trackGap = 3392 LayoutUnit trackGap =
3195 gridGapForDirection(ForRows, sizingData.sizingOperation); 3393 gridGapForDirection(ForRows, sizingData.sizingOperation);
(...skipping 22 matching lines...) Expand all
3218 GridSizingData& sizingData) const { 3416 GridSizingData& sizingData) const {
3219 const GridSpan& columnsSpan = cachedGridSpan(child, ForColumns); 3417 const GridSpan& columnsSpan = cachedGridSpan(child, ForColumns);
3220 size_t childStartLine = columnsSpan.startLine(); 3418 size_t childStartLine = columnsSpan.startLine();
3221 LayoutUnit startOfColumn = m_columnPositions[childStartLine]; 3419 LayoutUnit startOfColumn = m_columnPositions[childStartLine];
3222 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 3420 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
3223 if (hasAutoMarginsInRowAxis(child)) 3421 if (hasAutoMarginsInRowAxis(child))
3224 return startPosition; 3422 return startPosition;
3225 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 3423 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
3226 switch (axisPosition) { 3424 switch (axisPosition) {
3227 case GridAxisStart: 3425 case GridAxisStart:
3228 return startPosition; 3426 return startPosition + rowAxisBaselineOffsetForChild(child, sizingData);
3229 case GridAxisEnd: 3427 case GridAxisEnd:
3230 case GridAxisCenter: { 3428 case GridAxisCenter: {
3231 size_t childEndLine = columnsSpan.endLine(); 3429 size_t childEndLine = columnsSpan.endLine();
3232 LayoutUnit endOfColumn = m_columnPositions[childEndLine]; 3430 LayoutUnit endOfColumn = m_columnPositions[childEndLine];
3233 // m_columnPositions include distribution offset (because of content 3431 // m_columnPositions include distribution offset (because of content
3234 // alignment) and gutters so we need to subtract them to get the actual 3432 // alignment) and gutters so we need to subtract them to get the actual
3235 // end position for a given column (this does not have to be done for the 3433 // end position for a given column (this does not have to be done for the
3236 // last track as there are no more m_columnPositions after it). 3434 // last track as there are no more m_columnPositions after it).
3237 LayoutUnit trackGap = 3435 LayoutUnit trackGap =
3238 gridGapForDirection(ForColumns, sizingData.sizingOperation); 3436 gridGapForDirection(ForColumns, sizingData.sizingOperation);
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
3436 if (!m_gridItemArea.isEmpty()) 3634 if (!m_gridItemArea.isEmpty())
3437 GridPainter(*this).paintChildren(paintInfo, paintOffset); 3635 GridPainter(*this).paintChildren(paintInfo, paintOffset);
3438 } 3636 }
3439 3637
3440 bool LayoutGrid::cachedHasDefiniteLogicalHeight() const { 3638 bool LayoutGrid::cachedHasDefiniteLogicalHeight() const {
3441 SECURITY_DCHECK(m_hasDefiniteLogicalHeight); 3639 SECURITY_DCHECK(m_hasDefiniteLogicalHeight);
3442 return m_hasDefiniteLogicalHeight.value(); 3640 return m_hasDefiniteLogicalHeight.value();
3443 } 3641 }
3444 3642
3445 } // namespace blink 3643 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698