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/ng_absolute_utils.h" | 7 #include "core/layout/ng/ng_absolute_utils.h" |
| 8 #include "core/layout/ng/ng_block_break_token.h" | 8 #include "core/layout/ng/ng_block_break_token.h" |
| 9 #include "core/layout/ng/ng_box_fragment.h" | 9 #include "core/layout/ng/ng_box_fragment.h" |
| 10 #include "core/layout/ng/ng_column_mapper.h" | 10 #include "core/layout/ng/ng_column_mapper.h" |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 } | 177 } |
| 178 | 178 |
| 179 } // namespace | 179 } // namespace |
| 180 | 180 |
| 181 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( | 181 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( |
| 182 PassRefPtr<const ComputedStyle> style, | 182 PassRefPtr<const ComputedStyle> style, |
| 183 NGBlockNode* first_child, | 183 NGBlockNode* first_child, |
| 184 NGConstraintSpace* constraint_space, | 184 NGConstraintSpace* constraint_space, |
| 185 NGBreakToken* break_token) | 185 NGBreakToken* break_token) |
| 186 : NGLayoutAlgorithm(kBlockLayoutAlgorithm), | 186 : NGLayoutAlgorithm(kBlockLayoutAlgorithm), |
| 187 layout_state_(kStateInit), | |
| 188 style_(style), | 187 style_(style), |
| 189 first_child_(first_child), | 188 first_child_(first_child), |
| 190 constraint_space_(constraint_space), | 189 constraint_space_(constraint_space), |
| 191 break_token_(break_token), | 190 break_token_(break_token), |
| 192 is_fragment_margin_strut_block_start_updated_(false) { | 191 is_fragment_margin_strut_block_start_updated_(false) { |
| 193 DCHECK(style_); | 192 DCHECK(style_); |
| 194 } | 193 } |
| 195 | 194 |
| 196 bool NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes( | 195 bool NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes( |
| 197 MinAndMaxContentSizes* sizes) { | 196 MinAndMaxContentSizes* sizes) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 217 } | 216 } |
| 218 | 217 |
| 219 sizes->max_content = std::max(sizes->min_content, sizes->max_content); | 218 sizes->max_content = std::max(sizes->min_content, sizes->max_content); |
| 220 return true; | 219 return true; |
| 221 } | 220 } |
| 222 | 221 |
| 223 NGLayoutStatus NGBlockLayoutAlgorithm::Layout( | 222 NGLayoutStatus NGBlockLayoutAlgorithm::Layout( |
| 224 NGPhysicalFragment* child_fragment, | 223 NGPhysicalFragment* child_fragment, |
| 225 NGPhysicalFragment** fragment_out, | 224 NGPhysicalFragment** fragment_out, |
| 226 NGLayoutAlgorithm** algorithm_out) { | 225 NGLayoutAlgorithm** algorithm_out) { |
| 227 switch (layout_state_) { | 226 WTF::Optional<MinAndMaxContentSizes> sizes; |
| 228 case kStateInit: { | 227 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) { |
| 229 WTF::Optional<MinAndMaxContentSizes> sizes; | 228 // TODO(ikilpatrick): Change ComputeMinAndMaxContentSizes to return |
| 230 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) { | 229 // MinAndMaxContentSizes. |
|
cbiesinger
2017/01/19 18:41:11
Tricky because how do you indicate that it isn't i
ikilpatrick
2017/01/19 18:54:15
I was thinking we could just have a bool NGLayoutA
cbiesinger
2017/01/19 19:06:30
True, that works. sounds good.
| |
| 231 sizes = MinAndMaxContentSizes(); | 230 sizes = MinAndMaxContentSizes(); |
| 232 ComputeMinAndMaxContentSizes(&*sizes); | 231 ComputeMinAndMaxContentSizes(&*sizes); |
| 233 } | 232 } |
| 234 | 233 |
| 235 border_and_padding_ = | 234 border_and_padding_ = |
| 236 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); | 235 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); |
| 237 | 236 |
| 238 LayoutUnit inline_size = | 237 LayoutUnit inline_size = |
| 239 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); | 238 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); |
| 240 LayoutUnit adjusted_inline_size = | 239 LayoutUnit adjusted_inline_size = |
| 241 inline_size - border_and_padding_.InlineSum(); | 240 inline_size - border_and_padding_.InlineSum(); |
| 242 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of | 241 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of |
| 243 // -1? | 242 // -1? |
| 244 LayoutUnit block_size = ComputeBlockSizeForFragment( | 243 LayoutUnit block_size = |
| 245 ConstraintSpace(), Style(), NGSizeIndefinite); | 244 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite); |
| 246 LayoutUnit adjusted_block_size(block_size); | 245 LayoutUnit adjusted_block_size(block_size); |
| 247 // Our calculated block-axis size may be indefinite at this point. | 246 // Our calculated block-axis size may be indefinite at this point. |
| 248 // If so, just leave the size as NGSizeIndefinite instead of subtracting | 247 // If so, just leave the size as NGSizeIndefinite instead of subtracting |
| 249 // borders and padding. | 248 // borders and padding. |
| 250 if (adjusted_block_size != NGSizeIndefinite) | 249 if (adjusted_block_size != NGSizeIndefinite) |
| 251 adjusted_block_size -= border_and_padding_.BlockSum(); | 250 adjusted_block_size -= border_and_padding_.BlockSum(); |
| 252 | 251 |
| 253 space_builder_ = new NGConstraintSpaceBuilder(constraint_space_); | 252 space_builder_ = new NGConstraintSpaceBuilder(constraint_space_); |
| 254 if (Style().specifiesColumns()) { | 253 if (Style().specifiesColumns()) { |
| 255 space_builder_->SetFragmentationType(kFragmentColumn); | 254 space_builder_->SetFragmentationType(kFragmentColumn); |
| 256 adjusted_inline_size = | 255 adjusted_inline_size = |
| 257 ResolveUsedColumnInlineSize(adjusted_inline_size, Style()); | 256 ResolveUsedColumnInlineSize(adjusted_inline_size, Style()); |
| 258 LayoutUnit inline_progression = | 257 LayoutUnit inline_progression = |
| 259 adjusted_inline_size + ResolveUsedColumnGap(Style()); | 258 adjusted_inline_size + ResolveUsedColumnGap(Style()); |
| 260 fragmentainer_mapper_ = | 259 fragmentainer_mapper_ = |
| 261 new NGColumnMapper(inline_progression, adjusted_block_size); | 260 new NGColumnMapper(inline_progression, adjusted_block_size); |
| 262 } | 261 } |
| 263 space_builder_->SetAvailableSize( | 262 space_builder_->SetAvailableSize( |
| 264 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); | 263 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); |
| 265 space_builder_->SetPercentageResolutionSize( | 264 space_builder_->SetPercentageResolutionSize( |
| 266 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); | 265 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); |
| 267 | 266 |
| 268 builder_ = new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox); | 267 builder_ = new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox); |
| 269 builder_->SetDirection(constraint_space_->Direction()); | 268 builder_->SetDirection(constraint_space_->Direction()); |
| 270 builder_->SetWritingMode(constraint_space_->WritingMode()); | 269 builder_->SetWritingMode(constraint_space_->WritingMode()); |
| 271 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); | 270 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); |
| 272 | 271 |
| 273 if (NGBlockBreakToken* token = CurrentBlockBreakToken()) { | 272 if (NGBlockBreakToken* token = CurrentBlockBreakToken()) { |
| 274 // Resume after a previous break. | 273 // Resume after a previous break. |
| 275 content_size_ = token->BreakOffset(); | 274 content_size_ = token->BreakOffset(); |
| 276 current_child_ = token->InputNode(); | 275 current_child_ = token->InputNode(); |
| 277 } else { | 276 } else { |
| 278 content_size_ = border_and_padding_.block_start; | 277 content_size_ = border_and_padding_.block_start; |
| 279 current_child_ = first_child_; | 278 current_child_ = first_child_; |
| 280 } | 279 } |
| 281 | 280 |
| 282 layout_state_ = kStatePrepareForChildLayout; | 281 while (current_child_) { |
| 283 return kNotFinished; | 282 EPosition position = current_child_->Style()->position(); |
| 283 if ((position == AbsolutePosition || position == FixedPosition)) { | |
|
cbiesinger
2017/01/19 18:41:11
I know you just moved this but maybe remove one se
ikilpatrick
2017/01/19 18:54:15
Done.
| |
| 284 builder_->AddOutOfFlowChildCandidate(current_child_, | |
| 285 GetChildSpaceOffset()); | |
| 286 current_child_ = current_child_->NextSibling(); | |
| 287 continue; | |
| 284 } | 288 } |
| 285 case kStatePrepareForChildLayout: { | |
| 286 if (current_child_) { | |
| 287 EPosition position = current_child_->Style()->position(); | |
| 288 if ((position == AbsolutePosition || position == FixedPosition)) { | |
| 289 builder_->AddOutOfFlowChildCandidate(current_child_, | |
| 290 GetChildSpaceOffset()); | |
| 291 current_child_ = current_child_->NextSibling(); | |
| 292 return kNotFinished; | |
| 293 } | |
| 294 DCHECK(!ConstraintSpace().HasBlockFragmentation() || | |
| 295 SpaceAvailableForCurrentChild() > LayoutUnit()); | |
| 296 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); | |
| 297 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( | |
| 298 current_child_, space_for_current_child_); | |
| 299 layout_state_ = kStateChildLayout; | |
| 300 return kChildAlgorithmRequired; | |
| 301 } | |
| 302 | 289 |
| 303 // Prepare for kStateOutOfFlowLayout | 290 DCHECK(!ConstraintSpace().HasBlockFragmentation() || |
| 304 content_size_ += border_and_padding_.block_end; | 291 SpaceAvailableForCurrentChild() > LayoutUnit()); |
| 292 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); | |
| 305 | 293 |
| 306 // Recompute the block-axis size now that we know our content size. | 294 NGFragment* fragment; |
| 307 LayoutUnit block_size = ComputeBlockSizeForFragment( | 295 current_child_->LayoutSync(space_for_current_child_, &fragment); |
| 308 ConstraintSpace(), Style(), content_size_); | 296 NGPhysicalFragment* child_fragment = fragment->PhysicalFragment(); |
| 309 builder_->SetBlockSize(block_size); | |
| 310 | 297 |
| 311 // Out of flow setup. | 298 // TODO(layout_ng): Seems like a giant hack to call this here. |
| 312 out_of_flow_layout_ = | 299 current_child_->UpdateLayoutBox(toNGPhysicalBoxFragment(child_fragment), |
| 313 new NGOutOfFlowLayoutPart(&Style(), builder_->Size()); | 300 space_for_current_child_); |
| 314 builder_->GetAndClearOutOfFlowDescendantCandidates( | |
| 315 &out_of_flow_candidates_, &out_of_flow_candidate_positions_); | |
| 316 out_of_flow_candidate_positions_index_ = 0; | |
| 317 current_child_ = nullptr; | |
| 318 layout_state_ = kStateOutOfFlowLayout; | |
| 319 return kNotFinished; | |
| 320 } | |
| 321 case kStateChildLayout: { | |
| 322 DCHECK(current_child_); | |
| 323 DCHECK(child_fragment); | |
| 324 | 301 |
| 325 // TODO(layout_ng): Seems like a giant hack to call this here. | 302 FinishCurrentChildLayout(new NGBoxFragment( |
| 326 current_child_->UpdateLayoutBox(toNGPhysicalBoxFragment(child_fragment), | 303 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), |
| 327 space_for_current_child_); | 304 toNGPhysicalBoxFragment(child_fragment))); |
| 328 | 305 |
| 329 FinishCurrentChildLayout(new NGBoxFragment( | 306 if (!ProceedToNextUnfinishedSibling(child_fragment)) |
| 330 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), | 307 break; |
| 331 toNGPhysicalBoxFragment(child_fragment))); | 308 } |
| 332 | 309 |
| 333 if (ProceedToNextUnfinishedSibling(child_fragment)) | 310 content_size_ += border_and_padding_.block_end; |
| 334 layout_state_ = kStatePrepareForChildLayout; | |
| 335 else | |
| 336 layout_state_ = kStateFinalize; | |
| 337 return kNotFinished; | |
| 338 } | |
| 339 case kStateOutOfFlowLayout: | |
| 340 if (LayoutOutOfFlowChild()) | |
| 341 layout_state_ = kStateFinalize; | |
| 342 return kNotFinished; | |
| 343 case kStateFinalize: { | |
| 344 builder_->SetInlineOverflow(max_inline_size_) | |
| 345 .SetBlockOverflow(content_size_); | |
| 346 | 311 |
| 347 if (ConstraintSpace().HasBlockFragmentation()) | 312 // Recompute the block-axis size now that we know our content size. |
| 348 FinalizeForFragmentation(); | 313 block_size = |
| 314 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); | |
| 315 builder_->SetBlockSize(block_size); | |
| 349 | 316 |
| 350 *fragment_out = builder_->ToBoxFragment(); | 317 // Out of flow setup. |
| 351 layout_state_ = kStateInit; | 318 out_of_flow_layout_ = new NGOutOfFlowLayoutPart(&Style(), builder_->Size()); |
| 352 return kNewFragment; | 319 builder_->GetAndClearOutOfFlowDescendantCandidates( |
| 353 } | 320 &out_of_flow_candidates_, &out_of_flow_candidate_positions_); |
| 354 }; | 321 out_of_flow_candidate_positions_index_ = 0; |
| 355 NOTREACHED(); | 322 current_child_ = nullptr; |
| 356 *fragment_out = nullptr; | 323 |
| 324 while (!LayoutOutOfFlowChild()) | |
| 325 continue; | |
| 326 | |
| 327 builder_->SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_); | |
| 328 | |
| 329 if (ConstraintSpace().HasBlockFragmentation()) | |
| 330 FinalizeForFragmentation(); | |
| 331 | |
| 332 *fragment_out = builder_->ToBoxFragment(); | |
| 357 return kNewFragment; | 333 return kNewFragment; |
| 358 } | 334 } |
| 359 | 335 |
| 360 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout(NGFragment* fragment) { | 336 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout(NGFragment* fragment) { |
| 361 NGBoxStrut child_margins = ComputeMargins( | 337 NGBoxStrut child_margins = ComputeMargins( |
| 362 *space_for_current_child_, CurrentChildStyle(), | 338 *space_for_current_child_, CurrentChildStyle(), |
| 363 constraint_space_->WritingMode(), constraint_space_->Direction()); | 339 constraint_space_->WritingMode(), constraint_space_->Direction()); |
| 364 | 340 |
| 365 NGLogicalOffset fragment_offset; | 341 NGLogicalOffset fragment_offset; |
| 366 if (CurrentChildStyle().isFloating()) { | 342 if (CurrentChildStyle().isFloating()) { |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 visitor->trace(builder_); | 678 visitor->trace(builder_); |
| 703 visitor->trace(space_builder_); | 679 visitor->trace(space_builder_); |
| 704 visitor->trace(space_for_current_child_); | 680 visitor->trace(space_for_current_child_); |
| 705 visitor->trace(current_child_); | 681 visitor->trace(current_child_); |
| 706 visitor->trace(out_of_flow_layout_); | 682 visitor->trace(out_of_flow_layout_); |
| 707 visitor->trace(out_of_flow_candidates_); | 683 visitor->trace(out_of_flow_candidates_); |
| 708 visitor->trace(fragmentainer_mapper_); | 684 visitor->trace(fragmentainer_mapper_); |
| 709 } | 685 } |
| 710 | 686 |
| 711 } // namespace blink | 687 } // namespace blink |
| OLD | NEW |