OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #ifndef NGBlockLayoutAlgorithm_h | 5 #ifndef NGBlockLayoutAlgorithm_h |
6 #define NGBlockLayoutAlgorithm_h | 6 #define NGBlockLayoutAlgorithm_h |
7 | 7 |
8 #include "core/CoreExport.h" | 8 #include "core/CoreExport.h" |
9 #include "core/layout/ng/geometry/ng_margin_strut.h" | 9 #include "core/layout/ng/geometry/ng_margin_strut.h" |
10 #include "core/layout/ng/ng_block_break_token.h" | 10 #include "core/layout/ng/ng_block_break_token.h" |
11 #include "core/layout/ng/ng_block_node.h" | 11 #include "core/layout/ng/ng_block_node.h" |
12 #include "core/layout/ng/ng_box_fragment.h" | 12 #include "core/layout/ng/ng_box_fragment.h" |
13 #include "core/layout/ng/ng_constraint_space_builder.h" | 13 #include "core/layout/ng/ng_constraint_space_builder.h" |
14 #include "core/layout/ng/ng_layout_algorithm.h" | 14 #include "core/layout/ng/ng_layout_algorithm.h" |
15 #include "platform/wtf/RefPtr.h" | 15 #include "platform/wtf/RefPtr.h" |
16 | 16 |
17 namespace blink { | 17 namespace blink { |
18 | 18 |
19 class NGConstraintSpace; | 19 class NGConstraintSpace; |
20 class NGLayoutResult; | 20 class NGLayoutResult; |
21 struct NGInflowChildData; | 21 |
22 struct NGPreviousInflowPosition; | 22 // This struct is used for communicating to a child the position of the |
| 23 // previous inflow child. |
| 24 struct NGPreviousInflowPosition { |
| 25 LayoutUnit bfc_block_offset; |
| 26 LayoutUnit logical_block_offset; |
| 27 NGMarginStrut margin_strut; |
| 28 }; |
| 29 |
| 30 // This strut holds information for the current inflow child. The data is not |
| 31 // useful outside of handling this single inflow child. |
| 32 struct NGInflowChildData { |
| 33 NGLogicalOffset bfc_offset_estimate; |
| 34 NGMarginStrut margin_strut; |
| 35 NGBoxStrut margins; |
| 36 }; |
23 | 37 |
24 // Updates the fragment's BFC offset if it's not already set. | 38 // Updates the fragment's BFC offset if it's not already set. |
25 void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace&, | 39 bool MaybeUpdateFragmentBfcOffset(const NGConstraintSpace&, |
26 LayoutUnit bfc_block_offset, | 40 LayoutUnit bfc_block_offset, |
27 NGFragmentBuilder* builder); | 41 NGFragmentBuilder* builder); |
28 | 42 |
29 // Positions pending floats starting from {@origin_block_offset} and relative | 43 // Positions pending floats starting from {@origin_block_offset} and relative |
30 // to container's BFC offset. | 44 // to container's BFC offset. |
31 void PositionPendingFloats(LayoutUnit origin_block_offset, | 45 void PositionPendingFloats( |
32 NGFragmentBuilder* container_builder, | 46 LayoutUnit origin_block_offset, |
33 NGConstraintSpace* space); | 47 NGFragmentBuilder* container_builder, |
| 48 Vector<RefPtr<NGUnpositionedFloat>>* unpositioned_floats, |
| 49 NGConstraintSpace* space); |
34 | 50 |
35 // A class for general block layout (e.g. a <div> with no special style). | 51 // A class for general block layout (e.g. a <div> with no special style). |
36 // Lays out the children in sequence. | 52 // Lays out the children in sequence. |
37 class CORE_EXPORT NGBlockLayoutAlgorithm | 53 class CORE_EXPORT NGBlockLayoutAlgorithm |
38 : public NGLayoutAlgorithm<NGBlockNode, NGBlockBreakToken> { | 54 : public NGLayoutAlgorithm<NGBlockNode, NGBlockBreakToken> { |
39 public: | 55 public: |
40 // Default constructor. | 56 // Default constructor. |
41 // @param node The input node to perform layout upon. | 57 // @param node The input node to perform layout upon. |
42 // @param space The constraint space which the algorithm should generate a | 58 // @param space The constraint space which the algorithm should generate a |
43 // fragment within. | 59 // fragment within. |
44 // @param break_token The break token from which the layout should start. | 60 // @param break_token The break token from which the layout should start. |
45 NGBlockLayoutAlgorithm(NGBlockNode node, | 61 NGBlockLayoutAlgorithm(NGBlockNode node, |
46 NGConstraintSpace* space, | 62 NGConstraintSpace* space, |
47 NGBlockBreakToken* break_token = nullptr); | 63 NGBlockBreakToken* break_token = nullptr); |
48 | 64 |
49 Optional<MinMaxContentSize> ComputeMinMaxContentSize() const override; | 65 Optional<MinMaxContentSize> ComputeMinMaxContentSize() const override; |
50 virtual RefPtr<NGLayoutResult> Layout() override; | 66 virtual RefPtr<NGLayoutResult> Layout() override; |
51 | 67 |
52 private: | 68 private: |
53 NGBoxStrut CalculateMargins(NGLayoutInputNode child); | 69 NGBoxStrut CalculateMargins(NGLayoutInputNode child); |
54 | 70 |
55 // Creates a new constraint space for the current child. | 71 // Creates a new constraint space for the current child. |
56 RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild( | 72 RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild( |
57 const NGLayoutInputNode child, | 73 const NGLayoutInputNode child, |
58 const NGInflowChildData& child_data); | 74 const NGInflowChildData& child_data, |
| 75 const WTF::Optional<NGLogicalOffset> floats_bfc_offset = WTF::nullopt); |
59 | 76 |
60 // @return Estimated BFC offset for the "to be layout" child. | 77 // @return Estimated BFC offset for the "to be layout" child. |
61 NGInflowChildData PrepareChildLayout(const NGPreviousInflowPosition&, | 78 WTF::Optional<NGInflowChildData> PrepareChildLayout( |
62 NGLayoutInputNode); | 79 const NGPreviousInflowPosition&, |
| 80 NGLayoutInputNode); |
63 | 81 |
64 NGPreviousInflowPosition FinishChildLayout( | 82 WTF::Optional<NGPreviousInflowPosition> FinishChildLayout( |
65 const NGConstraintSpace&, | 83 const NGConstraintSpace&, |
66 const NGPreviousInflowPosition& prev_data, | 84 const NGPreviousInflowPosition& prev_data, |
67 const NGInflowChildData& child_data, | 85 const NGInflowChildData& child_data, |
68 const NGLayoutInputNode child, | 86 NGLayoutInputNode child, |
69 NGLayoutResult*); | 87 NGBreakToken* child_break_token, |
| 88 RefPtr<NGLayoutResult>); |
70 | 89 |
71 // Positions the fragment that establishes a new formatting context. | 90 // Positions the fragment that establishes a new formatting context. |
72 // | 91 // |
73 // This uses Layout Opportunity iterator to position the fragment. | 92 // This uses Layout Opportunity iterator to position the fragment. |
74 // That's because an element that establishes a new block formatting context | 93 // That's because an element that establishes a new block formatting context |
75 // must not overlap the margin box of any floats in the same block formatting | 94 // must not overlap the margin box of any floats in the same block formatting |
76 // context as the element itself. | 95 // context as the element itself. |
77 // | 96 // |
78 // So if necessary, we clear the new BFC by placing it below any preceding | 97 // So if necessary, we clear the new BFC by placing it below any preceding |
79 // floats or place it adjacent to such floats if there is sufficient space. | 98 // floats or place it adjacent to such floats if there is sufficient space. |
80 // | 99 // |
81 // Example: | 100 // Example: |
82 // <div id="container"> | 101 // <div id="container"> |
83 // <div id="float"></div> | 102 // <div id="float"></div> |
84 // <div id="new-fc" style="margin-top: 20px;"></div> | 103 // <div id="new-fc" style="margin-top: 20px;"></div> |
85 // </div> | 104 // </div> |
86 // 1) If #new-fc is small enough to fit the available space right from #float | 105 // 1) If #new-fc is small enough to fit the available space right from #float |
87 // then it will be placed there and we collapse its margin. | 106 // then it will be placed there and we collapse its margin. |
88 // 2) If #new-fc is too big then we need to clear its position and place it | 107 // 2) If #new-fc is too big then we need to clear its position and place it |
89 // below #float ignoring its vertical margin. | 108 // below #float ignoring its vertical margin. |
90 NGLogicalOffset PositionNewFc(const NGLayoutInputNode& child, | 109 bool PositionNewFc(const NGLayoutInputNode& child, |
91 const NGPreviousInflowPosition&, | 110 const NGPreviousInflowPosition&, |
92 const NGBoxFragment&, | 111 const NGLayoutResult&, |
93 const NGInflowChildData& child_data, | 112 const NGInflowChildData& child_data, |
94 const NGConstraintSpace& child_space); | 113 const NGConstraintSpace& child_space, |
| 114 WTF::Optional<NGLogicalOffset>* child_bfc_offset); |
95 | 115 |
96 // Positions the fragment that knows its BFC offset. | 116 // Positions the fragment that knows its BFC offset. |
97 NGLogicalOffset PositionWithBfcOffset(const NGLogicalOffset& bfc_offset); | 117 WTF::Optional<NGLogicalOffset> PositionWithBfcOffset( |
| 118 const NGLogicalOffset& bfc_offset); |
| 119 bool PositionWithBfcOffset(const NGLogicalOffset& bfc_offset, |
| 120 WTF::Optional<NGLogicalOffset>* child_bfc_offset); |
98 | 121 |
99 // Positions using the parent BFC offset. | 122 // Positions using the parent BFC offset. |
100 // Fragment doesn't know its offset but we can still calculate its BFC | 123 // Fragment doesn't know its offset but we can still calculate its BFC |
101 // position because the parent fragment's BFC is known. | 124 // position because the parent fragment's BFC is known. |
102 // Example: | 125 // Example: |
103 // BFC Offset is known here because of the padding. | 126 // BFC Offset is known here because of the padding. |
104 // <div style="padding: 1px"> | 127 // <div style="padding: 1px"> |
105 // <div id="empty-div" style="margins: 1px"></div> | 128 // <div id="empty-div" style="margins: 1px"></div> |
106 NGLogicalOffset PositionWithParentBfc(const NGConstraintSpace&, | 129 NGLogicalOffset PositionWithParentBfc(const NGConstraintSpace&, |
107 const NGInflowChildData& child_data, | 130 const NGInflowChildData& child_data, |
(...skipping 22 matching lines...) Expand all Loading... |
130 NGLogicalOffset CalculateLogicalOffset( | 153 NGLogicalOffset CalculateLogicalOffset( |
131 const NGBoxStrut& child_margins, | 154 const NGBoxStrut& child_margins, |
132 const WTF::Optional<NGLogicalOffset>& known_fragment_offset); | 155 const WTF::Optional<NGLogicalOffset>& known_fragment_offset); |
133 | 156 |
134 NGLogicalSize child_available_size_; | 157 NGLogicalSize child_available_size_; |
135 NGLogicalSize child_percentage_size_; | 158 NGLogicalSize child_percentage_size_; |
136 | 159 |
137 NGBoxStrut border_scrollbar_padding_; | 160 NGBoxStrut border_scrollbar_padding_; |
138 LayoutUnit content_size_; | 161 LayoutUnit content_size_; |
139 LayoutUnit max_inline_size_; | 162 LayoutUnit max_inline_size_; |
| 163 |
| 164 bool abort_when_bfc_resolved_; |
| 165 |
| 166 Vector<RefPtr<NGUnpositionedFloat>> unpositioned_floats_; |
140 }; | 167 }; |
141 | 168 |
142 } // namespace blink | 169 } // namespace blink |
143 | 170 |
144 #endif // NGBlockLayoutAlgorithm_h | 171 #endif // NGBlockLayoutAlgorithm_h |
OLD | NEW |