OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "core/layout/ng/ng_multi_column_layout_algorithm.h" |
| 6 |
| 7 #include "core/layout/ng/ng_absolute_utils.h" |
| 8 #include "core/layout/ng/ng_block_break_token.h" |
| 9 #include "core/layout/ng/ng_block_layout_algorithm.h" |
| 10 #include "core/layout/ng/ng_box_fragment.h" |
| 11 #include "core/layout/ng/ng_constraint_space.h" |
| 12 #include "core/layout/ng/ng_constraint_space_builder.h" |
| 13 #include "core/layout/ng/ng_fragment.h" |
| 14 #include "core/layout/ng/ng_fragment_builder.h" |
| 15 #include "core/layout/ng/ng_inline_node.h" |
| 16 #include "core/layout/ng/ng_layout_opportunity_iterator.h" |
| 17 #include "core/layout/ng/ng_length_utils.h" |
| 18 #include "core/layout/ng/ng_line_builder.h" |
| 19 #include "core/layout/ng/ng_out_of_flow_layout_part.h" |
| 20 #include "core/style/ComputedStyle.h" |
| 21 #include "platform/LengthFunctions.h" |
| 22 |
| 23 namespace blink { |
| 24 |
| 25 NGMultiColumnLayoutAlgorithm::NGMultiColumnLayoutAlgorithm( |
| 26 NGBlockNode* node, |
| 27 NGConstraintSpace* constraint_space, |
| 28 NGBreakToken* break_token) |
| 29 : node_(node), |
| 30 constraint_space_(constraint_space), |
| 31 break_token_(break_token), |
| 32 builder_(NGPhysicalFragment::kFragmentBox, node), |
| 33 space_builder_(constraint_space) {} |
| 34 |
| 35 Optional<MinMaxContentSize> |
| 36 NGMultiColumnLayoutAlgorithm::ComputeMinMaxContentSize() const { |
| 37 return NGBlockLayoutAlgorithm(node_, constraint_space_, |
| 38 toNGBlockBreakToken(break_token_)) |
| 39 .ComputeMinMaxContentSize(); |
| 40 } |
| 41 |
| 42 RefPtr<NGLayoutResult> NGMultiColumnLayoutAlgorithm::Layout() { |
| 43 WTF::Optional<MinMaxContentSize> sizes; |
| 44 if (NeedMinMaxContentSize(ConstraintSpace(), Style())) |
| 45 sizes = ComputeMinMaxContentSize(); |
| 46 |
| 47 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) + |
| 48 ComputePadding(ConstraintSpace(), Style()); |
| 49 |
| 50 LayoutUnit inline_size = |
| 51 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); |
| 52 |
| 53 DCHECK(Style().specifiesColumns()); |
| 54 LayoutUnit adjusted_inline_size = ResolveUsedColumnInlineSize( |
| 55 inline_size - border_and_padding_.InlineSum(), Style()); |
| 56 |
| 57 /*LayoutUnit inline_progression = |
| 58 adjusted_inline_size + ResolveUsedColumnGap(Style());*/ |
| 59 |
| 60 LayoutUnit block_size = |
| 61 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite); |
| 62 |
| 63 // Our calculated block-axis size may be indefinite at this point. |
| 64 // If so, just leave the size as NGSizeIndefinite instead of subtracting |
| 65 // borders and padding. |
| 66 LayoutUnit adjusted_block_size(block_size); |
| 67 if (adjusted_block_size != NGSizeIndefinite) |
| 68 adjusted_block_size -= border_and_padding_.BlockSum(); |
| 69 |
| 70 space_builder_.SetFragmentationType(kFragmentColumn) |
| 71 .SetAvailableSize( |
| 72 NGLogicalSize(adjusted_inline_size, adjusted_block_size)) |
| 73 .SetPercentageResolutionSize( |
| 74 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); |
| 75 |
| 76 // TODO(ikilpatrick): if we don't have a fragmentation line we should peform a |
| 77 // full layout, determine the break opportunities, and then perform a relayout |
| 78 // into the individual columns. |
| 79 // If __our__ constraint space has a column fragmentation line, we trust that |
| 80 // a multi column algorithm above us has determined the correct layout |
| 81 // opportunites so we just layout with that fragmentation line. |
| 82 |
| 83 // TODO(ikilpatrick): We only support multicols with definite block sizes. |
| 84 DCHECK(adjusted_block_size != NGSizeIndefinite); |
| 85 space_builder_.SetFragmentainerSpaceAvailable( |
| 86 constraint_space_->HasBlockFragmentation() |
| 87 ? constraint_space_->FragmentainerSpaceAvailable() |
| 88 : // TODO need to account for borders and padding. |
| 89 adjusted_block_size); |
| 90 |
| 91 builder_.SetDirection(constraint_space_->Direction()); |
| 92 builder_.SetWritingMode(constraint_space_->WritingMode()); |
| 93 builder_.SetInlineSize(inline_size).SetBlockSize(block_size); |
| 94 |
| 95 /*LayoutUnit block_offset = border_and_padding_.block_start; |
| 96 LayoutUnit inline_offset = border_and_padding_.inline_start;*/ |
| 97 |
| 98 NGBreakToken* break_token = |
| 99 break_token_; // TODO we should have a special multi-col break token. |
| 100 do { |
| 101 RefPtr<NGConstraintSpace> space = space_builder_.ToConstraintSpace( |
| 102 FromPlatformWritingMode(Style().getWritingMode())); |
| 103 |
| 104 RefPtr<NGLayoutResult> layout_result = |
| 105 NGBlockLayoutAlgorithm(node_, space.get(), |
| 106 toNGBlockBreakToken(break_token)) |
| 107 .Layout(); |
| 108 |
| 109 // TODO(ikilpatrick): we need to check if a spanner was bubbled up to us, if |
| 110 // so, layout that next across all the columns. :) |
| 111 |
| 112 break_token = layout_result->PhysicalFragment()->BreakToken(); |
| 113 } while (!break_token->IsFinished()); // TODO OR WE SHOULD FRAGMENT. |
| 114 |
| 115 // Recompute the block-axis size now that we know our content size. |
| 116 block_size = |
| 117 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); |
| 118 builder_.SetBlockSize(block_size); |
| 119 builder_.SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_); |
| 120 |
| 121 return builder_.ToBoxFragment(); |
| 122 } |
| 123 |
| 124 } // namespace blink |
OLD | NEW |