Chromium Code Reviews| 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 |