OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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_column_layout_algorithm.h" | 5 #include "core/layout/ng/ng_column_layout_algorithm.h" |
| 6 #include "core/layout/ng/ng_length_utils.h" |
6 | 7 |
7 namespace blink { | 8 namespace blink { |
8 | 9 |
9 NGColumnLayoutAlgorithm::NGColumnLayoutAlgorithm(NGBlockNode* node, | 10 NGColumnLayoutAlgorithm::NGColumnLayoutAlgorithm(NGBlockNode* node, |
10 NGConstraintSpace* space, | 11 NGConstraintSpace* space, |
11 NGBreakToken* break_token) | 12 NGBreakToken* break_token) |
12 : NGBlockLayoutAlgorithm(node, space, toNGBlockBreakToken(break_token)){}; | 13 : NGBlockLayoutAlgorithm(node, space, toNGBlockBreakToken(break_token)){}; |
13 | 14 |
14 RefPtr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() { | 15 RefPtr<NGLayoutResult> NGColumnLayoutAlgorithm::Layout() { |
15 LOG(FATAL) << "Not implemented"; | 16 WTF::Optional<MinMaxContentSize> sizes; |
16 return nullptr; | 17 if (NeedMinMaxContentSize(ConstraintSpace(), Style())) |
| 18 sizes = ComputeMinMaxContentSize(); |
| 19 |
| 20 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) + |
| 21 ComputePadding(ConstraintSpace(), Style()); |
| 22 LayoutUnit inline_size = |
| 23 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); |
| 24 DCHECK(Style().specifiesColumns()); |
| 25 LayoutUnit adjusted_inline_size = ResolveUsedColumnInlineSize( |
| 26 inline_size - border_and_padding_.InlineSum(), Style()); |
| 27 /*LayoutUnit inline_progression = |
| 28 adjusted_inline_size + ResolveUsedColumnGap(Style());*/ |
| 29 |
| 30 LayoutUnit block_size = |
| 31 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite); |
| 32 |
| 33 // Our calculated block-axis size may be indefinite at this point. |
| 34 // If so, just leave the size as NGSizeIndefinite instead of subtracting |
| 35 // borders and padding. |
| 36 LayoutUnit adjusted_block_size(block_size); |
| 37 if (adjusted_block_size != NGSizeIndefinite) |
| 38 adjusted_block_size -= border_and_padding_.BlockSum(); |
| 39 space_builder_.SetFragmentationType(kFragmentColumn) |
| 40 .SetAvailableSize( |
| 41 NGLogicalSize(adjusted_inline_size, adjusted_block_size)) |
| 42 .SetPercentageResolutionSize( |
| 43 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); |
| 44 |
| 45 // TODO(ikilpatrick): if we don't have a fragmentation line we should peform a |
| 46 // full layout, determine the break opportunities, and then perform a relayout |
| 47 // into the individual columns. |
| 48 // If __our__ constraint space has a column fragmentation line, we trust that |
| 49 // a multi column algorithm above us has determined the correct layout |
| 50 // opportunites so we just layout with that fragmentation line. |
| 51 // TODO(ikilpatrick): We only support multicols with definite block sizes. |
| 52 DCHECK(adjusted_block_size != NGSizeIndefinite); |
| 53 |
| 54 space_builder_.SetFragmentainerSpaceAvailable( |
| 55 constraint_space_->HasBlockFragmentation() |
| 56 ? constraint_space_->FragmentainerSpaceAvailable() |
| 57 : // TODO need to account for borders and padding. |
| 58 adjusted_block_size); |
| 59 builder_.SetDirection(constraint_space_->Direction()); |
| 60 builder_.SetWritingMode(constraint_space_->WritingMode()); |
| 61 builder_.SetInlineSize(inline_size).SetBlockSize(block_size); |
| 62 /*LayoutUnit block_offset = border_and_padding_.block_start; |
| 63 LayoutUnit inline_offset = border_and_padding_.inline_start;*/ |
| 64 NGBreakToken* break_token = |
| 65 break_token_; // TODO we should have a special multi-col break token. |
| 66 RefPtr<NGLayoutResult> layout_result = nullptr; |
| 67 |
| 68 // As long as we have the flow thread in the layout tree, we need to skip |
| 69 // it, and proceed right to its children, when laying out. |
| 70 if (NGBlockNode* multicol_root = toNGBlockNode(Node()->FirstChild())) { |
| 71 DCHECK(multicol_root->GetLayoutObject()); |
| 72 DCHECK(multicol_root->GetLayoutObject()->isLayoutFlowThread()); |
| 73 do { |
| 74 RefPtr<NGConstraintSpace> space = space_builder_.ToConstraintSpace( |
| 75 FromPlatformWritingMode(Style().getWritingMode())); |
| 76 |
| 77 auto* block_break_token = toNGBlockBreakToken(break_token); |
| 78 layout_result = |
| 79 NGBlockLayoutAlgorithm(multicol_root, space.get(), block_break_token) |
| 80 .Layout(); |
| 81 |
| 82 // TODO(ikilpatrick): we need to check if a spanner was bubbled up to us, |
| 83 // if so, layout that next across all the columns. :) |
| 84 |
| 85 break_token = layout_result->PhysicalFragment()->BreakToken(); |
| 86 |
| 87 // TODO(mstensho): Pass correct offset. Need to progress column inline |
| 88 // offset as we proceed from column to column. |
| 89 builder_.AddChild(layout_result, NGLogicalOffset()); |
| 90 } while (!break_token->IsFinished()); // TODO OR WE SHOULD FRAGMENT. |
| 91 } |
| 92 |
| 93 // Recompute the block-axis size now that we know our content size. |
| 94 block_size = |
| 95 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); |
| 96 builder_.SetBlockSize(block_size); |
| 97 builder_.SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_); |
| 98 |
| 99 return builder_.ToBoxFragment(); |
17 } | 100 } |
18 | 101 |
19 } // namespace Blink | 102 } // namespace Blink |
OLD | NEW |