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/inline/ng_inline_layout_algorithm.h" | 5 #include "core/layout/ng/inline/ng_inline_layout_algorithm.h" |
6 | 6 |
7 #include "core/layout/ng/inline/ng_baseline.h" | 7 #include "core/layout/ng/inline/ng_baseline.h" |
8 #include "core/layout/ng/inline/ng_bidi_paragraph.h" | 8 #include "core/layout/ng/inline/ng_bidi_paragraph.h" |
9 #include "core/layout/ng/inline/ng_inline_break_token.h" | 9 #include "core/layout/ng/inline/ng_inline_break_token.h" |
10 #include "core/layout/ng/inline/ng_inline_node.h" | 10 #include "core/layout/ng/inline/ng_inline_node.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm( | 52 NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm( |
53 NGInlineNode inline_node, | 53 NGInlineNode inline_node, |
54 NGConstraintSpace* space, | 54 NGConstraintSpace* space, |
55 NGInlineBreakToken* break_token) | 55 NGInlineBreakToken* break_token) |
56 : NGLayoutAlgorithm(inline_node, space, break_token), | 56 : NGLayoutAlgorithm(inline_node, space, break_token), |
57 is_horizontal_writing_mode_( | 57 is_horizontal_writing_mode_( |
58 blink::IsHorizontalWritingMode(space->WritingMode())), | 58 blink::IsHorizontalWritingMode(space->WritingMode())), |
59 space_builder_(space) { | 59 space_builder_(space) { |
60 container_builder_.MutableUnpositionedFloats() = space->UnpositionedFloats(); | 60 unpositioned_floats_ = ConstraintSpace().UnpositionedFloats(); |
61 | 61 |
62 if (!is_horizontal_writing_mode_) | 62 if (!is_horizontal_writing_mode_) |
63 baseline_type_ = FontBaseline::kIdeographicBaseline; | 63 baseline_type_ = FontBaseline::kIdeographicBaseline; |
64 } | 64 } |
65 | 65 |
66 bool NGInlineLayoutAlgorithm::CreateLine( | 66 bool NGInlineLayoutAlgorithm::CreateLine( |
67 NGLineInfo* line_info, | 67 NGLineInfo* line_info, |
68 RefPtr<NGInlineBreakToken> break_token) { | 68 RefPtr<NGInlineBreakToken> break_token) { |
69 if (Node().IsBidiEnabled()) | 69 if (Node().IsBidiEnabled()) |
70 BidiReorder(&line_info->Results()); | 70 BidiReorder(&line_info->Results()); |
71 | 71 |
72 if (!PlaceItems(line_info, break_token)) | 72 if (!PlaceItems(line_info, break_token)) |
73 return false; | 73 return false; |
74 | 74 |
75 // If something has resolved our BFC offset we can place all of the | 75 // If something has resolved our BFC offset we can place all of the |
76 // unpositioned floats below the current line. | 76 // unpositioned floats below the current line. |
77 if (container_builder_.BfcOffset()) { | 77 if (container_builder_.BfcOffset()) { |
78 NGLogicalOffset origin_point = | 78 NGLogicalOffset origin_point = |
79 GetOriginPointForFloats(ContainerBfcOffset(), content_size_); | 79 GetOriginPointForFloats(ContainerBfcOffset(), content_size_); |
80 PositionPendingFloats(origin_point.block_offset, &container_builder_, | 80 PositionPendingFloats(origin_point.block_offset, &container_builder_, |
81 MutableConstraintSpace()); | 81 &unpositioned_floats_, MutableConstraintSpace()); |
82 } | 82 } |
83 | 83 |
84 return true; | 84 return true; |
85 } | 85 } |
86 | 86 |
87 void NGInlineLayoutAlgorithm::BidiReorder(NGInlineItemResults* line_items) { | 87 void NGInlineLayoutAlgorithm::BidiReorder(NGInlineItemResults* line_items) { |
88 // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change | 88 // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change |
89 // embedding levels of parts of runs, which requires to split items. | 89 // embedding levels of parts of runs, which requires to split items. |
90 // http://unicode.org/reports/tr9/#L1 | 90 // http://unicode.org/reports/tr9/#L1 |
91 // BidiResolver does not support L1 crbug.com/316409. | 91 // BidiResolver does not support L1 crbug.com/316409. |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 } | 440 } |
441 } | 441 } |
442 } | 442 } |
443 | 443 |
444 RefPtr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() { | 444 RefPtr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() { |
445 // Line boxes should start at (0,0). | 445 // Line boxes should start at (0,0). |
446 // The parent NGBlockLayoutAlgorithm places the anonymous wrapper using the | 446 // The parent NGBlockLayoutAlgorithm places the anonymous wrapper using the |
447 // border and padding of the container block. | 447 // border and padding of the container block. |
448 content_size_ = LayoutUnit(); | 448 content_size_ = LayoutUnit(); |
449 | 449 |
450 // Check if we can resolve the BFC offset. | 450 // We can resolve our BFC offset if we aren't an empty inline. |
451 if (!Node().IsEmptyInline()) { | 451 if (!Node().IsEmptyInline()) { |
452 DCHECK(!container_builder_.BfcOffset()); | 452 DCHECK(!container_builder_.BfcOffset()); |
453 LayoutUnit bfc_block_offset = constraint_space_->BfcOffset().block_offset + | 453 LayoutUnit bfc_block_offset = constraint_space_->BfcOffset().block_offset + |
454 constraint_space_->MarginStrut().Sum(); | 454 constraint_space_->MarginStrut().Sum(); |
455 MaybeUpdateFragmentBfcOffset(*constraint_space_, bfc_block_offset, | 455 MaybeUpdateFragmentBfcOffset(*constraint_space_, bfc_block_offset, |
456 &container_builder_); | 456 &container_builder_); |
457 PositionPendingFloats(bfc_block_offset, &container_builder_, | 457 |
458 constraint_space_); | 458 // If we have unpositioned floats from a previous sibling, we need to abort |
| 459 // our layout, and tell our parent that we now know our BFC offset. |
| 460 if (!unpositioned_floats_.IsEmpty()) { |
| 461 // TODO(ikilpatrick): This should be swapping in its unpositioned floats |
| 462 // before aborting, but as because NGLayoutInputNode::IsInline isn't |
| 463 // stable, we can't do this yet. |
| 464 // container_builder_.SwapUnpositionedFloats(&unpositioned_floats_); |
| 465 return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved); |
| 466 } |
459 } | 467 } |
460 | 468 |
461 NGLineBreaker line_breaker(Node(), constraint_space_, &container_builder_, | 469 NGLineBreaker line_breaker(Node(), constraint_space_, &container_builder_, |
462 BreakToken()); | 470 &unpositioned_floats_, BreakToken()); |
463 NGLineInfo line_info; | 471 NGLineInfo line_info; |
464 while (line_breaker.NextLine(&line_info, {LayoutUnit(), content_size_})) | 472 while (line_breaker.NextLine(&line_info, {LayoutUnit(), content_size_})) |
465 CreateLine(&line_info, line_breaker.CreateBreakToken()); | 473 CreateLine(&line_info, line_breaker.CreateBreakToken()); |
466 | 474 |
| 475 // Place any remaining floats which couldn't fit on the previous line. |
| 476 // TODO(ikilpatrick): This is duplicated from CreateLine, but flushes any |
| 477 // floats if we didn't create a line-box. Refactor this such that this isn't |
| 478 // needed. |
| 479 if (container_builder_.BfcOffset()) { |
| 480 NGLogicalOffset origin_point = |
| 481 GetOriginPointForFloats(ContainerBfcOffset(), content_size_); |
| 482 PositionPendingFloats(origin_point.block_offset, &container_builder_, |
| 483 &unpositioned_floats_, MutableConstraintSpace()); |
| 484 } |
| 485 |
467 // TODO(kojii): Check if the line box width should be content or available. | 486 // TODO(kojii): Check if the line box width should be content or available. |
468 NGLogicalSize size(max_inline_size_, content_size_); | 487 NGLogicalSize size(max_inline_size_, content_size_); |
469 container_builder_.SetSize(size).SetOverflowSize(size); | 488 container_builder_.SetSize(size).SetOverflowSize(size); |
470 | 489 |
471 // TODO(crbug.com/716930): We may be an empty LayoutInline due to splitting. | 490 // TODO(crbug.com/716930): We may be an empty LayoutInline due to splitting. |
472 // Margin struts shouldn't need to be passed through like this once we've | 491 // Margin struts shouldn't need to be passed through like this once we've |
473 // removed LayoutInline splitting. | 492 // removed LayoutInline splitting. |
474 if (!container_builder_.BfcOffset()) { | 493 if (!container_builder_.BfcOffset()) { |
475 container_builder_.SetEndMarginStrut(ConstraintSpace().MarginStrut()); | 494 container_builder_.SetEndMarginStrut(ConstraintSpace().MarginStrut()); |
476 } | 495 } |
477 | 496 |
| 497 // If we've got any unpositioned floats here, we must be an empty inline |
| 498 // without a BFC offset. We need to pass our unpositioned floats to our next |
| 499 // sibling. |
| 500 if (!unpositioned_floats_.IsEmpty()) { |
| 501 DCHECK(Node().IsEmptyInline()); |
| 502 DCHECK(!container_builder_.BfcOffset()); |
| 503 container_builder_.SwapUnpositionedFloats(&unpositioned_floats_); |
| 504 } |
| 505 |
478 PropagateBaselinesFromChildren(); | 506 PropagateBaselinesFromChildren(); |
479 | 507 |
480 return container_builder_.ToBoxFragment(); | 508 return container_builder_.ToBoxFragment(); |
481 } | 509 } |
482 | 510 |
483 } // namespace blink | 511 } // namespace blink |
OLD | NEW |