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 #include "core/layout/ng/ng_fragment_builder.h" | 5 #include "core/layout/ng/ng_fragment_builder.h" |
6 | 6 |
7 #include "core/layout/ng/inline/ng_physical_text_fragment.h" | 7 #include "core/layout/ng/inline/ng_physical_text_fragment.h" |
8 #include "core/layout/ng/ng_block_break_token.h" | 8 #include "core/layout/ng/ng_block_break_token.h" |
9 #include "core/layout/ng/ng_block_node.h" | 9 #include "core/layout/ng/ng_block_node.h" |
10 #include "core/layout/ng/ng_break_token.h" | 10 #include "core/layout/ng/ng_break_token.h" |
11 #include "core/layout/ng/ng_fragment.h" | 11 #include "core/layout/ng/ng_fragment.h" |
12 #include "core/layout/ng/ng_layout_result.h" | 12 #include "core/layout/ng/ng_layout_result.h" |
13 #include "core/layout/ng/ng_physical_box_fragment.h" | 13 #include "core/layout/ng/ng_physical_box_fragment.h" |
14 #include "platform/heap/Handle.h" | 14 #include "platform/heap/Handle.h" |
15 | 15 |
16 namespace blink { | 16 namespace blink { |
17 | 17 |
18 // TODO(ikilpatrick): Make writing mode and direction be in the constructor. | 18 // TODO(ikilpatrick): Make writing mode and direction be in the constructor. |
19 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, | 19 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, |
20 NGLayoutInputNode* node) | 20 NGLayoutInputNode node) |
21 : type_(type), | 21 : type_(type), |
22 writing_mode_(kHorizontalTopBottom), | 22 writing_mode_(kHorizontalTopBottom), |
23 direction_(TextDirection::kLtr), | 23 direction_(TextDirection::kLtr), |
24 node_(node), | 24 node_(node), |
25 layout_object_(node->GetLayoutObject()), | 25 layout_object_(node.GetLayoutObject()), |
26 did_break_(false), | 26 did_break_(false), |
27 border_edges_(NGBorderEdges::kAll) {} | 27 border_edges_(NGBorderEdges::kAll) {} |
28 | 28 |
29 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, | 29 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, |
30 LayoutObject* layout_object) | 30 LayoutObject* layout_object) |
31 : type_(type), | 31 : type_(type), |
32 writing_mode_(kHorizontalTopBottom), | 32 writing_mode_(kHorizontalTopBottom), |
33 direction_(TextDirection::kLtr), | 33 direction_(TextDirection::kLtr), |
| 34 node_(nullptr), |
34 layout_object_(layout_object), | 35 layout_object_(layout_object), |
35 did_break_(false) {} | 36 did_break_(false) {} |
36 | 37 |
37 NGFragmentBuilder& NGFragmentBuilder::SetWritingMode( | 38 NGFragmentBuilder& NGFragmentBuilder::SetWritingMode( |
38 NGWritingMode writing_mode) { | 39 NGWritingMode writing_mode) { |
39 writing_mode_ = writing_mode; | 40 writing_mode_ = writing_mode; |
40 return *this; | 41 return *this; |
41 } | 42 } |
42 | 43 |
43 NGFragmentBuilder& NGFragmentBuilder::SetDirection(TextDirection direction) { | 44 NGFragmentBuilder& NGFragmentBuilder::SetDirection(TextDirection direction) { |
(...skipping 24 matching lines...) Expand all Loading... |
68 | 69 |
69 NGFragmentBuilder& NGFragmentBuilder::AddChild( | 70 NGFragmentBuilder& NGFragmentBuilder::AddChild( |
70 RefPtr<NGLayoutResult> child, | 71 RefPtr<NGLayoutResult> child, |
71 const NGLogicalOffset& child_offset) { | 72 const NGLogicalOffset& child_offset) { |
72 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) | 73 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) |
73 << "Only box fragments can have children"; | 74 << "Only box fragments can have children"; |
74 | 75 |
75 // Collect child's out of flow descendants. | 76 // Collect child's out of flow descendants. |
76 const Vector<NGStaticPosition>& oof_positions = child->OutOfFlowPositions(); | 77 const Vector<NGStaticPosition>& oof_positions = child->OutOfFlowPositions(); |
77 size_t oof_index = 0; | 78 size_t oof_index = 0; |
78 for (auto& oof_node : child->OutOfFlowDescendants()) { | 79 for (NGBlockNode oof_node : child->OutOfFlowDescendants()) { |
79 NGStaticPosition oof_position = oof_positions[oof_index++]; | 80 NGStaticPosition oof_position = oof_positions[oof_index++]; |
80 out_of_flow_descendant_candidates_.insert(oof_node); | 81 out_of_flow_descendant_candidates_.push_back(oof_node); |
81 out_of_flow_candidate_placements_.push_back( | 82 out_of_flow_candidate_placements_.push_back( |
82 OutOfFlowPlacement{child_offset, oof_position}); | 83 OutOfFlowPlacement{child_offset, oof_position}); |
83 } | 84 } |
84 | 85 |
85 return AddChild(child->PhysicalFragment(), child_offset); | 86 return AddChild(child->PhysicalFragment(), child_offset); |
86 } | 87 } |
87 | 88 |
88 NGFragmentBuilder& NGFragmentBuilder::AddChild( | 89 NGFragmentBuilder& NGFragmentBuilder::AddChild( |
89 RefPtr<NGPhysicalFragment> child, | 90 RefPtr<NGPhysicalFragment> child, |
90 const NGLogicalOffset& child_offset) { | 91 const NGLogicalOffset& child_offset) { |
91 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) | 92 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) |
92 << "Only box fragments can have children"; | 93 << "Only box fragments can have children"; |
93 | 94 |
94 switch (child->Type()) { | 95 switch (child->Type()) { |
95 case NGPhysicalBoxFragment::kFragmentBox: | 96 case NGPhysicalBoxFragment::kFragmentBox: |
96 // Update if we have fragmented in this flow. | 97 // Update if we have fragmented in this flow. |
97 if (child->BreakToken()) { | 98 if (child->BreakToken()) { |
98 did_break_ |= !child->BreakToken()->IsFinished(); | 99 did_break_ |= !child->BreakToken()->IsFinished(); |
99 child_break_tokens_.push_back(child->BreakToken()); | 100 child_break_tokens_.push_back(child->BreakToken()); |
100 } | 101 } |
101 break; | 102 break; |
102 case NGPhysicalBoxFragment::kFragmentLineBox: | 103 case NGPhysicalBoxFragment::kFragmentLineBox: |
103 // NGInlineNode produces multiple line boxes in an anonymous box. Only | 104 // NGInlineNode produces multiple line boxes in an anonymous box. Only |
104 // the last break token is needed to be reported to the parent. | 105 // the last break token is needed to be reported to the parent. |
105 DCHECK(child->BreakToken()); | 106 DCHECK(child->BreakToken()); |
106 DCHECK_EQ(child->BreakToken()->InputNode(), node_); | 107 DCHECK(child->BreakToken()->InputNode() == node_); |
107 last_inline_break_token_ = | 108 last_inline_break_token_ = |
108 child->BreakToken()->IsFinished() ? nullptr : child->BreakToken(); | 109 child->BreakToken()->IsFinished() ? nullptr : child->BreakToken(); |
109 break; | 110 break; |
110 case NGPhysicalBoxFragment::kFragmentText: | 111 case NGPhysicalBoxFragment::kFragmentText: |
111 DCHECK(!child->BreakToken()); | 112 DCHECK(!child->BreakToken()); |
112 break; | 113 break; |
113 default: | 114 default: |
114 NOTREACHED(); | 115 NOTREACHED(); |
115 break; | 116 break; |
116 } | 117 } |
(...skipping 12 matching lines...) Expand all Loading... |
129 return *this; | 130 return *this; |
130 } | 131 } |
131 | 132 |
132 NGFragmentBuilder& NGFragmentBuilder::SetBfcOffset( | 133 NGFragmentBuilder& NGFragmentBuilder::SetBfcOffset( |
133 const NGLogicalOffset& offset) { | 134 const NGLogicalOffset& offset) { |
134 bfc_offset_ = offset; | 135 bfc_offset_ = offset; |
135 return *this; | 136 return *this; |
136 } | 137 } |
137 | 138 |
138 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowChildCandidate( | 139 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowChildCandidate( |
139 NGBlockNode* child, | 140 NGBlockNode child, |
140 NGLogicalOffset child_offset) { | 141 NGLogicalOffset child_offset) { |
141 out_of_flow_descendant_candidates_.insert(child); | 142 out_of_flow_descendant_candidates_.push_back(child); |
142 NGStaticPosition child_position = | 143 NGStaticPosition child_position = |
143 NGStaticPosition::Create(writing_mode_, direction_, NGPhysicalOffset()); | 144 NGStaticPosition::Create(writing_mode_, direction_, NGPhysicalOffset()); |
144 out_of_flow_candidate_placements_.push_back( | 145 out_of_flow_candidate_placements_.push_back( |
145 OutOfFlowPlacement{child_offset, child_position}); | 146 OutOfFlowPlacement{child_offset, child_position}); |
146 child->SaveStaticOffsetForLegacy(child_offset); | 147 child.SaveStaticOffsetForLegacy(child_offset); |
147 return *this; | 148 return *this; |
148 } | 149 } |
149 | 150 |
150 NGFragmentBuilder& NGFragmentBuilder::AddUnpositionedFloat( | 151 NGFragmentBuilder& NGFragmentBuilder::AddUnpositionedFloat( |
151 RefPtr<NGUnpositionedFloat> unpositioned_float) { | 152 RefPtr<NGUnpositionedFloat> unpositioned_float) { |
152 unpositioned_floats_.push_back(std::move(unpositioned_float)); | 153 unpositioned_floats_.push_back(std::move(unpositioned_float)); |
153 return *this; | 154 return *this; |
154 } | 155 } |
155 | 156 |
156 void NGFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates( | 157 void NGFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates( |
157 WeakBoxList* descendants, | 158 Vector<NGBlockNode>* descendants, |
158 Vector<NGStaticPosition>* descendant_positions) { | 159 Vector<NGStaticPosition>* descendant_positions) { |
159 DCHECK(descendants->IsEmpty()); | 160 DCHECK(descendants->IsEmpty()); |
160 DCHECK(descendant_positions->IsEmpty()); | 161 DCHECK(descendant_positions->IsEmpty()); |
161 | 162 |
162 DCHECK_GE(size_.inline_size, LayoutUnit()); | 163 DCHECK_GE(size_.inline_size, LayoutUnit()); |
163 DCHECK_GE(size_.block_size, LayoutUnit()); | 164 DCHECK_GE(size_.block_size, LayoutUnit()); |
164 NGPhysicalSize builder_physical_size{size_.ConvertToPhysical(writing_mode_)}; | 165 NGPhysicalSize builder_physical_size{size_.ConvertToPhysical(writing_mode_)}; |
165 | 166 |
166 size_t placement_index = 0; | 167 size_t placement_index = 0; |
167 for (auto& oof_node : out_of_flow_descendant_candidates_) { | 168 for (NGBlockNode oof_node : out_of_flow_descendant_candidates_) { |
168 OutOfFlowPlacement oof_placement = | 169 OutOfFlowPlacement oof_placement = |
169 out_of_flow_candidate_placements_[placement_index++]; | 170 out_of_flow_candidate_placements_[placement_index++]; |
170 | 171 |
171 NGPhysicalOffset child_offset = | 172 NGPhysicalOffset child_offset = |
172 oof_placement.child_offset.ConvertToPhysical( | 173 oof_placement.child_offset.ConvertToPhysical( |
173 writing_mode_, direction_, builder_physical_size, NGPhysicalSize()); | 174 writing_mode_, direction_, builder_physical_size, NGPhysicalSize()); |
174 | 175 |
175 NGStaticPosition builder_relative_position; | 176 NGStaticPosition builder_relative_position; |
176 builder_relative_position.type = oof_placement.descendant_position.type; | 177 builder_relative_position.type = oof_placement.descendant_position.type; |
177 builder_relative_position.offset = | 178 builder_relative_position.offset = |
178 child_offset + oof_placement.descendant_position.offset; | 179 child_offset + oof_placement.descendant_position.offset; |
179 descendants->insert(oof_node); | 180 descendants->push_back(oof_node); |
180 descendant_positions->push_back(builder_relative_position); | 181 descendant_positions->push_back(builder_relative_position); |
181 } | 182 } |
182 out_of_flow_descendant_candidates_.clear(); | 183 out_of_flow_descendant_candidates_.clear(); |
183 out_of_flow_candidate_placements_.clear(); | 184 out_of_flow_candidate_placements_.clear(); |
184 } | 185 } |
185 | 186 |
186 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowDescendant( | 187 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowDescendant( |
187 NGBlockNode* descendant, | 188 NGBlockNode descendant, |
188 const NGStaticPosition& position) { | 189 const NGStaticPosition& position) { |
189 out_of_flow_descendants_.insert(descendant); | 190 out_of_flow_descendants_.push_back(descendant); |
190 out_of_flow_positions_.push_back(position); | 191 out_of_flow_positions_.push_back(position); |
191 return *this; | 192 return *this; |
192 } | 193 } |
193 | 194 |
194 RefPtr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment() { | 195 RefPtr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment() { |
195 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox); | 196 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox); |
196 DCHECK_EQ(offsets_.size(), children_.size()); | 197 DCHECK_EQ(offsets_.size(), children_.size()); |
197 | 198 |
198 NGPhysicalSize physical_size = size_.ConvertToPhysical(writing_mode_); | 199 NGPhysicalSize physical_size = size_.ConvertToPhysical(writing_mode_); |
199 | 200 |
200 for (size_t i = 0; i < children_.size(); ++i) { | 201 for (size_t i = 0; i < children_.size(); ++i) { |
201 NGPhysicalFragment* child = children_[i].Get(); | 202 NGPhysicalFragment* child = children_[i].Get(); |
202 child->SetOffset(offsets_[i].ConvertToPhysical( | 203 child->SetOffset(offsets_[i].ConvertToPhysical( |
203 writing_mode_, direction_, physical_size, child->Size())); | 204 writing_mode_, direction_, physical_size, child->Size())); |
204 } | 205 } |
205 | 206 |
206 RefPtr<NGBreakToken> break_token; | 207 RefPtr<NGBreakToken> break_token; |
207 if (node_) { | 208 if (node_) { |
208 if (last_inline_break_token_) { | 209 if (last_inline_break_token_) { |
209 DCHECK(!last_inline_break_token_->IsFinished()); | 210 DCHECK(!last_inline_break_token_->IsFinished()); |
210 child_break_tokens_.push_back(std::move(last_inline_break_token_)); | 211 child_break_tokens_.push_back(std::move(last_inline_break_token_)); |
211 did_break_ = true; | 212 did_break_ = true; |
212 } | 213 } |
213 if (did_break_) { | 214 if (did_break_) { |
214 break_token = NGBlockBreakToken::Create(node_.Get(), used_block_size_, | 215 break_token = NGBlockBreakToken::Create(node_, used_block_size_, |
215 child_break_tokens_); | 216 child_break_tokens_); |
216 } else { | 217 } else { |
217 break_token = NGBlockBreakToken::Create(node_.Get()); | 218 break_token = NGBlockBreakToken::Create(node_); |
218 } | 219 } |
219 } | 220 } |
220 | 221 |
221 for (auto& positioned_float : positioned_floats_) { | 222 for (auto& positioned_float : positioned_floats_) { |
222 NGPhysicalFragment* floating_fragment = positioned_float.fragment.Get(); | 223 NGPhysicalFragment* floating_fragment = positioned_float.fragment.Get(); |
223 floating_fragment->SetOffset( | 224 floating_fragment->SetOffset( |
224 positioned_float.logical_offset.ConvertToPhysical( | 225 positioned_float.logical_offset.ConvertToPhysical( |
225 writing_mode_, direction_, physical_size, | 226 writing_mode_, direction_, physical_size, |
226 floating_fragment->Size())); | 227 floating_fragment->Size())); |
227 } | 228 } |
228 | 229 |
229 RefPtr<NGPhysicalBoxFragment> fragment = AdoptRef(new NGPhysicalBoxFragment( | 230 RefPtr<NGPhysicalBoxFragment> fragment = AdoptRef(new NGPhysicalBoxFragment( |
230 layout_object_, physical_size, overflow_.ConvertToPhysical(writing_mode_), | 231 layout_object_, physical_size, overflow_.ConvertToPhysical(writing_mode_), |
231 children_, positioned_floats_, bfc_offset_, end_margin_strut_, | 232 children_, positioned_floats_, bfc_offset_, end_margin_strut_, |
232 NGBorderEdges::ToPhysical(border_edges_, writing_mode_), | 233 NGBorderEdges::ToPhysical(border_edges_, writing_mode_), |
233 std::move(break_token))); | 234 std::move(break_token))); |
234 | 235 |
235 return AdoptRef( | 236 return AdoptRef( |
236 new NGLayoutResult(std::move(fragment), out_of_flow_descendants_, | 237 new NGLayoutResult(std::move(fragment), out_of_flow_descendants_, |
237 out_of_flow_positions_, unpositioned_floats_)); | 238 out_of_flow_positions_, unpositioned_floats_)); |
238 } | 239 } |
239 | 240 |
240 } // namespace blink | 241 } // namespace blink |
OLD | NEW |