Index: third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc |
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc |
index a3b6f64cbdc44fda9c3d1a81736a5d5e901fbf19..38f4c4a3711ff82adafcf53527de4a56a593042e 100644 |
--- a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc |
+++ b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc |
@@ -3,6 +3,7 @@ |
// found in the LICENSE file. |
#include "core/layout/ng/ng_column_layout_algorithm.h" |
+#include "core/layout/ng/ng_length_utils.h" |
namespace blink { |
@@ -12,8 +13,90 @@ NGColumnLayoutAlgorithm::NGColumnLayoutAlgorithm(NGBlockNode* node, |
: NGBlockLayoutAlgorithm(node, space, toNGBlockBreakToken(break_token)){}; |
RefPtr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() { |
- LOG(FATAL) << "Not implemented"; |
- return nullptr; |
+ WTF::Optional<MinMaxContentSize> sizes; |
+ if (NeedMinMaxContentSize(ConstraintSpace(), Style())) |
+ sizes = ComputeMinMaxContentSize(); |
+ |
+ border_and_padding_ = ComputeBorders(ConstraintSpace(), 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());*/ |
+ |
+ 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_.SetFragmentationType(kFragmentColumn) |
+ .SetAvailableSize( |
+ 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. |
+ RefPtr<NGLayoutResult> layout_result = nullptr; |
+ |
+ // As long as we have the flow thread in the layout tree, we need to skip |
+ // it, and proceed right to its children, when laying out. |
+ if (NGBlockNode* multicol_root = toNGBlockNode(Node()->FirstChild())) { |
+ DCHECK(multicol_root->GetLayoutObject()); |
+ DCHECK(multicol_root->GetLayoutObject()->isLayoutFlowThread()); |
+ do { |
+ RefPtr<NGConstraintSpace> space = space_builder_.ToConstraintSpace( |
+ FromPlatformWritingMode(Style().getWritingMode())); |
+ |
+ auto* block_break_token = toNGBlockBreakToken(break_token); |
+ layout_result = |
+ NGBlockLayoutAlgorithm(multicol_root, space.get(), block_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. :) |
+ |
+ break_token = layout_result->PhysicalFragment()->BreakToken(); |
+ |
+ // TODO(mstensho): Pass correct offset. Need to progress column inline |
+ // offset as we proceed from column to column. |
+ builder_.AddChild(layout_result, NGLogicalOffset()); |
+ } 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 |