| Index: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| index 56607765eb2d5714f8ea19d16672713626840656..6552cb503e67df931c874ecd860a54444340b3fe 100644
|
| --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
|
| @@ -5,6 +5,7 @@
|
| #include "core/layout/ng/ng_block_layout_algorithm.h"
|
|
|
| #include "core/layout/ng/ng_constraint_space.h"
|
| +#include "core/layout/ng/ng_constraint_space_builder.h"
|
| #include "core/layout/ng/ng_fragment_builder.h"
|
| #include "core/layout/ng/ng_fragment.h"
|
| #include "core/layout/ng/ng_layout_opportunity_iterator.h"
|
| @@ -58,7 +59,7 @@ NGExclusion* CreateExclusion(const NGFragment& fragment,
|
| // @param margins Margins of the fragment.
|
| // @return Layout opportunity for the fragment.
|
| const NGLayoutOpportunity FindLayoutOpportunityForFragment(
|
| - const Member<NGConstraintSpace>& space,
|
| + NGConstraintSpace* space,
|
| const NGFragment& fragment,
|
| const NGBoxStrut& margins) {
|
| NGLayoutOpportunityIterator* opportunity_iter = space->LayoutOpportunities();
|
| @@ -139,60 +140,84 @@ bool IsNewFormattingContextForInFlowBlockLevelChild(
|
| return false;
|
| }
|
|
|
| +// Creates a new constraint space for a child.
|
| +NGConstraintSpace* CreateConstraintSpaceForChild(
|
| + const NGConstraintSpace& space,
|
| + const NGBox& child,
|
| + NGConstraintSpaceBuilder* builder) {
|
| + builder->SetIsNewFormattingContext(
|
| + IsNewFormattingContextForInFlowBlockLevelChild(space, *child.Style()));
|
| + return new NGConstraintSpace(space.WritingMode(), space.Direction(),
|
| + builder->ToConstraintSpace());
|
| +}
|
| +
|
| } // namespace
|
|
|
| NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
|
| PassRefPtr<const ComputedStyle> style,
|
| - NGBox* first_child)
|
| - : style_(style),
|
| + NGBox* first_child,
|
| + NGConstraintSpace* constraint_space)
|
| + : state_(kStateInit),
|
| + style_(style),
|
| first_child_(first_child),
|
| - state_(kStateInit),
|
| + constraint_space_(constraint_space),
|
| is_fragment_margin_strut_block_start_updated_(false) {
|
| DCHECK(style_);
|
| }
|
|
|
| -bool NGBlockLayoutAlgorithm::Layout(const NGConstraintSpace* constraint_space,
|
| - NGPhysicalFragment** out) {
|
| +bool NGBlockLayoutAlgorithm::Layout(NGPhysicalFragment** out) {
|
| switch (state_) {
|
| case kStateInit: {
|
| border_and_padding_ =
|
| - ComputeBorders(Style()) + ComputePadding(*constraint_space, Style());
|
| + ComputeBorders(Style()) + ComputePadding(*constraint_space_, Style());
|
|
|
| LayoutUnit inline_size =
|
| - ComputeInlineSizeForFragment(*constraint_space, Style());
|
| + ComputeInlineSizeForFragment(*constraint_space_, Style());
|
| LayoutUnit adjusted_inline_size =
|
| inline_size - border_and_padding_.InlineSum();
|
| // TODO(layout-ng): For quirks mode, should we pass blockSize instead of
|
| // -1?
|
| LayoutUnit block_size = ComputeBlockSizeForFragment(
|
| - *constraint_space, Style(), NGSizeIndefinite);
|
| + *constraint_space_, Style(), NGSizeIndefinite);
|
| LayoutUnit adjusted_block_size(block_size);
|
| // Our calculated block-axis size may be indefinite at this point.
|
| // If so, just leave the size as NGSizeIndefinite instead of subtracting
|
| // borders and padding.
|
| if (adjusted_block_size != NGSizeIndefinite)
|
| adjusted_block_size -= border_and_padding_.BlockSum();
|
| - constraint_space_for_children_ = new NGConstraintSpace(
|
| - FromPlatformWritingMode(Style().getWritingMode()),
|
| - FromPlatformDirection(Style().direction()), *constraint_space,
|
| +
|
| + space_builder_ =
|
| + new NGConstraintSpaceBuilder(constraint_space_->WritingMode());
|
| + space_builder_->SetContainerSize(
|
| + NGLogicalSize(adjusted_inline_size, adjusted_block_size));
|
| +
|
| + constraint_space_->SetSize(
|
| NGLogicalSize(adjusted_inline_size, adjusted_block_size));
|
| +
|
| content_size_ = border_and_padding_.block_start;
|
|
|
| builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::FragmentBox);
|
| - builder_->SetDirection(constraint_space->Direction());
|
| - builder_->SetWritingMode(constraint_space->WritingMode());
|
| + builder_->SetDirection(constraint_space_->Direction());
|
| + builder_->SetWritingMode(constraint_space_->WritingMode());
|
| builder_->SetInlineSize(inline_size).SetBlockSize(block_size);
|
| current_child_ = first_child_;
|
| + if (current_child_)
|
| + space_for_current_child_ = CreateConstraintSpaceForChild(
|
| + *constraint_space_, *current_child_, space_builder_);
|
| +
|
| state_ = kStateChildLayout;
|
| return false;
|
| }
|
| case kStateChildLayout: {
|
| if (current_child_) {
|
| - if (!LayoutCurrentChild(constraint_space))
|
| + if (!LayoutCurrentChild())
|
| return false;
|
| current_child_ = current_child_->NextSibling();
|
| - if (current_child_)
|
| + if (current_child_) {
|
| + space_for_current_child_ = CreateConstraintSpaceForChild(
|
| + *constraint_space_, *current_child_, space_builder_);
|
| return false;
|
| + }
|
| }
|
| state_ = kStateFinalize;
|
| return false;
|
| @@ -202,7 +227,7 @@ bool NGBlockLayoutAlgorithm::Layout(const NGConstraintSpace* constraint_space,
|
|
|
| // Recompute the block-axis size now that we know our content size.
|
| LayoutUnit block_size = ComputeBlockSizeForFragment(
|
| - *constraint_space, Style(), content_size_);
|
| + *constraint_space_, Style(), content_size_);
|
|
|
| builder_->SetBlockSize(block_size)
|
| .SetInlineOverflow(max_inline_size_)
|
| @@ -217,37 +242,28 @@ bool NGBlockLayoutAlgorithm::Layout(const NGConstraintSpace* constraint_space,
|
| return true;
|
| }
|
|
|
| -bool NGBlockLayoutAlgorithm::LayoutCurrentChild(
|
| - const NGConstraintSpace* constraint_space) {
|
| - constraint_space_for_children_->SetIsNewFormattingContext(
|
| - IsNewFormattingContextForInFlowBlockLevelChild(*constraint_space,
|
| - *current_child_->Style()));
|
| -
|
| +bool NGBlockLayoutAlgorithm::LayoutCurrentChild() {
|
| NGFragment* fragment;
|
| - if (!current_child_->Layout(constraint_space_for_children_, &fragment))
|
| + if (!current_child_->Layout(space_for_current_child_, &fragment))
|
| return false;
|
|
|
| - NGBoxStrut child_margins =
|
| - ComputeMargins(*constraint_space_for_children_, *current_child_->Style(),
|
| - constraint_space_for_children_->WritingMode(),
|
| - constraint_space_for_children_->Direction());
|
| + NGBoxStrut child_margins = ComputeMargins(
|
| + *space_for_current_child_, *current_child_->Style(),
|
| + constraint_space_->WritingMode(), constraint_space_->Direction());
|
|
|
| NGLogicalOffset fragment_offset;
|
| if (current_child_->Style()->isFloating()) {
|
| fragment_offset = PositionFloatFragment(*fragment, child_margins);
|
| } else {
|
| - // TODO(layout-ng): move ApplyAutoMargins to PositionFragment
|
| - ApplyAutoMargins(*constraint_space_for_children_, *current_child_->Style(),
|
| + ApplyAutoMargins(*space_for_current_child_, *current_child_->Style(),
|
| *fragment, &child_margins);
|
| - fragment_offset =
|
| - PositionFragment(*fragment, child_margins, *constraint_space);
|
| + fragment_offset = PositionFragment(*fragment, child_margins);
|
| }
|
| builder_->AddChild(fragment, fragment_offset);
|
| return true;
|
| }
|
|
|
| NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
|
| - const NGConstraintSpace& space,
|
| const NGBoxStrut& margins,
|
| const NGFragment& fragment) {
|
| bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() &&
|
| @@ -260,7 +276,7 @@ NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
|
| // Calculate borders and padding for the current child.
|
| NGBoxStrut border_and_padding =
|
| ComputeBorders(*current_child_->Style()) +
|
| - ComputePadding(space, *current_child_->Style());
|
| + ComputePadding(*constraint_space_, *current_child_->Style());
|
|
|
| // Collapse BLOCK-START margins if there is no padding or border between
|
| // parent (current child) and its first in-flow child.
|
| @@ -287,7 +303,7 @@ NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
|
| // - Compute margins block start for adjoining blocks *including* 1st block.
|
| // - Compute margins block end for the last block.
|
| // - Do not set the computed margins to the parent fragment.
|
| - if (space.IsNewFormattingContext()) {
|
| + if (constraint_space_->IsNewFormattingContext()) {
|
| result_margins.block_start = ComputeCollapsedMarginBlockStart(
|
| prev_child_margin_strut_, curr_margin_strut);
|
| bool is_last_child = !current_child_->NextSibling();
|
| @@ -315,10 +331,8 @@ NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
|
|
|
| NGLogicalOffset NGBlockLayoutAlgorithm::PositionFragment(
|
| const NGFragment& fragment,
|
| - const NGBoxStrut& child_margins,
|
| - const NGConstraintSpace& space) {
|
| - const NGBoxStrut collapsed_margins =
|
| - CollapseMargins(space, child_margins, fragment);
|
| + const NGBoxStrut& child_margins) {
|
| + const NGBoxStrut collapsed_margins = CollapseMargins(child_margins, fragment);
|
|
|
| LayoutUnit inline_offset =
|
| border_and_padding_.inline_start + child_margins.inline_start;
|
| @@ -336,8 +350,8 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PositionFloatFragment(
|
| const NGBoxStrut& margins) {
|
| // TODO(glebl@chromium.org): Support the top edge alignment rule.
|
| // Find a layout opportunity that will fit our float.
|
| - const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
|
| - constraint_space_for_children_, fragment, margins);
|
| + const NGLayoutOpportunity opportunity =
|
| + FindLayoutOpportunityForFragment(constraint_space_, fragment, margins);
|
| DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be";
|
|
|
| // Calculate the float offset if needed.
|
| @@ -349,7 +363,7 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PositionFloatFragment(
|
| // Add the float as an exclusion.
|
| const NGExclusion* exclusion =
|
| CreateExclusion(fragment, opportunity, float_offset, margins);
|
| - constraint_space_for_children_->AddExclusion(exclusion);
|
| + constraint_space_->AddExclusion(exclusion);
|
|
|
| return CalculateLogicalOffsetForOpportunity(opportunity, border_and_padding_,
|
| float_offset, margins);
|
| @@ -366,8 +380,10 @@ void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) {
|
| DEFINE_TRACE(NGBlockLayoutAlgorithm) {
|
| NGLayoutAlgorithm::trace(visitor);
|
| visitor->trace(first_child_);
|
| + visitor->trace(constraint_space_);
|
| visitor->trace(builder_);
|
| - visitor->trace(constraint_space_for_children_);
|
| + visitor->trace(space_builder_);
|
| + visitor->trace(space_for_current_child_);
|
| visitor->trace(current_child_);
|
| }
|
|
|
|
|