Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc

Issue 2568743005: Place the out of flow positioned blocks (Closed)
Patch Set: skip failing tests Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_break_token.h" 7 #include "core/layout/ng/ng_break_token.h"
8 #include "core/layout/ng/ng_constraint_space.h" 8 #include "core/layout/ng/ng_constraint_space.h"
9 #include "core/layout/ng/ng_constraint_space_builder.h" 9 #include "core/layout/ng/ng_constraint_space_builder.h"
10 #include "core/layout/ng/ng_fragment_base.h" 10 #include "core/layout/ng/ng_fragment_base.h"
11 #include "core/layout/ng/ng_fragment_builder.h" 11 #include "core/layout/ng/ng_fragment_builder.h"
12 #include "core/layout/ng/ng_fragment.h" 12 #include "core/layout/ng/ng_fragment.h"
13 #include "core/layout/ng/ng_layout_opportunity_iterator.h" 13 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
14 #include "core/layout/ng/ng_length_utils.h" 14 #include "core/layout/ng/ng_length_utils.h"
15 #include "core/layout/ng/ng_out_of_flow_layout_part.h"
15 #include "core/layout/ng/ng_units.h" 16 #include "core/layout/ng/ng_units.h"
16 #include "core/style/ComputedStyle.h" 17 #include "core/style/ComputedStyle.h"
17 #include "platform/LengthFunctions.h" 18 #include "platform/LengthFunctions.h"
18 #include "wtf/Optional.h" 19 #include "wtf/Optional.h"
19 20
20 namespace blink { 21 namespace blink {
21 namespace { 22 namespace {
22 23
23 // Adjusts content's offset to CSS "clear" property. 24 // Adjusts content's offset to CSS "clear" property.
24 // TODO(glebl): Support margin collapsing edge cases, e.g. margin collapsing 25 // TODO(glebl): Support margin collapsing edge cases, e.g. margin collapsing
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 builder_->SetDirection(constraint_space_->Direction()); 286 builder_->SetDirection(constraint_space_->Direction());
286 builder_->SetWritingMode(constraint_space_->WritingMode()); 287 builder_->SetWritingMode(constraint_space_->WritingMode());
287 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); 288 builder_->SetInlineSize(inline_size).SetBlockSize(block_size);
288 289
289 current_child_ = first_child_; 290 current_child_ = first_child_;
290 layout_state_ = kStatePrepareForChildLayout; 291 layout_state_ = kStatePrepareForChildLayout;
291 return kNotFinished; 292 return kNotFinished;
292 } 293 }
293 case kStatePrepareForChildLayout: { 294 case kStatePrepareForChildLayout: {
294 if (current_child_) { 295 if (current_child_) {
295 // TODO(atotic): uncomment this code when implementing oof layout. 296 EPosition position = current_child_->Style()->position();
296 // This code cannot be turned on because it prevents layout of 297 if ((position == AbsolutePosition || position == FixedPosition)) {
297 // oof children, and non-layedout objects trigger a DCHECK. 298 builder_->AddOutOfFlowChildCandidate(current_child_,
298 // EPosition position = current_child_->Style()->position(); 299 GetChildSpaceOffset());
299 // if ((position == AbsolutePosition || position == FixedPosition)) { 300 current_child_ = current_child_->NextSibling();
300 // builder_->AddOutOfFlowCandidateChild(current_child_, 301 return kNotFinished;
301 // GetChildSpaceOffset()); 302 }
302 // }
303 // else
304 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); 303 space_for_current_child_ = CreateConstraintSpaceForCurrentChild();
305 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( 304 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode(
306 current_child_, space_for_current_child_); 305 current_child_, space_for_current_child_);
307 layout_state_ = kStateChildLayout; 306 layout_state_ = kStateChildLayout;
308 return kChildAlgorithmRequired; 307 return kChildAlgorithmRequired;
309 } 308 }
310 309
311 layout_state_ = kStateFinalize; 310 // Prepare for kStateOutOfFlowLayout
311 content_size_ += border_and_padding_.block_end;
312
313 // Recompute the block-axis size now that we know our content size.
314 LayoutUnit block_size = ComputeBlockSizeForFragment(
315 ConstraintSpace(), Style(), content_size_);
316 builder_->SetBlockSize(block_size);
317
318 // Out of flow setup.
319 out_of_flow_layout_ = new NGOutOfFlowLayoutPart(style_, builder_->Size());
320 builder_->GetAndClearOutOfFlowDescendantCandidates(
321 &out_of_flow_candidates_, &out_of_flow_candidate_positions_);
322 out_of_flow_candidate_positions_index_ = 0;
323 current_child_ = nullptr;
324 layout_state_ = kStateOutOfFlowLayout;
312 return kNotFinished; 325 return kNotFinished;
313 } 326 }
314 case kStateChildLayout: { 327 case kStateChildLayout: {
315 DCHECK(current_child_); 328 DCHECK(current_child_);
316 DCHECK(child_fragment); 329 DCHECK(child_fragment);
317 330
318 // TODO(layout_ng): Seems like a giant hack to call this here. 331 // TODO(layout_ng): Seems like a giant hack to call this here.
319 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), 332 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment),
320 space_for_current_child_); 333 space_for_current_child_);
321 334
322 FinishCurrentChildLayout(new NGFragment( 335 FinishCurrentChildLayout(new NGFragment(
323 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), 336 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(),
324 toNGPhysicalFragment(child_fragment))); 337 toNGPhysicalFragment(child_fragment)));
325 current_child_ = current_child_->NextSibling(); 338 current_child_ = current_child_->NextSibling();
326 layout_state_ = kStatePrepareForChildLayout; 339 layout_state_ = kStatePrepareForChildLayout;
327 return kNotFinished; 340 return kNotFinished;
328 } 341 }
342 case kStateOutOfFlowLayout:
343 if (LayoutOutOfFlowChild())
344 layout_state_ = kStateFinalize;
345 return kNotFinished;
329 case kStateFinalize: { 346 case kStateFinalize: {
330 content_size_ += border_and_padding_.block_end; 347 builder_->SetInlineOverflow(max_inline_size_)
331
332 // Recompute the block-axis size now that we know our content size.
333 LayoutUnit block_size = ComputeBlockSizeForFragment(
334 ConstraintSpace(), Style(), content_size_);
335
336 builder_->SetBlockSize(block_size)
337 .SetInlineOverflow(max_inline_size_)
338 .SetBlockOverflow(content_size_); 348 .SetBlockOverflow(content_size_);
339 *fragment_out = builder_->ToFragment(); 349 *fragment_out = builder_->ToFragment();
340 layout_state_ = kStateInit; 350 layout_state_ = kStateInit;
341 return kNewFragment; 351 return kNewFragment;
342 } 352 }
343 }; 353 };
344 NOTREACHED(); 354 NOTREACHED();
345 *fragment_out = nullptr; 355 *fragment_out = nullptr;
346 return kNewFragment; 356 return kNewFragment;
347 } 357 }
348 358
349 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( 359 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout(
350 NGFragmentBase* fragment) { 360 NGFragmentBase* fragment) {
351 NGBoxStrut child_margins = ComputeMargins( 361 NGBoxStrut child_margins = ComputeMargins(
352 *space_for_current_child_, CurrentChildStyle(), 362 *space_for_current_child_, CurrentChildStyle(),
353 constraint_space_->WritingMode(), constraint_space_->Direction()); 363 constraint_space_->WritingMode(), constraint_space_->Direction());
354 364
355 NGLogicalOffset fragment_offset; 365 NGLogicalOffset fragment_offset;
356 if (CurrentChildStyle().isFloating()) { 366 if (CurrentChildStyle().isFloating()) {
357 fragment_offset = PositionFloatFragment(*fragment, child_margins); 367 fragment_offset = PositionFloatFragment(*fragment, child_margins);
358 } else { 368 } else {
359 ApplyAutoMargins(*space_for_current_child_, CurrentChildStyle(), *fragment, 369 ApplyAutoMargins(*space_for_current_child_, CurrentChildStyle(), *fragment,
360 &child_margins); 370 &child_margins);
361 fragment_offset = PositionFragment(*fragment, child_margins); 371 fragment_offset = PositionFragment(*fragment, child_margins);
362 } 372 }
363 builder_->AddChild(fragment, fragment_offset); 373 builder_->AddChild(fragment, fragment_offset);
364 } 374 }
365 375
376 bool NGBlockLayoutAlgorithm::LayoutOutOfFlowChild() {
377 if (!current_child_) {
378 if (out_of_flow_candidates_.isEmpty()) {
379 out_of_flow_layout_ = nullptr;
380 out_of_flow_candidate_positions_.clear();
381 return true;
382 }
383 current_child_ = out_of_flow_candidates_.first();
384 out_of_flow_candidates_.removeFirst();
385 NGStaticPosition position = out_of_flow_candidate_positions_
386 [out_of_flow_candidate_positions_index_++];
387
388 if (!out_of_flow_layout_->StartLayout(current_child_, position)) {
389 builder_->AddOutOfFlowDescendant(current_child_, position);
390 current_child_ = nullptr;
391 return false;
392 }
393 }
394 NGFragmentBase* fragment;
395 NGLogicalOffset offset;
396 if (out_of_flow_layout_->Layout(&fragment, &offset) == kNewFragment) {
397 // TODO(atotic) Need to adjust size of overflow rect per spec.
398 builder_->AddChild(fragment, offset);
399 current_child_ = nullptr;
400 }
401 return false;
402 }
403
366 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins( 404 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
367 const NGBoxStrut& margins, 405 const NGBoxStrut& margins,
368 const NGFragment& fragment) { 406 const NGFragment& fragment) {
369 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() && 407 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() &&
370 fragment.MarginStrut().IsEmpty(); 408 fragment.MarginStrut().IsEmpty();
371 // Create the current child's margin strut from its children's margin strut or 409 // Create the current child's margin strut from its children's margin strut or
372 // use margin strut from the the last non-empty child. 410 // use margin strut from the the last non-empty child.
373 NGMarginStrut curr_margin_strut = 411 NGMarginStrut curr_margin_strut =
374 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut(); 412 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut();
375 413
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 DEFINE_TRACE(NGBlockLayoutAlgorithm) { 554 DEFINE_TRACE(NGBlockLayoutAlgorithm) {
517 NGLayoutAlgorithm::trace(visitor); 555 NGLayoutAlgorithm::trace(visitor);
518 visitor->trace(first_child_); 556 visitor->trace(first_child_);
519 visitor->trace(constraint_space_); 557 visitor->trace(constraint_space_);
520 visitor->trace(break_token_); 558 visitor->trace(break_token_);
521 visitor->trace(builder_); 559 visitor->trace(builder_);
522 visitor->trace(space_builder_); 560 visitor->trace(space_builder_);
523 visitor->trace(space_for_current_child_); 561 visitor->trace(space_for_current_child_);
524 visitor->trace(current_child_); 562 visitor->trace(current_child_);
525 visitor->trace(current_minmax_child_); 563 visitor->trace(current_minmax_child_);
564 visitor->trace(out_of_flow_layout_);
565 visitor->trace(out_of_flow_candidates_);
526 } 566 }
527 567
528 } // namespace blink 568 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698