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_block_layout_algorithm.h" | 5 #include "core/layout/ng/ng_block_layout_algorithm.h" |
6 | 6 |
7 #include "core/layout/ng/ng_constraint_space.h" | 7 #include "core/layout/ng/ng_constraint_space.h" |
8 #include "core/layout/ng/ng_fragment_builder.h" | 8 #include "core/layout/ng/ng_fragment_builder.h" |
9 #include "core/layout/ng/ng_fragment.h" | 9 #include "core/layout/ng/ng_fragment.h" |
10 #include "core/layout/ng/ng_layout_opportunity_iterator.h" | 10 #include "core/layout/ng/ng_layout_opportunity_iterator.h" |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::FragmentBox); | 178 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::FragmentBox); |
179 builder_->SetDirection(constraint_space->Direction()); | 179 builder_->SetDirection(constraint_space->Direction()); |
180 builder_->SetWritingMode(constraint_space->WritingMode()); | 180 builder_->SetWritingMode(constraint_space->WritingMode()); |
181 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); | 181 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); |
182 current_child_ = first_child_; | 182 current_child_ = first_child_; |
183 state_ = kStateChildLayout; | 183 state_ = kStateChildLayout; |
184 return false; | 184 return false; |
185 } | 185 } |
186 case kStateChildLayout: { | 186 case kStateChildLayout: { |
187 if (current_child_) { | 187 if (current_child_) { |
188 constraint_space_for_children_->SetIsNewFormattingContext( | 188 if (!LayoutCurrentChild(constraint_space)) |
189 IsNewFormattingContextForInFlowBlockLevelChild( | |
190 *constraint_space, *current_child_->Style())); | |
191 | |
192 NGFragment* fragment; | |
193 if (!current_child_->Layout(constraint_space_for_children_, &fragment)) | |
194 return false; | 189 return false; |
195 | |
196 NGBoxStrut child_margins = ComputeMargins( | |
197 *constraint_space_for_children_, *current_child_->Style(), | |
198 constraint_space_for_children_->WritingMode(), | |
199 constraint_space_for_children_->Direction()); | |
200 | |
201 NGLogicalOffset fragment_offset; | |
202 if (current_child_->Style()->isFloating()) { | |
203 fragment_offset = PositionFloatFragment(*fragment, child_margins); | |
204 } else { | |
205 ApplyAutoMargins(*constraint_space_for_children_, | |
206 *current_child_->Style(), *fragment, &child_margins); | |
207 fragment_offset = | |
208 PositionFragment(*fragment, child_margins, *constraint_space); | |
209 } | |
210 builder_->AddChild(fragment, fragment_offset); | |
211 | |
212 current_child_ = current_child_->NextSibling(); | 190 current_child_ = current_child_->NextSibling(); |
213 if (current_child_) | 191 if (current_child_) |
214 return false; | 192 return false; |
215 } | 193 } |
216 state_ = kStateFinalize; | 194 state_ = kStateFinalize; |
217 return false; | 195 return false; |
218 } | 196 } |
219 case kStateFinalize: { | 197 case kStateFinalize: { |
220 content_size_ += border_and_padding_.block_end; | 198 content_size_ += border_and_padding_.block_end; |
221 | 199 |
222 // Recompute the block-axis size now that we know our content size. | 200 // Recompute the block-axis size now that we know our content size. |
223 LayoutUnit block_size = ComputeBlockSizeForFragment( | 201 LayoutUnit block_size = ComputeBlockSizeForFragment( |
224 *constraint_space, Style(), content_size_); | 202 *constraint_space, Style(), content_size_); |
225 | 203 |
226 builder_->SetBlockSize(block_size) | 204 builder_->SetBlockSize(block_size) |
227 .SetInlineOverflow(max_inline_size_) | 205 .SetInlineOverflow(max_inline_size_) |
228 .SetBlockOverflow(content_size_); | 206 .SetBlockOverflow(content_size_); |
229 *out = builder_->ToFragment(); | 207 *out = builder_->ToFragment(); |
230 state_ = kStateInit; | 208 state_ = kStateInit; |
231 return true; | 209 return true; |
232 } | 210 } |
233 }; | 211 }; |
234 NOTREACHED(); | 212 NOTREACHED(); |
235 *out = nullptr; | 213 *out = nullptr; |
236 return true; | 214 return true; |
237 } | 215 } |
238 | 216 |
| 217 bool NGBlockLayoutAlgorithm::LayoutCurrentChild( |
| 218 const NGConstraintSpace* constraint_space) { |
| 219 constraint_space_for_children_->SetIsNewFormattingContext( |
| 220 IsNewFormattingContextForInFlowBlockLevelChild(*constraint_space, |
| 221 *current_child_->Style())); |
| 222 |
| 223 NGFragment* fragment; |
| 224 if (!current_child_->Layout(constraint_space_for_children_, &fragment)) |
| 225 return false; |
| 226 |
| 227 NGBoxStrut child_margins = |
| 228 ComputeMargins(*constraint_space_for_children_, *current_child_->Style(), |
| 229 constraint_space_for_children_->WritingMode(), |
| 230 constraint_space_for_children_->Direction()); |
| 231 |
| 232 NGLogicalOffset fragment_offset; |
| 233 if (current_child_->Style()->isFloating()) { |
| 234 fragment_offset = PositionFloatFragment(*fragment, child_margins); |
| 235 } else { |
| 236 // TODO(layout-ng): move ApplyAutoMargins to PositionFragment |
| 237 ApplyAutoMargins(*constraint_space_for_children_, *current_child_->Style(), |
| 238 *fragment, &child_margins); |
| 239 fragment_offset = |
| 240 PositionFragment(*fragment, child_margins, *constraint_space); |
| 241 } |
| 242 builder_->AddChild(fragment, fragment_offset); |
| 243 return true; |
| 244 } |
| 245 |
239 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins( | 246 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins( |
240 const NGConstraintSpace& space, | 247 const NGConstraintSpace& space, |
241 const NGBoxStrut& margins, | 248 const NGBoxStrut& margins, |
242 const NGFragment& fragment) { | 249 const NGFragment& fragment) { |
243 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() && | 250 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() && |
244 fragment.MarginStrut().IsEmpty(); | 251 fragment.MarginStrut().IsEmpty(); |
245 // Create the current child's margin strut from its children's margin strut or | 252 // Create the current child's margin strut from its children's margin strut or |
246 // use margin strut from the the last non-empty child. | 253 // use margin strut from the the last non-empty child. |
247 NGMarginStrut curr_margin_strut = | 254 NGMarginStrut curr_margin_strut = |
248 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut(); | 255 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut(); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 } | 353 } |
347 | 354 |
348 void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) { | 355 void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) { |
349 if (!is_fragment_margin_strut_block_start_updated_) { | 356 if (!is_fragment_margin_strut_block_start_updated_) { |
350 builder_->SetMarginStrutBlockStart(from); | 357 builder_->SetMarginStrutBlockStart(from); |
351 is_fragment_margin_strut_block_start_updated_ = true; | 358 is_fragment_margin_strut_block_start_updated_ = true; |
352 } | 359 } |
353 builder_->SetMarginStrutBlockEnd(from); | 360 builder_->SetMarginStrutBlockEnd(from); |
354 } | 361 } |
355 | 362 |
| 363 DEFINE_TRACE(NGBlockLayoutAlgorithm) { |
| 364 NGLayoutAlgorithm::trace(visitor); |
| 365 visitor->trace(first_child_); |
| 366 visitor->trace(builder_); |
| 367 visitor->trace(constraint_space_for_children_); |
| 368 visitor->trace(current_child_); |
| 369 } |
| 370 |
356 } // namespace blink | 371 } // namespace blink |
OLD | NEW |