| 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 | 
|  |