| 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_break_token.h" | 7 #include "core/layout/ng/ng_break_token.h" |
| 8 #include "core/layout/ng/ng_constraint_space.h" | 8 #include "core/layout/ng/ng_constraint_space.h" |
| 9 #include "core/layout/ng/ng_constraint_space_builder.h" | 9 #include "core/layout/ng/ng_constraint_space_builder.h" |
| 10 #include "core/layout/ng/ng_fragment_base.h" | 10 #include "core/layout/ng/ng_fragment_base.h" |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 } | 174 } |
| 175 | 175 |
| 176 } // namespace | 176 } // namespace |
| 177 | 177 |
| 178 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( | 178 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( |
| 179 PassRefPtr<const ComputedStyle> style, | 179 PassRefPtr<const ComputedStyle> style, |
| 180 NGBlockNode* first_child, | 180 NGBlockNode* first_child, |
| 181 NGConstraintSpace* constraint_space, | 181 NGConstraintSpace* constraint_space, |
| 182 NGBreakToken* break_token) | 182 NGBreakToken* break_token) |
| 183 : NGLayoutAlgorithm(kBlockLayoutAlgorithm), | 183 : NGLayoutAlgorithm(kBlockLayoutAlgorithm), |
| 184 state_(kStateInit), | 184 layout_state_(kStateInit), |
| 185 compute_minmax_state_(kStateInit), |
| 185 style_(style), | 186 style_(style), |
| 186 first_child_(first_child), | 187 first_child_(first_child), |
| 187 constraint_space_(constraint_space), | 188 constraint_space_(constraint_space), |
| 188 break_token_(break_token), | 189 break_token_(break_token), |
| 189 is_fragment_margin_strut_block_start_updated_(false) { | 190 is_fragment_margin_strut_block_start_updated_(false) { |
| 190 DCHECK(style_); | 191 DCHECK(style_); |
| 191 } | 192 } |
| 192 | 193 |
| 194 NGLayoutAlgorithm::MinAndMaxState |
| 195 NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes( |
| 196 MinAndMaxContentSizes* sizes) { |
| 197 switch (compute_minmax_state_) { |
| 198 case kStateInit: |
| 199 pending_minmax_sizes_.min_content = pending_minmax_sizes_.max_content = |
| 200 LayoutUnit(); |
| 201 // Size-contained elements don't consider their contents for intrinsic |
| 202 // sizing. |
| 203 if (style_->containsSize()) |
| 204 return kSuccess; |
| 205 current_minmax_child_ = first_child_; |
| 206 compute_minmax_state_ = kStateChildLayout; |
| 207 case kStateChildLayout: |
| 208 // TODO: handle floats & orthogonal children |
| 209 if (current_minmax_child_) { |
| 210 Optional<MinAndMaxContentSizes> child_minmax; |
| 211 if (NeedMinAndMaxContentSizesForContentContribution( |
| 212 *current_minmax_child_->Style())) { |
| 213 child_minmax = MinAndMaxContentSizes(); |
| 214 if (!current_minmax_child_->ComputeMinAndMaxContentSizes( |
| 215 &*child_minmax)) |
| 216 return kPending; |
| 217 } |
| 218 MinAndMaxContentSizes child_sizes = ComputeMinAndMaxContentContribution( |
| 219 *current_minmax_child_->Style(), child_minmax); |
| 220 pending_minmax_sizes_.min_content = std::max( |
| 221 pending_minmax_sizes_.min_content, child_sizes.min_content); |
| 222 pending_minmax_sizes_.max_content = std::max( |
| 223 pending_minmax_sizes_.max_content, child_sizes.max_content); |
| 224 |
| 225 current_minmax_child_ = current_minmax_child_->NextSibling(); |
| 226 if (current_minmax_child_) |
| 227 return kPending; |
| 228 } |
| 229 |
| 230 *sizes = pending_minmax_sizes_; |
| 231 sizes->max_content = std::max(sizes->min_content, sizes->max_content); |
| 232 compute_minmax_state_ = kStateInit; |
| 233 return kSuccess; |
| 234 default: |
| 235 NOTREACHED(); |
| 236 return kSuccess; |
| 237 }; |
| 238 } |
| 239 |
| 193 NGLayoutStatus NGBlockLayoutAlgorithm::Layout( | 240 NGLayoutStatus NGBlockLayoutAlgorithm::Layout( |
| 194 NGPhysicalFragmentBase* child_fragment, | 241 NGPhysicalFragmentBase* child_fragment, |
| 195 NGPhysicalFragmentBase** fragment_out, | 242 NGPhysicalFragmentBase** fragment_out, |
| 196 NGLayoutAlgorithm** algorithm_out) { | 243 NGLayoutAlgorithm** algorithm_out) { |
| 197 switch (state_) { | 244 switch (layout_state_) { |
| 198 case kStateInit: { | 245 case kStateInit: { |
| 246 WTF::Optional<MinAndMaxContentSizes> sizes; |
| 247 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) { |
| 248 sizes = MinAndMaxContentSizes(); |
| 249 if (ComputeMinAndMaxContentSizes(&*sizes) == kPending) |
| 250 return kNotFinished; |
| 251 } |
| 252 |
| 199 border_and_padding_ = | 253 border_and_padding_ = |
| 200 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); | 254 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); |
| 201 | 255 |
| 202 WTF::Optional<MinAndMaxContentSizes> sizes; | |
| 203 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) { | |
| 204 // TODOO(layout-ng): Implement | |
| 205 sizes = MinAndMaxContentSizes(); | |
| 206 } | |
| 207 LayoutUnit inline_size = | 256 LayoutUnit inline_size = |
| 208 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); | 257 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); |
| 209 LayoutUnit adjusted_inline_size = | 258 LayoutUnit adjusted_inline_size = |
| 210 inline_size - border_and_padding_.InlineSum(); | 259 inline_size - border_and_padding_.InlineSum(); |
| 211 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of | 260 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of |
| 212 // -1? | 261 // -1? |
| 213 LayoutUnit block_size = ComputeBlockSizeForFragment( | 262 LayoutUnit block_size = ComputeBlockSizeForFragment( |
| 214 ConstraintSpace(), Style(), NGSizeIndefinite); | 263 ConstraintSpace(), Style(), NGSizeIndefinite); |
| 215 LayoutUnit adjusted_block_size(block_size); | 264 LayoutUnit adjusted_block_size(block_size); |
| 216 // Our calculated block-axis size may be indefinite at this point. | 265 // Our calculated block-axis size may be indefinite at this point. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 231 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); | 280 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); |
| 232 | 281 |
| 233 content_size_ = border_and_padding_.block_start; | 282 content_size_ = border_and_padding_.block_start; |
| 234 | 283 |
| 235 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::kFragmentBox); | 284 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::kFragmentBox); |
| 236 builder_->SetDirection(constraint_space_->Direction()); | 285 builder_->SetDirection(constraint_space_->Direction()); |
| 237 builder_->SetWritingMode(constraint_space_->WritingMode()); | 286 builder_->SetWritingMode(constraint_space_->WritingMode()); |
| 238 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); | 287 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); |
| 239 | 288 |
| 240 current_child_ = first_child_; | 289 current_child_ = first_child_; |
| 241 state_ = kStatePrepareForChildLayout; | 290 layout_state_ = kStatePrepareForChildLayout; |
| 242 return kNotFinished; | 291 return kNotFinished; |
| 243 } | 292 } |
| 244 case kStatePrepareForChildLayout: { | 293 case kStatePrepareForChildLayout: { |
| 245 if (current_child_) { | 294 if (current_child_) { |
| 246 // TODO(atotic): uncomment this code when implementing oof layout. | 295 // TODO(atotic): uncomment this code when implementing oof layout. |
| 247 // This code cannot be turned on because it prevents layout of | 296 // This code cannot be turned on because it prevents layout of |
| 248 // oof children, and non-layedout objects trigger a DCHECK. | 297 // oof children, and non-layedout objects trigger a DCHECK. |
| 249 // EPosition position = current_child_->Style()->position(); | 298 // EPosition position = current_child_->Style()->position(); |
| 250 // if ((position == AbsolutePosition || position == FixedPosition)) { | 299 // if ((position == AbsolutePosition || position == FixedPosition)) { |
| 251 // builder_->AddOutOfFlowCandidateChild(current_child_, | 300 // builder_->AddOutOfFlowCandidateChild(current_child_, |
| 252 // GetChildSpaceOffset()); | 301 // GetChildSpaceOffset()); |
| 253 // } | 302 // } |
| 254 // else | 303 // else |
| 255 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); | 304 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); |
| 256 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( | 305 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( |
| 257 current_child_, space_for_current_child_); | 306 current_child_, space_for_current_child_); |
| 258 state_ = kStateChildLayout; | 307 layout_state_ = kStateChildLayout; |
| 259 return kChildAlgorithmRequired; | 308 return kChildAlgorithmRequired; |
| 260 } | 309 } |
| 261 | 310 |
| 262 state_ = kStateFinalize; | 311 layout_state_ = kStateFinalize; |
| 263 return kNotFinished; | 312 return kNotFinished; |
| 264 } | 313 } |
| 265 case kStateChildLayout: { | 314 case kStateChildLayout: { |
| 266 DCHECK(current_child_); | 315 DCHECK(current_child_); |
| 267 DCHECK(child_fragment); | 316 DCHECK(child_fragment); |
| 268 | 317 |
| 269 // TODO(layout_ng): Seems like a giant hack to call this here. | 318 // TODO(layout_ng): Seems like a giant hack to call this here. |
| 270 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), | 319 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), |
| 271 space_for_current_child_); | 320 space_for_current_child_); |
| 272 | 321 |
| 273 FinishCurrentChildLayout(new NGFragment( | 322 FinishCurrentChildLayout(new NGFragment( |
| 274 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), | 323 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), |
| 275 toNGPhysicalFragment(child_fragment))); | 324 toNGPhysicalFragment(child_fragment))); |
| 276 current_child_ = current_child_->NextSibling(); | 325 current_child_ = current_child_->NextSibling(); |
| 277 state_ = kStatePrepareForChildLayout; | 326 layout_state_ = kStatePrepareForChildLayout; |
| 278 return kNotFinished; | 327 return kNotFinished; |
| 279 } | 328 } |
| 280 case kStateFinalize: { | 329 case kStateFinalize: { |
| 281 content_size_ += border_and_padding_.block_end; | 330 content_size_ += border_and_padding_.block_end; |
| 282 | 331 |
| 283 // Recompute the block-axis size now that we know our content size. | 332 // Recompute the block-axis size now that we know our content size. |
| 284 LayoutUnit block_size = ComputeBlockSizeForFragment( | 333 LayoutUnit block_size = ComputeBlockSizeForFragment( |
| 285 ConstraintSpace(), Style(), content_size_); | 334 ConstraintSpace(), Style(), content_size_); |
| 286 | 335 |
| 287 builder_->SetBlockSize(block_size) | 336 builder_->SetBlockSize(block_size) |
| 288 .SetInlineOverflow(max_inline_size_) | 337 .SetInlineOverflow(max_inline_size_) |
| 289 .SetBlockOverflow(content_size_); | 338 .SetBlockOverflow(content_size_); |
| 290 *fragment_out = builder_->ToFragment(); | 339 *fragment_out = builder_->ToFragment(); |
| 291 state_ = kStateInit; | 340 layout_state_ = kStateInit; |
| 292 return kNewFragment; | 341 return kNewFragment; |
| 293 } | 342 } |
| 294 }; | 343 }; |
| 295 NOTREACHED(); | 344 NOTREACHED(); |
| 296 *fragment_out = nullptr; | 345 *fragment_out = nullptr; |
| 297 return kNewFragment; | 346 return kNewFragment; |
| 298 } | 347 } |
| 299 | 348 |
| 300 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( | 349 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( |
| 301 NGFragmentBase* fragment) { | 350 NGFragmentBase* fragment) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 } | 488 } |
| 440 builder_->SetMarginStrutBlockEnd(from); | 489 builder_->SetMarginStrutBlockEnd(from); |
| 441 } | 490 } |
| 442 | 491 |
| 443 NGConstraintSpace* | 492 NGConstraintSpace* |
| 444 NGBlockLayoutAlgorithm::CreateConstraintSpaceForCurrentChild() const { | 493 NGBlockLayoutAlgorithm::CreateConstraintSpaceForCurrentChild() const { |
| 445 // TODO(layout-ng): Orthogonal children should also shrink to fit (in *their* | 494 // TODO(layout-ng): Orthogonal children should also shrink to fit (in *their* |
| 446 // inline axis) | 495 // inline axis) |
| 447 // We have to keep this commented out for now until we correctly compute | 496 // We have to keep this commented out for now until we correctly compute |
| 448 // min/max content sizes in Layout(). | 497 // min/max content sizes in Layout(). |
| 449 // bool shrink_to_fit = CurrentChildStyle().display() == EDisplay::InlineBlock | 498 bool shrink_to_fit = CurrentChildStyle().display() == EDisplay::InlineBlock || |
| 450 // || CurrentChildStyle().isFloating(); | 499 CurrentChildStyle().isFloating(); |
| 451 bool shrink_to_fit = false; | |
| 452 DCHECK(current_child_); | 500 DCHECK(current_child_); |
| 453 space_builder_ | 501 space_builder_ |
| 454 ->SetIsNewFormattingContext( | 502 ->SetIsNewFormattingContext( |
| 455 IsNewFormattingContextForInFlowBlockLevelChild(ConstraintSpace(), | 503 IsNewFormattingContextForInFlowBlockLevelChild(ConstraintSpace(), |
| 456 CurrentChildStyle())) | 504 CurrentChildStyle())) |
| 457 .SetIsShrinkToFit(shrink_to_fit) | 505 .SetIsShrinkToFit(shrink_to_fit) |
| 458 .SetWritingMode( | 506 .SetWritingMode( |
| 459 FromPlatformWritingMode(CurrentChildStyle().getWritingMode())) | 507 FromPlatformWritingMode(CurrentChildStyle().getWritingMode())) |
| 460 .SetTextDirection(CurrentChildStyle().direction()); | 508 .SetTextDirection(CurrentChildStyle().direction()); |
| 461 NGConstraintSpace* child_space = space_builder_->ToConstraintSpace(); | 509 NGConstraintSpace* child_space = space_builder_->ToConstraintSpace(); |
| 462 | 510 |
| 463 // TODO(layout-ng): Set offset through the space builder. | 511 // TODO(layout-ng): Set offset through the space builder. |
| 464 child_space->SetOffset(GetChildSpaceOffset()); | 512 child_space->SetOffset(GetChildSpaceOffset()); |
| 465 return child_space; | 513 return child_space; |
| 466 } | 514 } |
| 467 | 515 |
| 468 DEFINE_TRACE(NGBlockLayoutAlgorithm) { | 516 DEFINE_TRACE(NGBlockLayoutAlgorithm) { |
| 469 NGLayoutAlgorithm::trace(visitor); | 517 NGLayoutAlgorithm::trace(visitor); |
| 470 visitor->trace(first_child_); | 518 visitor->trace(first_child_); |
| 471 visitor->trace(constraint_space_); | 519 visitor->trace(constraint_space_); |
| 472 visitor->trace(break_token_); | 520 visitor->trace(break_token_); |
| 473 visitor->trace(builder_); | 521 visitor->trace(builder_); |
| 474 visitor->trace(space_builder_); | 522 visitor->trace(space_builder_); |
| 475 visitor->trace(space_for_current_child_); | 523 visitor->trace(space_for_current_child_); |
| 476 visitor->trace(current_child_); | 524 visitor->trace(current_child_); |
| 525 visitor->trace(current_minmax_child_); |
| 477 } | 526 } |
| 478 | 527 |
| 479 } // namespace blink | 528 } // namespace blink |
| OLD | NEW |