OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/layout/ng/ng_length_utils.h" | 5 #include "core/layout/ng/ng_length_utils.h" |
6 | 6 |
7 #include "core/layout/ng/ng_constraint_space.h" | 7 #include "core/layout/ng/ng_constraint_space.h" |
8 #include "core/layout/ng/ng_fragment.h" | 8 #include "core/layout/ng/ng_fragment.h" |
9 #include "core/style/ComputedStyle.h" | 9 #include "core/style/ComputedStyle.h" |
10 #include "platform/LayoutUnit.h" | 10 #include "platform/LayoutUnit.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 logical_dim = {is_ltr ? physical_dim.left : physical_dim.right, | 49 logical_dim = {is_ltr ? physical_dim.left : physical_dim.right, |
50 is_ltr ? physical_dim.right : physical_dim.left, | 50 is_ltr ? physical_dim.right : physical_dim.left, |
51 physical_dim.top, physical_dim.bottom}; | 51 physical_dim.top, physical_dim.bottom}; |
52 break; | 52 break; |
53 } | 53 } |
54 return logical_dim; | 54 return logical_dim; |
55 } | 55 } |
56 | 56 |
57 } // namespace | 57 } // namespace |
58 | 58 |
59 LayoutUnit resolveInlineLength(const NGConstraintSpace& constraintSpace, | 59 LayoutUnit ResolveInlineLength(const NGConstraintSpace& constraintSpace, |
60 const ComputedStyle& style, | 60 const ComputedStyle& style, |
61 const Length& length, | 61 const Length& length, |
62 LengthResolveType type) { | 62 LengthResolveType type) { |
63 // TODO(layout-ng): Handle min/max/fit-content | 63 // TODO(layout-ng): Handle min/max/fit-content |
64 DCHECK(!length.isMaxSizeNone()); | 64 DCHECK(!length.isMaxSizeNone()); |
65 DCHECK_GE(constraintSpace.ContainerSize().inline_size, LayoutUnit()); | 65 DCHECK_GE(constraintSpace.ContainerSize().inline_size, LayoutUnit()); |
66 | 66 |
67 if (type == LengthResolveType::MinSize && length.isAuto()) | 67 if (type == LengthResolveType::MinSize && length.isAuto()) |
68 return LayoutUnit(); | 68 return LayoutUnit(); |
69 | 69 |
70 if (type == LengthResolveType::MarginBorderPaddingSize && length.isAuto()) | 70 if (type == LengthResolveType::MarginBorderPaddingSize && length.isAuto()) |
71 return LayoutUnit(); | 71 return LayoutUnit(); |
72 | 72 |
73 // We don't need this when we're resolving margin/border/padding; skip | 73 // We don't need this when we're resolving margin/border/padding; skip |
74 // computing it as an optimization and to simplify the code below. | 74 // computing it as an optimization and to simplify the code below. |
75 NGBoxStrut border_and_padding; | 75 NGBoxStrut border_and_padding; |
76 if (type != LengthResolveType::MarginBorderPaddingSize) { | 76 if (type != LengthResolveType::MarginBorderPaddingSize) { |
77 border_and_padding = | 77 border_and_padding = |
78 computeBorders(style) + computePadding(constraintSpace, style); | 78 ComputeBorders(style) + ComputePadding(constraintSpace, style); |
79 } | 79 } |
80 LayoutUnit container_size = constraintSpace.ContainerSize().inline_size; | 80 LayoutUnit container_size = constraintSpace.ContainerSize().inline_size; |
81 switch (length.type()) { | 81 switch (length.type()) { |
82 case Auto: | 82 case Auto: |
83 case FillAvailable: { | 83 case FillAvailable: { |
84 NGBoxStrut margins = | 84 NGBoxStrut margins = |
85 computeMargins(constraintSpace, style, | 85 ComputeMargins(constraintSpace, style, |
86 FromPlatformWritingMode(style.getWritingMode()), | 86 FromPlatformWritingMode(style.getWritingMode()), |
87 FromPlatformDirection(style.direction())); | 87 FromPlatformDirection(style.direction())); |
88 return std::max(border_and_padding.InlineSum(), | 88 return std::max(border_and_padding.InlineSum(), |
89 container_size - margins.InlineSum()); | 89 container_size - margins.InlineSum()); |
90 } | 90 } |
91 case Percent: | 91 case Percent: |
92 case Fixed: | 92 case Fixed: |
93 case Calculated: { | 93 case Calculated: { |
94 LayoutUnit value = valueForLength(length, container_size); | 94 LayoutUnit value = valueForLength(length, container_size); |
95 if (style.boxSizing() == BoxSizingContentBox) { | 95 if (style.boxSizing() == BoxSizingContentBox) { |
(...skipping 12 matching lines...) Expand all Loading... |
108 case DeviceHeight: | 108 case DeviceHeight: |
109 case ExtendToZoom: | 109 case ExtendToZoom: |
110 NOTREACHED() << "These should only be used for viewport definitions"; | 110 NOTREACHED() << "These should only be used for viewport definitions"; |
111 case MaxSizeNone: | 111 case MaxSizeNone: |
112 default: | 112 default: |
113 NOTREACHED(); | 113 NOTREACHED(); |
114 return border_and_padding.InlineSum(); | 114 return border_and_padding.InlineSum(); |
115 } | 115 } |
116 } | 116 } |
117 | 117 |
118 LayoutUnit resolveBlockLength(const NGConstraintSpace& constraintSpace, | 118 LayoutUnit ResolveBlockLength(const NGConstraintSpace& constraintSpace, |
119 const ComputedStyle& style, | 119 const ComputedStyle& style, |
120 const Length& length, | 120 const Length& length, |
121 LayoutUnit contentSize, | 121 LayoutUnit contentSize, |
122 LengthResolveType type) { | 122 LengthResolveType type) { |
123 DCHECK(!length.isMaxSizeNone()); | 123 DCHECK(!length.isMaxSizeNone()); |
124 DCHECK(type != LengthResolveType::MarginBorderPaddingSize); | 124 DCHECK(type != LengthResolveType::MarginBorderPaddingSize); |
125 | 125 |
126 if (type == LengthResolveType::MinSize && length.isAuto()) | 126 if (type == LengthResolveType::MinSize && length.isAuto()) |
127 return LayoutUnit(); | 127 return LayoutUnit(); |
128 | 128 |
129 // Make sure that indefinite percentages resolve to NGSizeIndefinite, not to | 129 // Make sure that indefinite percentages resolve to NGSizeIndefinite, not to |
130 // a random negative number. | 130 // a random negative number. |
131 if (length.isPercentOrCalc() && | 131 if (length.isPercentOrCalc() && |
132 constraintSpace.ContainerSize().block_size == NGSizeIndefinite) | 132 constraintSpace.ContainerSize().block_size == NGSizeIndefinite) |
133 return contentSize; | 133 return contentSize; |
134 | 134 |
135 // We don't need this when we're resolving margin/border/padding; skip | 135 // We don't need this when we're resolving margin/border/padding; skip |
136 // computing it as an optimization and to simplify the code below. | 136 // computing it as an optimization and to simplify the code below. |
137 NGBoxStrut border_and_padding; | 137 NGBoxStrut border_and_padding; |
138 if (type != LengthResolveType::MarginBorderPaddingSize) { | 138 if (type != LengthResolveType::MarginBorderPaddingSize) { |
139 border_and_padding = | 139 border_and_padding = |
140 computeBorders(style) + computePadding(constraintSpace, style); | 140 ComputeBorders(style) + ComputePadding(constraintSpace, style); |
141 } | 141 } |
142 LayoutUnit container_size = constraintSpace.ContainerSize().block_size; | 142 LayoutUnit container_size = constraintSpace.ContainerSize().block_size; |
143 switch (length.type()) { | 143 switch (length.type()) { |
144 case FillAvailable: { | 144 case FillAvailable: { |
145 NGBoxStrut margins = | 145 NGBoxStrut margins = |
146 computeMargins(constraintSpace, style, | 146 ComputeMargins(constraintSpace, style, |
147 FromPlatformWritingMode(style.getWritingMode()), | 147 FromPlatformWritingMode(style.getWritingMode()), |
148 FromPlatformDirection(style.direction())); | 148 FromPlatformDirection(style.direction())); |
149 return std::max(border_and_padding.BlockSum(), | 149 return std::max(border_and_padding.BlockSum(), |
150 container_size - margins.BlockSum()); | 150 container_size - margins.BlockSum()); |
151 } | 151 } |
152 case Percent: | 152 case Percent: |
153 case Fixed: | 153 case Fixed: |
154 case Calculated: { | 154 case Calculated: { |
155 LayoutUnit value = valueForLength(length, container_size); | 155 LayoutUnit value = valueForLength(length, container_size); |
156 if (style.boxSizing() == BoxSizingContentBox) { | 156 if (style.boxSizing() == BoxSizingContentBox) { |
(...skipping 16 matching lines...) Expand all Loading... |
173 case DeviceHeight: | 173 case DeviceHeight: |
174 case ExtendToZoom: | 174 case ExtendToZoom: |
175 NOTREACHED() << "These should only be used for viewport definitions"; | 175 NOTREACHED() << "These should only be used for viewport definitions"; |
176 case MaxSizeNone: | 176 case MaxSizeNone: |
177 default: | 177 default: |
178 NOTREACHED(); | 178 NOTREACHED(); |
179 return border_and_padding.BlockSum(); | 179 return border_and_padding.BlockSum(); |
180 } | 180 } |
181 } | 181 } |
182 | 182 |
183 LayoutUnit computeInlineSizeForFragment( | 183 LayoutUnit ComputeInlineSizeForFragment( |
184 const NGConstraintSpace& constraintSpace, | 184 const NGConstraintSpace& constraintSpace, |
185 const ComputedStyle& style) { | 185 const ComputedStyle& style) { |
186 if (constraintSpace.FixedInlineSize()) | 186 if (constraintSpace.FixedInlineSize()) |
187 return constraintSpace.ContainerSize().inline_size; | 187 return constraintSpace.ContainerSize().inline_size; |
188 | 188 |
189 LayoutUnit extent = | 189 LayoutUnit extent = |
190 resolveInlineLength(constraintSpace, style, style.logicalWidth(), | 190 ResolveInlineLength(constraintSpace, style, style.logicalWidth(), |
191 LengthResolveType::ContentSize); | 191 LengthResolveType::ContentSize); |
192 | 192 |
193 Length maxLength = style.logicalMaxWidth(); | 193 Length maxLength = style.logicalMaxWidth(); |
194 if (!maxLength.isMaxSizeNone()) { | 194 if (!maxLength.isMaxSizeNone()) { |
195 LayoutUnit max = resolveInlineLength(constraintSpace, style, maxLength, | 195 LayoutUnit max = ResolveInlineLength(constraintSpace, style, maxLength, |
196 LengthResolveType::MaxSize); | 196 LengthResolveType::MaxSize); |
197 extent = std::min(extent, max); | 197 extent = std::min(extent, max); |
198 } | 198 } |
199 | 199 |
200 LayoutUnit min = | 200 LayoutUnit min = |
201 resolveInlineLength(constraintSpace, style, style.logicalMinWidth(), | 201 ResolveInlineLength(constraintSpace, style, style.logicalMinWidth(), |
202 LengthResolveType::MinSize); | 202 LengthResolveType::MinSize); |
203 extent = std::max(extent, min); | 203 extent = std::max(extent, min); |
204 return extent; | 204 return extent; |
205 } | 205 } |
206 | 206 |
207 LayoutUnit computeBlockSizeForFragment(const NGConstraintSpace& constraintSpace, | 207 LayoutUnit ComputeBlockSizeForFragment(const NGConstraintSpace& constraintSpace, |
208 const ComputedStyle& style, | 208 const ComputedStyle& style, |
209 LayoutUnit contentSize) { | 209 LayoutUnit contentSize) { |
210 if (constraintSpace.FixedBlockSize()) | 210 if (constraintSpace.FixedBlockSize()) |
211 return constraintSpace.ContainerSize().block_size; | 211 return constraintSpace.ContainerSize().block_size; |
212 | 212 |
213 LayoutUnit extent = | 213 LayoutUnit extent = |
214 resolveBlockLength(constraintSpace, style, style.logicalHeight(), | 214 ResolveBlockLength(constraintSpace, style, style.logicalHeight(), |
215 contentSize, LengthResolveType::ContentSize); | 215 contentSize, LengthResolveType::ContentSize); |
216 if (extent == NGSizeIndefinite) { | 216 if (extent == NGSizeIndefinite) { |
217 DCHECK_EQ(contentSize, NGSizeIndefinite); | 217 DCHECK_EQ(contentSize, NGSizeIndefinite); |
218 return extent; | 218 return extent; |
219 } | 219 } |
220 | 220 |
221 Length maxLength = style.logicalMaxHeight(); | 221 Length maxLength = style.logicalMaxHeight(); |
222 if (!maxLength.isMaxSizeNone()) { | 222 if (!maxLength.isMaxSizeNone()) { |
223 LayoutUnit max = | 223 LayoutUnit max = |
224 resolveBlockLength(constraintSpace, style, maxLength, contentSize, | 224 ResolveBlockLength(constraintSpace, style, maxLength, contentSize, |
225 LengthResolveType::MaxSize); | 225 LengthResolveType::MaxSize); |
226 extent = std::min(extent, max); | 226 extent = std::min(extent, max); |
227 } | 227 } |
228 | 228 |
229 LayoutUnit min = | 229 LayoutUnit min = |
230 resolveBlockLength(constraintSpace, style, style.logicalMinHeight(), | 230 ResolveBlockLength(constraintSpace, style, style.logicalMinHeight(), |
231 contentSize, LengthResolveType::MinSize); | 231 contentSize, LengthResolveType::MinSize); |
232 extent = std::max(extent, min); | 232 extent = std::max(extent, min); |
233 return extent; | 233 return extent; |
234 } | 234 } |
235 | 235 |
236 NGBoxStrut computeMargins(const NGConstraintSpace& constraintSpace, | 236 NGBoxStrut ComputeMargins(const NGConstraintSpace& constraintSpace, |
237 const ComputedStyle& style, | 237 const ComputedStyle& style, |
238 const NGWritingMode writing_mode, | 238 const NGWritingMode writing_mode, |
239 const NGDirection direction) { | 239 const NGDirection direction) { |
240 // Margins always get computed relative to the inline size: | 240 // Margins always get computed relative to the inline size: |
241 // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width | 241 // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width |
242 NGPhysicalDimensions physical_dim; | 242 NGPhysicalDimensions physical_dim; |
243 physical_dim.left = | 243 physical_dim.left = |
244 resolveInlineLength(constraintSpace, style, style.marginLeft(), | 244 ResolveInlineLength(constraintSpace, style, style.marginLeft(), |
245 LengthResolveType::MarginBorderPaddingSize); | 245 LengthResolveType::MarginBorderPaddingSize); |
246 physical_dim.right = | 246 physical_dim.right = |
247 resolveInlineLength(constraintSpace, style, style.marginRight(), | 247 ResolveInlineLength(constraintSpace, style, style.marginRight(), |
248 LengthResolveType::MarginBorderPaddingSize); | 248 LengthResolveType::MarginBorderPaddingSize); |
249 physical_dim.top = | 249 physical_dim.top = |
250 resolveInlineLength(constraintSpace, style, style.marginTop(), | 250 ResolveInlineLength(constraintSpace, style, style.marginTop(), |
251 LengthResolveType::MarginBorderPaddingSize); | 251 LengthResolveType::MarginBorderPaddingSize); |
252 physical_dim.bottom = | 252 physical_dim.bottom = |
253 resolveInlineLength(constraintSpace, style, style.marginBottom(), | 253 ResolveInlineLength(constraintSpace, style, style.marginBottom(), |
254 LengthResolveType::MarginBorderPaddingSize); | 254 LengthResolveType::MarginBorderPaddingSize); |
255 return ToLogicalDimensions(physical_dim, writing_mode, direction); | 255 return ToLogicalDimensions(physical_dim, writing_mode, direction); |
256 } | 256 } |
257 | 257 |
258 NGBoxStrut computeBorders(const ComputedStyle& style) { | 258 NGBoxStrut ComputeBorders(const ComputedStyle& style) { |
259 NGBoxStrut borders; | 259 NGBoxStrut borders; |
260 borders.inline_start = LayoutUnit(style.borderStartWidth()); | 260 borders.inline_start = LayoutUnit(style.borderStartWidth()); |
261 borders.inline_end = LayoutUnit(style.borderEndWidth()); | 261 borders.inline_end = LayoutUnit(style.borderEndWidth()); |
262 borders.block_start = LayoutUnit(style.borderBeforeWidth()); | 262 borders.block_start = LayoutUnit(style.borderBeforeWidth()); |
263 borders.block_end = LayoutUnit(style.borderAfterWidth()); | 263 borders.block_end = LayoutUnit(style.borderAfterWidth()); |
264 return borders; | 264 return borders; |
265 } | 265 } |
266 | 266 |
267 NGBoxStrut computePadding(const NGConstraintSpace& constraintSpace, | 267 NGBoxStrut ComputePadding(const NGConstraintSpace& constraintSpace, |
268 const ComputedStyle& style) { | 268 const ComputedStyle& style) { |
269 // Padding always gets computed relative to the inline size: | 269 // Padding always gets computed relative to the inline size: |
270 // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width | 270 // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width |
271 NGBoxStrut padding; | 271 NGBoxStrut padding; |
272 padding.inline_start = | 272 padding.inline_start = |
273 resolveInlineLength(constraintSpace, style, style.paddingStart(), | 273 ResolveInlineLength(constraintSpace, style, style.paddingStart(), |
274 LengthResolveType::MarginBorderPaddingSize); | 274 LengthResolveType::MarginBorderPaddingSize); |
275 padding.inline_end = | 275 padding.inline_end = |
276 resolveInlineLength(constraintSpace, style, style.paddingEnd(), | 276 ResolveInlineLength(constraintSpace, style, style.paddingEnd(), |
277 LengthResolveType::MarginBorderPaddingSize); | 277 LengthResolveType::MarginBorderPaddingSize); |
278 padding.block_start = | 278 padding.block_start = |
279 resolveInlineLength(constraintSpace, style, style.paddingBefore(), | 279 ResolveInlineLength(constraintSpace, style, style.paddingBefore(), |
280 LengthResolveType::MarginBorderPaddingSize); | 280 LengthResolveType::MarginBorderPaddingSize); |
281 padding.block_end = | 281 padding.block_end = |
282 resolveInlineLength(constraintSpace, style, style.paddingAfter(), | 282 ResolveInlineLength(constraintSpace, style, style.paddingAfter(), |
283 LengthResolveType::MarginBorderPaddingSize); | 283 LengthResolveType::MarginBorderPaddingSize); |
284 return padding; | 284 return padding; |
285 } | 285 } |
286 | 286 |
287 void ApplyAutoMargins(const NGConstraintSpace& constraint_space, | 287 void ApplyAutoMargins(const NGConstraintSpace& constraint_space, |
288 const ComputedStyle& style, | 288 const ComputedStyle& style, |
289 const NGFragment& fragment, | 289 const NGFragment& fragment, |
290 NGBoxStrut& margins) { | 290 NGBoxStrut& margins) { |
291 const LayoutUnit used_space = fragment.InlineSize() + margins.InlineSum(); | 291 const LayoutUnit used_space = fragment.InlineSize() + margins.InlineSum(); |
292 const LayoutUnit available_space = | 292 const LayoutUnit available_space = |
293 constraint_space.ContainerSize().inline_size - used_space; | 293 constraint_space.ContainerSize().inline_size - used_space; |
294 if (available_space < LayoutUnit()) | 294 if (available_space < LayoutUnit()) |
295 return; | 295 return; |
296 if (style.marginStart().isAuto() && style.marginEnd().isAuto()) { | 296 if (style.marginStart().isAuto() && style.marginEnd().isAuto()) { |
297 margins.inline_start = available_space / 2; | 297 margins.inline_start = available_space / 2; |
298 margins.inline_end = available_space - margins.inline_start; | 298 margins.inline_end = available_space - margins.inline_start; |
299 } else if (style.marginStart().isAuto()) { | 299 } else if (style.marginStart().isAuto()) { |
300 margins.inline_start = available_space; | 300 margins.inline_start = available_space; |
301 } else if (style.marginEnd().isAuto()) { | 301 } else if (style.marginEnd().isAuto()) { |
302 margins.inline_end = available_space; | 302 margins.inline_end = available_space; |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 } // namespace blink | 306 } // namespace blink |
OLD | NEW |