Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/ng/ng_multi_column_layout_algorithm.cc |
| diff --git a/third_party/WebKit/Source/core/layout/ng/ng_multi_column_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_multi_column_layout_algorithm.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..35187a8ffdcf482454865056113ff74719352591 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/core/layout/ng/ng_multi_column_layout_algorithm.cc |
| @@ -0,0 +1,125 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "core/layout/ng/ng_multi_column_layout_algorithm.h" |
| + |
| +#include "core/layout/ng/ng_absolute_utils.h" |
| +#include "core/layout/ng/ng_block_break_token.h" |
| +#include "core/layout/ng/ng_block_layout_algorithm.h" |
| +#include "core/layout/ng/ng_box_fragment.h" |
| +#include "core/layout/ng/ng_column_mapper.h" |
| +#include "core/layout/ng/ng_constraint_space.h" |
| +#include "core/layout/ng/ng_constraint_space_builder.h" |
| +#include "core/layout/ng/ng_fragment.h" |
| +#include "core/layout/ng/ng_fragment_builder.h" |
| +#include "core/layout/ng/ng_inline_node.h" |
| +#include "core/layout/ng/ng_layout_opportunity_iterator.h" |
| +#include "core/layout/ng/ng_length_utils.h" |
| +#include "core/layout/ng/ng_line_builder.h" |
| +#include "core/layout/ng/ng_out_of_flow_layout_part.h" |
| +#include "core/layout/ng/ng_units.h" |
| +#include "core/style/ComputedStyle.h" |
| +#include "platform/LengthFunctions.h" |
| +#include "wtf/Optional.h" |
| + |
| +namespace blink { |
| + |
| +NGMultiColumnLayoutAlgorithm::NGMultiColumnLayoutAlgorithm( |
| + NGBlockNode* node, |
| + NGConstraintSpace* constraint_space, |
| + NGBreakToken* break_token) |
| + : node_(node), |
| + constraint_space_(constraint_space), |
| + break_token_(break_token), |
| + builder_(WTF::wrapUnique( |
| + new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox, node))) {} |
| + |
| +Optional<MinAndMaxContentSizes> |
| +NGMultiColumnLayoutAlgorithm::ComputeMinAndMaxContentSizes() const { |
| + return NGBlockLayoutAlgorithm(node_, constraint_space_, |
| + toNGBlockBreakToken(break_token_)) |
| + .ComputeMinAndMaxContentSizes(); |
| +} |
| + |
| +RefPtr<NGPhysicalFragment> NGMultiColumnLayoutAlgorithm::Layout() { |
| + WTF::Optional<MinAndMaxContentSizes> sizes; |
| + if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) |
| + sizes = ComputeMinAndMaxContentSizes(); |
| + |
| + border_and_padding_ = |
| + ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); |
| + |
| + LayoutUnit inline_size = |
| + ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); |
| + |
| + DCHECK(Style().specifiesColumns()); |
| + LayoutUnit adjusted_inline_size = ResolveUsedColumnInlineSize( |
| + inline_size - border_and_padding_.InlineSum(), Style()); |
| + |
| + /*LayoutUnit inline_progression = |
| + adjusted_inline_size + ResolveUsedColumnGap(Style());*/ |
|
mstensho (USE GERRIT)
2017/02/15 21:12:23
So this is currently missing, right? We need to be
|
| + |
| + LayoutUnit block_size = |
| + ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite); |
| + |
| + // 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. |
| + LayoutUnit adjusted_block_size(block_size); |
| + if (adjusted_block_size != NGSizeIndefinite) |
| + adjusted_block_size -= border_and_padding_.BlockSum(); |
| + |
| + space_builder_ = new NGConstraintSpaceBuilder(constraint_space_); |
| + space_builder_->SetFragmentationType(kFragmentColumn) |
| + .SetAvailableSize( |
|
mstensho (USE GERRIT)
2017/02/15 21:12:23
I've been meaning to ask this for some time:
What
ikilpatrick
2017/02/16 16:48:31
I think just that's what all the other builders lo
mstensho (USE GERRIT)
2017/02/16 21:14:47
Yes, this is a common pattern in this code. I'm ju
|
| + NGLogicalSize(adjusted_inline_size, adjusted_block_size)) |
| + .SetPercentageResolutionSize( |
| + NGLogicalSize(adjusted_inline_size, adjusted_block_size)); |
| + |
| + // TODO(ikilpatrick): if we don't have a fragmentation line we should peform a |
| + // full layout, determine the break opportunities, and then perform a relayout |
| + // into the individual columns. |
| + // If __our__ constraint space has a column fragmentation line, we trust that |
| + // a multi column algorithm above us has determined the correct layout |
| + // opportunites so we just layout with that fragmentation line. |
| + |
| + // TODO(ikilpatrick): We only support multicols with definite block sizes. |
| + DCHECK(adjusted_block_size != NGSizeIndefinite); |
| + space_builder_->SetFragmentainerSpaceAvailable( |
| + constraint_space_->HasBlockFragmentation() |
| + ? constraint_space_->FragmentainerSpaceAvailable() |
| + : // TODO need to account for borders and padding. |
| + adjusted_block_size); |
| + |
| + builder_->SetDirection(constraint_space_->Direction()); |
| + builder_->SetWritingMode(constraint_space_->WritingMode()); |
| + builder_->SetInlineSize(inline_size).SetBlockSize(block_size); |
| + |
| + /*LayoutUnit block_offset = border_and_padding_.block_start; |
| + LayoutUnit inline_offset = border_and_padding_.inline_start;*/ |
| + |
| + NGBreakToken* break_token = |
| + break_token_; // TODO we should have a special multi-col break token. |
| + do { |
| + RefPtr<NGPhysicalFragment> physical_fragment = |
| + NGBlockLayoutAlgorithm(node_, space_builder_->ToConstraintSpace(), |
| + toNGBlockBreakToken(break_token)) |
| + .Layout(); |
| + |
| + // TODO(ikilpatrick): we need to check if a spanner was bubbled up to us, if |
| + // so, layout that next across all the columns. :) |
|
mstensho (USE GERRIT)
2017/02/15 21:12:23
I'm against using spanners and smileys in the same
ikilpatrick
2017/02/16 16:48:32
:)
|
| + |
| + break_token = physical_fragment->BreakToken(); |
| + } while (!break_token->IsFinished()); // TODO OR WE SHOULD FRAGMENT. |
| + |
| + // Recompute the block-axis size now that we know our content size. |
| + block_size = |
| + ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); |
| + builder_->SetBlockSize(block_size); |
| + builder_->SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_); |
| + |
| + return builder_->ToBoxFragment(); |
| +} |
| + |
| +} // namespace blink |