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_block_layout_algorithm.h" | 5 #include "core/layout/ng/ng_block_layout_algorithm.h" |
6 | 6 |
7 #include "core/layout/ng/inline/ng_inline_node.h" | 7 #include "core/layout/ng/inline/ng_inline_node.h" |
8 #include "core/layout/ng/ng_absolute_utils.h" | 8 #include "core/layout/ng/ng_absolute_utils.h" |
9 #include "core/layout/ng/ng_block_child_iterator.h" | 9 #include "core/layout/ng/ng_block_child_iterator.h" |
10 #include "core/layout/ng/ng_constraint_space.h" | 10 #include "core/layout/ng/ng_constraint_space.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 | 60 |
61 // Whether we've run out of space in this flow. If so, there will be no work | 61 // Whether we've run out of space in this flow. If so, there will be no work |
62 // left to do for this block in this fragmentainer. | 62 // left to do for this block in this fragmentainer. |
63 bool IsOutOfSpace(const NGConstraintSpace& space, LayoutUnit content_size) { | 63 bool IsOutOfSpace(const NGConstraintSpace& space, LayoutUnit content_size) { |
64 return space.HasBlockFragmentation() && | 64 return space.HasBlockFragmentation() && |
65 content_size >= space.FragmentainerSpaceAvailable(); | 65 content_size >= space.FragmentainerSpaceAvailable(); |
66 } | 66 } |
67 | 67 |
68 } // namespace | 68 } // namespace |
69 | 69 |
70 // This struct is used for communicating to a child the position of the | |
71 // previous inflow child. | |
72 struct NGPreviousInflowPosition { | |
73 LayoutUnit bfc_block_offset; | |
74 LayoutUnit logical_block_offset; | |
75 NGMarginStrut margin_strut; | |
76 }; | |
77 | |
78 // This strut holds information for the current inflow child. The data is not | |
79 // useful outside of handling this single inflow child. | |
80 struct NGInflowChildData { | |
81 NGLogicalOffset bfc_offset_estimate; | |
82 NGMarginStrut margin_strut; | |
83 NGBoxStrut margins; | |
84 }; | |
85 | |
70 void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace& space, | 86 void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace& space, |
71 const NGLogicalOffset& offset, | 87 LayoutUnit bfc_block_offset, |
72 NGFragmentBuilder* builder) { | 88 NGFragmentBuilder* builder) { |
73 DCHECK(builder); | 89 DCHECK(builder); |
74 if (!builder->BfcOffset()) { | 90 if (!builder->BfcOffset()) { |
75 NGLogicalOffset mutable_offset(offset); | 91 NGLogicalOffset mutable_offset = {space.BfcOffset().inline_offset, |
Gleb Lanbin
2017/05/31 04:56:14
bfc_offset ?
ikilpatrick
2017/06/01 18:07:08
Done.
| |
92 bfc_block_offset}; | |
76 AdjustToClearance(space.ClearanceOffset(), &mutable_offset); | 93 AdjustToClearance(space.ClearanceOffset(), &mutable_offset); |
77 builder->SetBfcOffset(mutable_offset); | 94 builder->SetBfcOffset(mutable_offset); |
78 } | 95 } |
79 } | 96 } |
80 | 97 |
81 void PositionPendingFloatsFromOffset(LayoutUnit origin_block_offset, | 98 void PositionPendingFloatsFromOffset(LayoutUnit origin_block_offset, |
82 LayoutUnit from_block_offset, | 99 LayoutUnit from_block_offset, |
83 NGFragmentBuilder* container_builder, | 100 NGFragmentBuilder* container_builder, |
84 NGConstraintSpace* space) { | 101 NGConstraintSpace* space) { |
85 DCHECK(container_builder->BfcOffset()) | 102 DCHECK(container_builder->BfcOffset()) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 | 160 |
144 sizes.min_content = std::max(sizes.min_content, child_sizes.min_content); | 161 sizes.min_content = std::max(sizes.min_content, child_sizes.min_content); |
145 sizes.max_content = std::max(sizes.max_content, child_sizes.max_content); | 162 sizes.max_content = std::max(sizes.max_content, child_sizes.max_content); |
146 } | 163 } |
147 | 164 |
148 sizes.max_content = std::max(sizes.min_content, sizes.max_content); | 165 sizes.max_content = std::max(sizes.min_content, sizes.max_content); |
149 return sizes; | 166 return sizes; |
150 } | 167 } |
151 | 168 |
152 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset( | 169 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset( |
170 const NGBoxStrut& child_margins, | |
153 const WTF::Optional<NGLogicalOffset>& known_fragment_offset) { | 171 const WTF::Optional<NGLogicalOffset>& known_fragment_offset) { |
154 if (known_fragment_offset) | 172 if (known_fragment_offset) |
155 return known_fragment_offset.value() - ContainerBfcOffset(); | 173 return known_fragment_offset.value() - ContainerBfcOffset(); |
156 LayoutUnit inline_offset = | 174 LayoutUnit inline_offset = |
157 border_and_padding_.inline_start + curr_child_margins_.inline_start; | 175 border_and_padding_.inline_start + child_margins.inline_start; |
176 // TODO(ikilpatrick): Using the content_size_ here looks suspicious - check. | |
158 return {inline_offset, content_size_}; | 177 return {inline_offset, content_size_}; |
159 } | 178 } |
160 | 179 |
161 RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { | 180 RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { |
162 WTF::Optional<MinMaxContentSize> min_max_size; | 181 WTF::Optional<MinMaxContentSize> min_max_size; |
163 if (NeedMinMaxContentSize(ConstraintSpace(), Style())) | 182 if (NeedMinMaxContentSize(ConstraintSpace(), Style())) |
164 min_max_size = ComputeMinMaxContentSize(); | 183 min_max_size = ComputeMinMaxContentSize(); |
165 | 184 |
166 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) + | 185 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) + |
167 ComputePadding(ConstraintSpace(), Style()); | 186 ComputePadding(ConstraintSpace(), Style()); |
(...skipping 24 matching lines...) Expand all Loading... | |
192 | 211 |
193 NGBlockChildIterator child_iterator(Node()->FirstChild(), BreakToken()); | 212 NGBlockChildIterator child_iterator(Node()->FirstChild(), BreakToken()); |
194 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); | 213 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); |
195 NGLayoutInputNode* child = entry.node; | 214 NGLayoutInputNode* child = entry.node; |
196 NGBreakToken* child_break_token = entry.token; | 215 NGBreakToken* child_break_token = entry.token; |
197 | 216 |
198 // If we are resuming from a break token our start border and padding is | 217 // If we are resuming from a break token our start border and padding is |
199 // within a previous fragment. | 218 // within a previous fragment. |
200 content_size_ = BreakToken() ? LayoutUnit() : border_and_padding_.block_start; | 219 content_size_ = BreakToken() ? LayoutUnit() : border_and_padding_.block_start; |
201 | 220 |
202 curr_margin_strut_ = ConstraintSpace().MarginStrut(); | 221 NGMarginStrut input_margin_strut = ConstraintSpace().MarginStrut(); |
203 curr_bfc_offset_ = ConstraintSpace().BfcOffset(); | 222 LayoutUnit input_bfc_block_offset = |
223 ConstraintSpace().BfcOffset().block_offset; | |
204 | 224 |
205 // Margins collapsing: | 225 // Margins collapsing: |
206 // Do not collapse margins between parent and its child if there is | 226 // Do not collapse margins between parent and its child if there is |
207 // border/padding between them. | 227 // border/padding between them. |
208 if (border_and_padding_.block_start) { | 228 if (border_and_padding_.block_start) { |
209 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); | 229 input_bfc_block_offset += input_margin_strut.Sum(); |
210 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, | 230 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), input_bfc_block_offset, |
211 &container_builder_); | 231 &container_builder_); |
212 curr_margin_strut_ = NGMarginStrut(); | 232 // We reset the block offset here as it may have been effected by clearance. |
233 input_bfc_block_offset = ContainerBfcOffset().block_offset; | |
234 input_margin_strut = NGMarginStrut(); | |
213 } | 235 } |
214 | 236 |
215 // If a new formatting context hits the margin collapsing if-branch above | 237 // If a new formatting context hits the margin collapsing if-branch above |
216 // then the BFC offset is still {} as the margin strut from the constraint | 238 // then the BFC offset is still {} as the margin strut from the constraint |
217 // space must also be empty. | 239 // space must also be empty. |
218 // If we are resuming layout from a break token the same rule applies. Margin | 240 // If we are resuming layout from a break token the same rule applies. Margin |
219 // struts cannot pass through break tokens. | 241 // struts cannot pass through break tokens. |
220 if (ConstraintSpace().IsNewFormattingContext() || BreakToken()) { | 242 if (ConstraintSpace().IsNewFormattingContext() || BreakToken()) { |
221 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, | 243 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), input_bfc_block_offset, |
222 &container_builder_); | 244 &container_builder_); |
223 DCHECK_EQ(curr_margin_strut_, NGMarginStrut()); | 245 DCHECK_EQ(input_margin_strut, NGMarginStrut()); |
224 DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset()); | 246 DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset()); |
225 curr_bfc_offset_ = {}; | |
226 } | 247 } |
227 | 248 |
228 curr_bfc_offset_.block_offset += content_size_; | 249 input_bfc_block_offset += content_size_; |
250 | |
251 NGPreviousInflowPosition previous_inflow_position = { | |
252 input_bfc_block_offset, content_size_, input_margin_strut}; | |
229 | 253 |
230 while (child) { | 254 while (child) { |
231 if (child->IsOutOfFlowPositioned()) { | 255 if (child->IsOutOfFlowPositioned()) { |
232 DCHECK(!child_break_token); | 256 DCHECK(!child_break_token); |
233 HandleOutOfFlowPositioned(ToNGBlockNode(child)); | 257 HandleOutOfFlowPositioned(previous_inflow_position, ToNGBlockNode(child)); |
234 } else if (child->IsFloating()) { | 258 } else if (child->IsFloating()) { |
235 HandleFloating(ToNGBlockNode(child), | 259 HandleFloating(previous_inflow_position, ToNGBlockNode(child), |
236 ToNGBlockBreakToken(child_break_token)); | 260 ToNGBlockBreakToken(child_break_token)); |
237 } else { | 261 } else { |
238 NGLogicalOffset child_bfc_offset = PrepareChildLayout(child); | 262 NGInflowChildData child_data = |
263 PrepareChildLayout(previous_inflow_position, child); | |
239 RefPtr<NGConstraintSpace> child_space = | 264 RefPtr<NGConstraintSpace> child_space = |
240 CreateConstraintSpaceForChild(child_bfc_offset, *child); | 265 CreateConstraintSpaceForChild(*child, child_data); |
241 RefPtr<NGLayoutResult> layout_result = | 266 RefPtr<NGLayoutResult> layout_result = |
242 child->Layout(child_space.Get(), child_break_token); | 267 child->Layout(child_space.Get(), child_break_token); |
243 FinishChildLayout(*child_space, child, layout_result.Get()); | 268 previous_inflow_position = |
269 FinishChildLayout(*child_space, previous_inflow_position, child_data, | |
270 child, layout_result.Get()); | |
244 } | 271 } |
245 | 272 |
246 entry = child_iterator.NextChild(); | 273 entry = child_iterator.NextChild(); |
247 child = entry.node; | 274 child = entry.node; |
248 child_break_token = entry.token; | 275 child_break_token = entry.token; |
249 | 276 |
250 if (IsOutOfSpace(ConstraintSpace(), content_size_)) | 277 if (IsOutOfSpace(ConstraintSpace(), content_size_)) |
251 break; | 278 break; |
252 } | 279 } |
253 | 280 |
281 NGMarginStrut end_margin_strut = previous_inflow_position.margin_strut; | |
282 LayoutUnit end_bfc_block_offset = previous_inflow_position.bfc_block_offset; | |
283 | |
254 // Margins collapsing: | 284 // Margins collapsing: |
255 // Bottom margins of an in-flow block box doesn't collapse with its last | 285 // Bottom margins of an in-flow block box doesn't collapse with its last |
256 // in-flow block-level child's bottom margin if the box has bottom | 286 // in-flow block-level child's bottom margin if the box has bottom |
257 // border/padding. | 287 // border/padding. |
258 content_size_ += border_and_padding_.block_end; | 288 content_size_ += border_and_padding_.block_end; |
259 if (border_and_padding_.block_end || | 289 if (border_and_padding_.block_end || |
260 ConstraintSpace().IsNewFormattingContext()) { | 290 ConstraintSpace().IsNewFormattingContext()) { |
261 content_size_ += curr_margin_strut_.Sum(); | 291 content_size_ += end_margin_strut.Sum(); |
262 curr_margin_strut_ = NGMarginStrut(); | 292 end_margin_strut = NGMarginStrut(); |
263 } | 293 } |
264 | 294 |
265 // Recompute the block-axis size now that we know our content size. | 295 // Recompute the block-axis size now that we know our content size. |
266 size.block_size = | 296 size.block_size = |
267 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); | 297 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); |
268 container_builder_.SetBlockSize(size.block_size); | 298 container_builder_.SetBlockSize(size.block_size); |
269 | 299 |
270 // Layout our absolute and fixed positioned children. | 300 // Layout our absolute and fixed positioned children. |
271 NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &container_builder_).Run(); | 301 NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &container_builder_).Run(); |
272 | 302 |
273 // Non-empty blocks always know their position in space. | 303 // Non-empty blocks always know their position in space. |
274 // TODO(ikilpatrick): This check for a break token seems error prone. | 304 // TODO(ikilpatrick): This check for a break token seems error prone. |
275 if (size.block_size || BreakToken()) { | 305 if (size.block_size || BreakToken()) { |
276 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); | 306 end_bfc_block_offset += end_margin_strut.Sum(); |
277 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, | 307 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), end_bfc_block_offset, |
278 &container_builder_); | 308 &container_builder_); |
279 PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, | 309 PositionPendingFloats(end_bfc_block_offset, &container_builder_, |
280 MutableConstraintSpace()); | 310 MutableConstraintSpace()); |
281 } | 311 } |
282 | 312 |
283 // Margins collapsing: | 313 // Margins collapsing: |
284 // Do not collapse margins between the last in-flow child and bottom margin | 314 // Do not collapse margins between the last in-flow child and bottom margin |
285 // of its parent if the parent has height != auto() | 315 // of its parent if the parent has height != auto() |
286 if (!Style().LogicalHeight().IsAuto()) { | 316 if (!Style().LogicalHeight().IsAuto()) { |
287 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight. | 317 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight. |
288 curr_margin_strut_ = NGMarginStrut(); | 318 end_margin_strut = NGMarginStrut(); |
289 } | 319 } |
290 container_builder_.SetEndMarginStrut(curr_margin_strut_); | 320 container_builder_.SetEndMarginStrut(end_margin_strut); |
291 | 321 |
292 container_builder_.SetOverflowSize( | 322 container_builder_.SetOverflowSize( |
293 NGLogicalSize(max_inline_size_, content_size_)); | 323 NGLogicalSize(max_inline_size_, content_size_)); |
294 | 324 |
295 // We only finalize for fragmentation if the fragment has a BFC offset. This | 325 // We only finalize for fragmentation if the fragment has a BFC offset. This |
296 // may occur with a zero block size fragment. We need to know the BFC offset | 326 // may occur with a zero block size fragment. We need to know the BFC offset |
297 // to determine where the fragmentation line is relative to us. | 327 // to determine where the fragmentation line is relative to us. |
298 if (container_builder_.BfcOffset() && | 328 if (container_builder_.BfcOffset() && |
299 ConstraintSpace().HasBlockFragmentation()) | 329 ConstraintSpace().HasBlockFragmentation()) |
300 FinalizeForFragmentation(); | 330 FinalizeForFragmentation(); |
301 | 331 |
302 return container_builder_.ToBoxFragment(); | 332 return container_builder_.ToBoxFragment(); |
303 } | 333 } |
304 | 334 |
305 void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode* child) { | 335 void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned( |
306 NGLogicalOffset offset = {border_and_padding_.inline_start, content_size_}; | 336 const NGPreviousInflowPosition& previous_inflow_position, |
337 NGBlockNode* child) { | |
338 NGLogicalOffset offset = {border_and_padding_.inline_start, | |
339 previous_inflow_position.logical_block_offset}; | |
307 | 340 |
308 // We only include the margin strut in the OOF static-position if we know we | 341 // We only include the margin strut in the OOF static-position if we know we |
309 // aren't going to be a zero-block-size fragment. | 342 // aren't going to be a zero-block-size fragment. |
310 if (container_builder_.BfcOffset()) | 343 if (container_builder_.BfcOffset()) |
311 offset.block_offset += curr_margin_strut_.Sum(); | 344 offset.block_offset += previous_inflow_position.margin_strut.Sum(); |
312 | 345 |
313 container_builder_.AddOutOfFlowChildCandidate(child, offset); | 346 container_builder_.AddOutOfFlowChildCandidate(child, offset); |
314 } | 347 } |
315 | 348 |
316 void NGBlockLayoutAlgorithm::HandleFloating(NGBlockNode* child, | 349 void NGBlockLayoutAlgorithm::HandleFloating( |
317 NGBlockBreakToken* token) { | 350 const NGPreviousInflowPosition& previous_inflow_position, |
318 // TODO(ikilpatrick): Pass in BFC offset from previous in-flow child. | 351 NGBlockNode* child, |
319 curr_bfc_offset_ = container_builder_.BfcOffset() | 352 NGBlockBreakToken* token) { |
320 ? container_builder_.BfcOffset().value() | |
321 : ConstraintSpace().BfcOffset(); | |
322 curr_bfc_offset_.block_offset += content_size_; | |
323 | |
324 // Calculate margins in the BFC's writing mode. | 353 // Calculate margins in the BFC's writing mode. |
325 curr_child_margins_ = CalculateMargins(child); | 354 NGBoxStrut margins = CalculateMargins(child); |
326 | 355 |
327 NGLogicalOffset origin_offset = constraint_space_->BfcOffset(); | 356 NGLogicalOffset origin_offset = constraint_space_->BfcOffset(); |
328 origin_offset.inline_offset += border_and_padding_.inline_start; | 357 origin_offset.inline_offset += border_and_padding_.inline_start; |
329 RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create( | 358 RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create( |
330 child_available_size_, child_percentage_size_, origin_offset, | 359 child_available_size_, child_percentage_size_, origin_offset, |
331 constraint_space_->BfcOffset(), curr_child_margins_, child, token); | 360 constraint_space_->BfcOffset(), margins, child, token); |
332 container_builder_.AddUnpositionedFloat(unpositioned_float); | 361 container_builder_.AddUnpositionedFloat(unpositioned_float); |
333 | 362 |
334 // If there is a break token for a float we must be resuming layout, we must | 363 // If there is a break token for a float we must be resuming layout, we must |
335 // always know our position in the BFC. | 364 // always know our position in the BFC. |
336 DCHECK(!token || container_builder_.BfcOffset()); | 365 DCHECK(!token || container_builder_.BfcOffset()); |
337 | 366 |
338 // No need to postpone the positioning if we know the correct offset. | 367 // No need to postpone the positioning if we know the correct offset. |
339 if (container_builder_.BfcOffset()) { | 368 if (container_builder_.BfcOffset()) { |
340 NGLogicalOffset origin_point = curr_bfc_offset_; | |
341 // Adjust origin point to the margins of the last child. | 369 // Adjust origin point to the margins of the last child. |
342 // Example: <div style="margin-bottom: 20px"><float></div> | 370 // Example: <div style="margin-bottom: 20px"><float></div> |
343 // <div style="margin-bottom: 30px"></div> | 371 // <div style="margin-bottom: 30px"></div> |
344 origin_point.block_offset += curr_margin_strut_.Sum(); | 372 LayoutUnit origin_block_offset = |
345 PositionPendingFloats(origin_point.block_offset, &container_builder_, | 373 previous_inflow_position.bfc_block_offset + |
374 previous_inflow_position.margin_strut.Sum(); | |
375 PositionPendingFloats(origin_block_offset, &container_builder_, | |
346 MutableConstraintSpace()); | 376 MutableConstraintSpace()); |
347 } | 377 } |
348 } | 378 } |
349 | 379 |
350 NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout( | 380 NGInflowChildData NGBlockLayoutAlgorithm::PrepareChildLayout( |
381 const NGPreviousInflowPosition& previous_inflow_position, | |
351 NGLayoutInputNode* child) { | 382 NGLayoutInputNode* child) { |
352 DCHECK(child); | 383 DCHECK(child); |
353 DCHECK(!child->IsFloating()); | 384 DCHECK(!child->IsFloating()); |
354 | 385 |
355 // TODO(ikilpatrick): Pass in BFC offset from previous in-flow child. | 386 LayoutUnit bfc_block_offset = previous_inflow_position.bfc_block_offset; |
356 curr_bfc_offset_ = container_builder_.BfcOffset() | |
357 ? container_builder_.BfcOffset().value() | |
358 : ConstraintSpace().BfcOffset(); | |
359 curr_bfc_offset_.block_offset += content_size_; | |
360 | 387 |
361 // Calculate margins in parent's writing mode. | 388 // Calculate margins in parent's writing mode. |
362 curr_child_margins_ = CalculateMargins(child); | 389 NGBoxStrut margins = CalculateMargins(child); |
390 NGMarginStrut margin_strut = previous_inflow_position.margin_strut; | |
363 | 391 |
364 bool should_position_pending_floats = | 392 bool should_position_pending_floats = |
365 !IsNewFormattingContextForBlockLevelChild(Style(), *child) && | 393 !IsNewFormattingContextForBlockLevelChild(Style(), *child) && |
366 ClearanceMayAffectLayout(ConstraintSpace(), | 394 ClearanceMayAffectLayout(ConstraintSpace(), |
367 container_builder_.UnpositionedFloats(), | 395 container_builder_.UnpositionedFloats(), |
368 child->Style()); | 396 child->Style()); |
369 | 397 |
370 // Children which may clear a float need to force all the pending floats to | 398 // Children which may clear a float need to force all the pending floats to |
371 // be positioned before layout. This also resolves the fragment's bfc offset. | 399 // be positioned before layout. This also resolves the fragment's bfc offset. |
372 if (should_position_pending_floats) { | 400 if (should_position_pending_floats) { |
373 LayoutUnit origin_point_block_offset = | 401 LayoutUnit origin_point_block_offset = |
374 curr_bfc_offset_.block_offset + curr_margin_strut_.Sum(); | 402 bfc_block_offset + margin_strut.Sum(); |
375 MaybeUpdateFragmentBfcOffset( | 403 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), origin_point_block_offset, |
376 ConstraintSpace(), | 404 &container_builder_); |
377 {curr_bfc_offset_.inline_offset, origin_point_block_offset}, | 405 // TODO(ikilpatrick): Check if origin_point_block_offset is correct - |
378 &container_builder_); | 406 // MaybeUpdateFragmentBfcOffset might have changed it due to clearance. |
379 PositionPendingFloats(origin_point_block_offset, &container_builder_, | 407 PositionPendingFloats(origin_point_block_offset, &container_builder_, |
380 MutableConstraintSpace()); | 408 MutableConstraintSpace()); |
381 } | 409 } |
382 | 410 |
383 NGLogicalOffset child_bfc_offset = curr_bfc_offset_; | 411 NGLogicalOffset child_bfc_offset = { |
384 child_bfc_offset.inline_offset += | 412 ConstraintSpace().BfcOffset().inline_offset + |
385 {border_and_padding_.inline_start + curr_child_margins_.inline_start}; | 413 border_and_padding_.inline_start + margins.inline_start, |
414 bfc_block_offset}; | |
415 | |
416 bool is_new_fc = IsNewFormattingContextForBlockLevelChild(Style(), *child); | |
386 | 417 |
387 // Append the current margin strut with child's block start margin. | 418 // Append the current margin strut with child's block start margin. |
388 // Non empty border/padding, and new FC use cases are handled inside of the | 419 // Non empty border/padding, and new FC use cases are handled inside of the |
389 // child's layout. | 420 // child's layout. |
390 if (!IsNewFormattingContextForBlockLevelChild(Style(), *child)) | 421 if (!is_new_fc) |
391 curr_margin_strut_.Append(curr_child_margins_.block_start); | 422 margin_strut.Append(margins.block_start); |
392 | 423 |
393 // TODO(crbug.com/716930): We should also collapse margins below once we | 424 // TODO(crbug.com/716930): We should also collapse margins below once we |
394 // remove LayoutInline splitting. | 425 // remove LayoutInline splitting. |
395 | 426 |
396 // Should collapse margins if our child is a legacy block. | 427 // Should collapse margins if our child is a legacy block. |
397 if (IsLegacyBlock(*child)) { | 428 // TODO(ikilpatrick): I think this can be removed. |
398 curr_bfc_offset_ += | 429 if (IsLegacyBlock(*child) && !is_new_fc) { |
399 {border_and_padding_.inline_start + curr_child_margins_.inline_start, | 430 child_bfc_offset.block_offset += margin_strut.Sum(); |
400 curr_margin_strut_.Sum()}; | 431 MaybeUpdateFragmentBfcOffset( |
401 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, | 432 ConstraintSpace(), child_bfc_offset.block_offset, &container_builder_); |
402 &container_builder_); | 433 // TODO(ikilpatrick): Check if child_bfc_offset.block_offset is correct - |
403 PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, | 434 // MaybeUpdateFragmentBfcOffset might have changed it due to clearance. |
435 PositionPendingFloats(child_bfc_offset.block_offset, &container_builder_, | |
404 MutableConstraintSpace()); | 436 MutableConstraintSpace()); |
405 curr_margin_strut_ = {}; | 437 margin_strut = {}; |
406 } | 438 } |
407 child_bfc_offset.block_offset = curr_bfc_offset_.block_offset; | 439 return {child_bfc_offset, margin_strut, margins}; |
408 return child_bfc_offset; | |
409 } | 440 } |
410 | 441 |
411 void NGBlockLayoutAlgorithm::FinishChildLayout( | 442 NGPreviousInflowPosition NGBlockLayoutAlgorithm::FinishChildLayout( |
412 const NGConstraintSpace& child_space, | 443 const NGConstraintSpace& child_space, |
444 const NGPreviousInflowPosition& previous_inflow_position, | |
445 const NGInflowChildData& child_data, | |
413 const NGLayoutInputNode* child, | 446 const NGLayoutInputNode* child, |
414 NGLayoutResult* layout_result) { | 447 NGLayoutResult* layout_result) { |
415 // Pull out unpositioned floats to the current fragment. This may needed if | 448 // Pull out unpositioned floats to the current fragment. This may needed if |
416 // for example the child fragment could not position its floats because it's | 449 // for example the child fragment could not position its floats because it's |
417 // empty and therefore couldn't determine its position in space. | 450 // empty and therefore couldn't determine its position in space. |
418 container_builder_.MutableUnpositionedFloats().AppendVector( | 451 container_builder_.MutableUnpositionedFloats().AppendVector( |
419 layout_result->UnpositionedFloats()); | 452 layout_result->UnpositionedFloats()); |
420 | 453 |
421 NGBoxFragment fragment( | 454 NGBoxFragment fragment( |
422 ConstraintSpace().WritingMode(), | 455 ConstraintSpace().WritingMode(), |
423 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get())); | 456 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get())); |
424 | 457 |
425 // Determine the fragment's position in the parent space. | 458 // Determine the fragment's position in the parent space. |
426 WTF::Optional<NGLogicalOffset> child_bfc_offset; | 459 WTF::Optional<NGLogicalOffset> child_bfc_offset; |
427 if (child_space.IsNewFormattingContext()) | 460 if (child_space.IsNewFormattingContext()) |
428 child_bfc_offset = PositionNewFc(fragment, child_space); | 461 child_bfc_offset = PositionNewFc(*child, previous_inflow_position, fragment, |
462 child_data, child_space); | |
429 else if (fragment.BfcOffset()) | 463 else if (fragment.BfcOffset()) |
430 child_bfc_offset = PositionWithBfcOffset(fragment); | 464 child_bfc_offset = PositionWithBfcOffset(fragment); |
431 else if (IsLegacyBlock(*child)) | 465 else if (IsLegacyBlock(*child)) |
432 child_bfc_offset = PositionLegacy(child_space); | 466 child_bfc_offset = PositionLegacy(child_space, child_data); |
433 else if (container_builder_.BfcOffset()) | 467 else if (container_builder_.BfcOffset()) |
434 child_bfc_offset = PositionWithParentBfc(child_space, fragment); | 468 child_bfc_offset = PositionWithParentBfc(child_space, child_data, fragment); |
435 | 469 |
436 NGLogicalOffset logical_offset = CalculateLogicalOffset(child_bfc_offset); | 470 NGLogicalOffset logical_offset = |
471 CalculateLogicalOffset(child_data.margins, child_bfc_offset); | |
437 | 472 |
438 // Update margin strut. | 473 NGMarginStrut margin_strut = fragment.EndMarginStrut(); |
439 curr_margin_strut_ = fragment.EndMarginStrut(); | 474 margin_strut.Append(child_data.margins.block_end); |
440 curr_margin_strut_.Append(curr_child_margins_.block_end); | |
441 | 475 |
442 // Only modify content_size if BlockSize is not empty. It's needed to prevent | 476 // Only modify content_size_ if the fragment's BlockSize is not empty. This is |
443 // the situation when logical_offset is included in content_size for empty | 477 // needed to prevent the situation when logical_offset is included in |
444 // blocks. Example: | 478 // content_size_ for empty blocks. Example: |
445 // <div style="overflow:hidden"> | 479 // <div style="overflow:hidden"> |
446 // <div style="margin-top: 8px"></div> | 480 // <div style="margin-top: 8px"></div> |
447 // <div style="margin-top: 10px"></div> | 481 // <div style="margin-top: 10px"></div> |
448 // </div> | 482 // </div> |
449 if (fragment.BlockSize()) | 483 if (fragment.BlockSize()) |
450 content_size_ = fragment.BlockSize() + logical_offset.block_offset; | 484 content_size_ = std::max( |
451 max_inline_size_ = | 485 content_size_, logical_offset.block_offset + fragment.BlockSize()); |
452 std::max(max_inline_size_, fragment.InlineSize() + | 486 max_inline_size_ = std::max( |
453 curr_child_margins_.InlineSum() + | 487 max_inline_size_, fragment.InlineSize() + child_data.margins.InlineSum() + |
454 border_and_padding_.InlineSum()); | 488 border_and_padding_.InlineSum()); |
455 | 489 |
456 container_builder_.AddChild(layout_result, logical_offset); | 490 container_builder_.AddChild(layout_result, logical_offset); |
491 | |
492 // Determine the child's end BFC block offset for the next child to use. | |
493 LayoutUnit child_end_bfc_block_offset; | |
494 if (child_bfc_offset) { | |
495 // TODO(crbug.com/716930): I think the fragment.BfcOffset() condition here | |
496 // can be removed once we've removed inline splitting. | |
497 if (fragment.BlockSize() || fragment.BfcOffset()) { | |
498 child_end_bfc_block_offset = | |
499 child_bfc_offset.value().block_offset + fragment.BlockSize(); | |
500 } else { | |
501 DCHECK_EQ(LayoutUnit(), fragment.BlockSize()); | |
502 child_end_bfc_block_offset = previous_inflow_position.bfc_block_offset; | |
503 } | |
504 } else { | |
505 child_end_bfc_block_offset = ConstraintSpace().BfcOffset().block_offset; | |
506 } | |
507 | |
508 return {child_end_bfc_block_offset, | |
509 logical_offset.block_offset + fragment.BlockSize(), margin_strut}; | |
457 } | 510 } |
458 | 511 |
459 NGLogicalOffset NGBlockLayoutAlgorithm::PositionNewFc( | 512 NGLogicalOffset NGBlockLayoutAlgorithm::PositionNewFc( |
513 const NGLayoutInputNode& child, | |
514 const NGPreviousInflowPosition& previous_inflow_position, | |
460 const NGBoxFragment& fragment, | 515 const NGBoxFragment& fragment, |
516 const NGInflowChildData& child_data, | |
461 const NGConstraintSpace& child_space) { | 517 const NGConstraintSpace& child_space) { |
518 const ComputedStyle& child_style = child.Style(); | |
519 | |
520 LayoutUnit child_bfc_offset_estimate = | |
521 child_data.bfc_offset_estimate.block_offset; | |
522 | |
462 // 1. Position all pending floats to a temporary space. | 523 // 1. Position all pending floats to a temporary space. |
463 RefPtr<NGConstraintSpace> tmp_space = | 524 RefPtr<NGConstraintSpace> tmp_space = |
464 NGConstraintSpaceBuilder(&child_space) | 525 NGConstraintSpaceBuilder(&child_space) |
465 .SetIsNewFormattingContext(false) | 526 .SetIsNewFormattingContext(false) |
466 .ToConstraintSpace(child_space.WritingMode()); | 527 .ToConstraintSpace(child_space.WritingMode()); |
467 PositionFloats(curr_bfc_offset_.block_offset, curr_bfc_offset_.block_offset, | 528 PositionFloats(child_bfc_offset_estimate, child_bfc_offset_estimate, |
468 curr_bfc_offset_.block_offset, | 529 child_bfc_offset_estimate, |
469 container_builder_.UnpositionedFloats(), tmp_space.Get()); | 530 container_builder_.UnpositionedFloats(), tmp_space.Get()); |
470 | 531 |
471 NGLogicalOffset origin_offset = curr_bfc_offset_; | 532 NGLogicalOffset origin_offset = {ConstraintSpace().BfcOffset().inline_offset + |
472 origin_offset.inline_offset += border_and_padding_.inline_start; | 533 border_and_padding_.inline_start, |
534 child_bfc_offset_estimate}; | |
535 AdjustToClearance( | |
536 GetClearanceOffset(ConstraintSpace().Exclusions(), child_style.Clear()), | |
537 &origin_offset); | |
473 | 538 |
474 // 2. Find an estimated layout opportunity for our fragment. | 539 // 2. Find an estimated layout opportunity for our fragment. |
475 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( | 540 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( |
476 tmp_space->Exclusions().get(), child_space.AvailableSize(), origin_offset, | 541 tmp_space->Exclusions().get(), child_space.AvailableSize(), origin_offset, |
477 curr_child_margins_, fragment.Size()); | 542 child_data.margins, fragment.Size()); |
543 | |
544 NGMarginStrut margin_strut = previous_inflow_position.margin_strut; | |
478 | 545 |
479 // 3. If the found opportunity lies on the same line with our estimated | 546 // 3. If the found opportunity lies on the same line with our estimated |
480 // child's BFC offset then merge fragment's margins with the current | 547 // child's BFC offset then merge fragment's margins with the current |
481 // MarginStrut. | 548 // MarginStrut. |
482 if (opportunity.offset.block_offset == curr_bfc_offset_.block_offset) | 549 if (opportunity.offset.block_offset == child_bfc_offset_estimate) |
483 curr_margin_strut_.Append(curr_child_margins_.block_start); | 550 margin_strut.Append(child_data.margins.block_start); |
484 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); | 551 child_bfc_offset_estimate += margin_strut.Sum(); |
485 curr_margin_strut_ = {}; | |
486 | 552 |
487 // 4. The child's BFC block offset is known here. | 553 // 4. The child's BFC block offset is known here. |
488 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, | 554 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), child_bfc_offset_estimate, |
489 &container_builder_); | 555 &container_builder_); |
490 PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, | 556 PositionPendingFloats(child_bfc_offset_estimate, &container_builder_, |
491 MutableConstraintSpace()); | 557 MutableConstraintSpace()); |
492 | 558 |
493 origin_offset = curr_bfc_offset_; | 559 origin_offset = {ConstraintSpace().BfcOffset().inline_offset + |
494 origin_offset.inline_offset += border_and_padding_.inline_start; | 560 border_and_padding_.inline_start, |
561 child_bfc_offset_estimate}; | |
562 AdjustToClearance( | |
563 GetClearanceOffset(ConstraintSpace().Exclusions(), child_style.Clear()), | |
564 &origin_offset); | |
495 | 565 |
496 // 5. Find the final layout opportunity for the fragment after all pending | 566 // 5. Find the final layout opportunity for the fragment after all pending |
497 // floats are positioned at the correct BFC block's offset. | 567 // floats are positioned at the correct BFC block's offset. |
498 opportunity = FindLayoutOpportunityForFragment( | 568 opportunity = FindLayoutOpportunityForFragment( |
499 MutableConstraintSpace()->Exclusions().get(), child_space.AvailableSize(), | 569 MutableConstraintSpace()->Exclusions().get(), child_space.AvailableSize(), |
500 origin_offset, curr_child_margins_, fragment.Size()); | 570 origin_offset, child_data.margins, fragment.Size()); |
501 | 571 |
502 curr_bfc_offset_ = opportunity.offset; | 572 return opportunity.offset; |
503 return curr_bfc_offset_; | |
504 } | 573 } |
505 | 574 |
506 NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithBfcOffset( | 575 NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithBfcOffset( |
507 const NGBoxFragment& fragment) { | 576 const NGBoxFragment& fragment) { |
508 DCHECK(fragment.BfcOffset()); | 577 DCHECK(fragment.BfcOffset()); |
509 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; | 578 LayoutUnit bfc_block_offset = fragment.BfcOffset().value().block_offset; |
510 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, | 579 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_block_offset, |
511 &container_builder_); | 580 &container_builder_); |
512 PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, | 581 PositionPendingFloats(bfc_block_offset, &container_builder_, |
513 MutableConstraintSpace()); | 582 MutableConstraintSpace()); |
514 return fragment.BfcOffset().value(); | 583 return fragment.BfcOffset().value(); |
515 } | 584 } |
516 | 585 |
517 NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc( | 586 NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc( |
518 const NGConstraintSpace& space, | 587 const NGConstraintSpace& space, |
588 const NGInflowChildData& child_data, | |
519 const NGBoxFragment& fragment) { | 589 const NGBoxFragment& fragment) { |
520 // The child must be an in-flow zero-block-size fragment, use its end margin | 590 // The child must be an in-flow zero-block-size fragment, use its end margin |
521 // strut for positioning. | 591 // strut for positioning. |
522 DCHECK(!fragment.BfcOffset()); | 592 DCHECK(!fragment.BfcOffset()); |
523 DCHECK_EQ(fragment.BlockSize(), LayoutUnit()); | 593 DCHECK_EQ(fragment.BlockSize(), LayoutUnit()); |
524 | 594 |
525 NGMarginStrut margin_strut = fragment.EndMarginStrut(); | 595 NGMarginStrut margin_strut = fragment.EndMarginStrut(); |
526 margin_strut.Append(curr_child_margins_.block_end); | 596 margin_strut.Append(child_data.margins.block_end); |
527 | 597 |
528 curr_bfc_offset_ += | 598 NGLogicalOffset bfc_offset = { |
529 {border_and_padding_.inline_start + curr_child_margins_.inline_start, | 599 ConstraintSpace().BfcOffset().inline_offset + |
530 margin_strut.Sum()}; | 600 border_and_padding_.inline_start + child_data.margins.inline_start, |
531 AdjustToClearance(space.ClearanceOffset(), &curr_bfc_offset_); | 601 child_data.bfc_offset_estimate.block_offset + margin_strut.Sum()}; |
532 PositionPendingFloatsFromOffset( | 602 AdjustToClearance(space.ClearanceOffset(), &bfc_offset); |
533 curr_bfc_offset_.block_offset, curr_bfc_offset_.block_offset, | 603 PositionPendingFloatsFromOffset(bfc_offset.block_offset, |
534 &container_builder_, MutableConstraintSpace()); | 604 bfc_offset.block_offset, &container_builder_, |
535 return curr_bfc_offset_; | 605 MutableConstraintSpace()); |
606 return bfc_offset; | |
536 } | 607 } |
537 | 608 |
538 NGLogicalOffset NGBlockLayoutAlgorithm::PositionLegacy( | 609 NGLogicalOffset NGBlockLayoutAlgorithm::PositionLegacy( |
539 const NGConstraintSpace& child_space) { | 610 const NGConstraintSpace& child_space, |
540 AdjustToClearance(child_space.ClearanceOffset(), &curr_bfc_offset_); | 611 const NGInflowChildData& child_data) { |
541 return curr_bfc_offset_; | 612 NGLogicalOffset bfc_offset = {ConstraintSpace().BfcOffset().inline_offset + |
613 border_and_padding_.inline_start + | |
614 child_data.margins.inline_start, | |
615 child_data.bfc_offset_estimate.block_offset}; | |
616 AdjustToClearance(child_space.ClearanceOffset(), &bfc_offset); | |
617 return bfc_offset; | |
542 } | 618 } |
543 | 619 |
544 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { | 620 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { |
545 LayoutUnit used_block_size = | 621 LayoutUnit used_block_size = |
546 BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit(); | 622 BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit(); |
547 LayoutUnit block_size = ComputeBlockSizeForFragment( | 623 LayoutUnit block_size = ComputeBlockSizeForFragment( |
548 ConstraintSpace(), Style(), used_block_size + content_size_); | 624 ConstraintSpace(), Style(), used_block_size + content_size_); |
549 | 625 |
550 block_size -= used_block_size; | 626 block_size -= used_block_size; |
551 DCHECK_GE(block_size, LayoutUnit()) | 627 DCHECK_GE(block_size, LayoutUnit()) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
602 sizes = child->ComputeMinMaxContentSize(); | 678 sizes = child->ComputeMinMaxContentSize(); |
603 | 679 |
604 LayoutUnit child_inline_size = | 680 LayoutUnit child_inline_size = |
605 ComputeInlineSizeForFragment(*space, child_style, sizes); | 681 ComputeInlineSizeForFragment(*space, child_style, sizes); |
606 ApplyAutoMargins(*space, child_style, child_inline_size, &margins); | 682 ApplyAutoMargins(*space, child_style, child_inline_size, &margins); |
607 } | 683 } |
608 return margins; | 684 return margins; |
609 } | 685 } |
610 | 686 |
611 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( | 687 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( |
612 const NGLogicalOffset& child_bfc_offset, | 688 const NGLayoutInputNode& child, |
613 const NGLayoutInputNode& child) { | 689 const NGInflowChildData& child_data) { |
614 NGConstraintSpaceBuilder space_builder(MutableConstraintSpace()); | 690 NGConstraintSpaceBuilder space_builder(MutableConstraintSpace()); |
615 space_builder.SetAvailableSize(child_available_size_) | 691 space_builder.SetAvailableSize(child_available_size_) |
616 .SetPercentageResolutionSize(child_percentage_size_); | 692 .SetPercentageResolutionSize(child_percentage_size_); |
617 | 693 |
618 const ComputedStyle& child_style = child.Style(); | 694 const ComputedStyle& child_style = child.Style(); |
619 bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child); | 695 bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child); |
620 space_builder.SetIsNewFormattingContext(is_new_bfc) | 696 space_builder.SetIsNewFormattingContext(is_new_bfc) |
621 .SetBfcOffset(child_bfc_offset) | 697 .SetBfcOffset(child_data.bfc_offset_estimate) |
622 .SetMarginStrut(curr_margin_strut_); | 698 .SetMarginStrut(child_data.margin_strut); |
623 | 699 |
624 if (!is_new_bfc) { | 700 if (!is_new_bfc) { |
625 space_builder.SetUnpositionedFloats( | 701 space_builder.SetUnpositionedFloats( |
626 container_builder_.MutableUnpositionedFloats()); | 702 container_builder_.MutableUnpositionedFloats()); |
627 } | 703 } |
628 | 704 |
629 if (child.IsInline()) { | 705 if (child.IsInline()) { |
630 // TODO(kojii): Setup space_builder appropriately for inline child. | 706 // TODO(kojii): Setup space_builder appropriately for inline child. |
631 space_builder.SetClearanceOffset(ConstraintSpace().ClearanceOffset()); | 707 space_builder.SetClearanceOffset(ConstraintSpace().ClearanceOffset()); |
632 return space_builder.ToConstraintSpace( | 708 return space_builder.ToConstraintSpace( |
633 FromPlatformWritingMode(Style().GetWritingMode())); | 709 FromPlatformWritingMode(Style().GetWritingMode())); |
634 } | 710 } |
635 | 711 |
636 space_builder | 712 space_builder |
637 .SetClearanceOffset(GetClearanceOffset(constraint_space_->Exclusions(), | 713 .SetClearanceOffset(GetClearanceOffset(constraint_space_->Exclusions(), |
638 child_style.Clear())) | 714 child_style.Clear())) |
639 .SetIsShrinkToFit(ShouldShrinkToFit(Style(), child_style)) | 715 .SetIsShrinkToFit(ShouldShrinkToFit(Style(), child_style)) |
640 .SetTextDirection(child_style.Direction()); | 716 .SetTextDirection(child_style.Direction()); |
641 | 717 |
642 LayoutUnit space_available; | 718 LayoutUnit space_available; |
643 if (constraint_space_->HasBlockFragmentation()) { | 719 if (constraint_space_->HasBlockFragmentation()) { |
644 space_available = ConstraintSpace().FragmentainerSpaceAvailable(); | 720 space_available = ConstraintSpace().FragmentainerSpaceAvailable(); |
645 // If a block establishes a new formatting context we must know our | 721 // If a block establishes a new formatting context we must know our |
646 // position in the formatting context, and are able to adjust the | 722 // position in the formatting context, and are able to adjust the |
647 // fragmentation line. | 723 // fragmentation line. |
648 if (is_new_bfc) { | 724 if (is_new_bfc) { |
649 space_available -= child_bfc_offset.block_offset; | 725 space_available -= child_data.bfc_offset_estimate.block_offset; |
650 } | 726 } |
651 } | 727 } |
652 space_builder.SetFragmentainerSpaceAvailable(space_available); | 728 space_builder.SetFragmentainerSpaceAvailable(space_available); |
653 | 729 |
654 return space_builder.ToConstraintSpace( | 730 return space_builder.ToConstraintSpace( |
655 FromPlatformWritingMode(child_style.GetWritingMode())); | 731 FromPlatformWritingMode(child_style.GetWritingMode())); |
656 } | 732 } |
657 } // namespace blink | 733 } // namespace blink |
OLD | NEW |