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_bidi_paragraph.h" | 7 #include "core/layout/ng/inline/ng_bidi_paragraph.h" |
8 #include "core/layout/ng/inline/ng_inline_break_token.h" | 8 #include "core/layout/ng/inline/ng_inline_break_token.h" |
9 #include "core/layout/ng/inline/ng_inline_node.h" | 9 #include "core/layout/ng/inline/ng_inline_node.h" |
10 #include "core/layout/ng/inline/ng_line_box_fragment.h" | 10 #include "core/layout/ng/inline/ng_line_box_fragment.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 } // namespace | 49 } // namespace |
50 | 50 |
51 NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm( | 51 NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm( |
52 NGInlineNode inline_node, | 52 NGInlineNode inline_node, |
53 NGConstraintSpace* space, | 53 NGConstraintSpace* space, |
54 NGInlineBreakToken* break_token) | 54 NGInlineBreakToken* break_token) |
55 : NGLayoutAlgorithm(inline_node, space, break_token), | 55 : NGLayoutAlgorithm(inline_node, space, break_token), |
56 is_horizontal_writing_mode_( | 56 is_horizontal_writing_mode_( |
57 blink::IsHorizontalWritingMode(space->WritingMode())), | 57 blink::IsHorizontalWritingMode(space->WritingMode())), |
58 space_builder_(space) { | 58 space_builder_(space) { |
59 container_builder_.MutableUnpositionedFloats() = space->UnpositionedFloats(); | 59 unpositioned_floats_ = ConstraintSpace().UnpositionedFloats(); |
60 | 60 |
61 if (!is_horizontal_writing_mode_) | 61 if (!is_horizontal_writing_mode_) |
62 baseline_type_ = FontBaseline::kIdeographicBaseline; | 62 baseline_type_ = FontBaseline::kIdeographicBaseline; |
63 } | 63 } |
64 | 64 |
65 bool NGInlineLayoutAlgorithm::CreateLine( | 65 bool NGInlineLayoutAlgorithm::CreateLine( |
66 NGLineInfo* line_info, | 66 NGLineInfo* line_info, |
67 RefPtr<NGInlineBreakToken> break_token) { | 67 RefPtr<NGInlineBreakToken> break_token) { |
68 if (Node().IsBidiEnabled()) | 68 if (Node().IsBidiEnabled()) |
69 BidiReorder(&line_info->Results()); | 69 BidiReorder(&line_info->Results()); |
70 | 70 |
71 if (!PlaceItems(line_info, break_token)) | 71 if (!PlaceItems(line_info, break_token)) |
72 return false; | 72 return false; |
73 | 73 |
74 // If something has resolved our BFC offset we can place all of the | 74 // If something has resolved our BFC offset we can place all of the |
75 // unpositioned floats below the current line. | 75 // unpositioned floats below the current line. |
76 if (container_builder_.BfcOffset()) { | 76 if (container_builder_.BfcOffset()) { |
77 NGLogicalOffset origin_point = | 77 NGLogicalOffset origin_point = |
78 GetOriginPointForFloats(ContainerBfcOffset(), content_size_); | 78 GetOriginPointForFloats(ContainerBfcOffset(), content_size_); |
79 PositionPendingFloats(origin_point.block_offset, &container_builder_, | 79 PositionPendingFloats(origin_point.block_offset, &container_builder_, |
80 MutableConstraintSpace()); | 80 &unpositioned_floats_, MutableConstraintSpace()); |
81 } | 81 } |
82 | 82 |
83 return true; | 83 return true; |
84 } | 84 } |
85 | 85 |
86 void NGInlineLayoutAlgorithm::BidiReorder(NGInlineItemResults* line_items) { | 86 void NGInlineLayoutAlgorithm::BidiReorder(NGInlineItemResults* line_items) { |
87 // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change | 87 // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change |
88 // embedding levels of parts of runs, which requires to split items. | 88 // embedding levels of parts of runs, which requires to split items. |
89 // http://unicode.org/reports/tr9/#L1 | 89 // http://unicode.org/reports/tr9/#L1 |
90 // BidiResolver does not support L1 crbug.com/316409. | 90 // BidiResolver does not support L1 crbug.com/316409. |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
405 | 405 |
406 return content_size; | 406 return content_size; |
407 } | 407 } |
408 | 408 |
409 RefPtr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() { | 409 RefPtr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() { |
410 // Line boxes should start at (0,0). | 410 // Line boxes should start at (0,0). |
411 // The parent NGBlockLayoutAlgorithm places the anonymous wrapper using the | 411 // The parent NGBlockLayoutAlgorithm places the anonymous wrapper using the |
412 // border and padding of the container block. | 412 // border and padding of the container block. |
413 content_size_ = LayoutUnit(); | 413 content_size_ = LayoutUnit(); |
414 | 414 |
415 // Check if we can resolve the BFC offset. | 415 // We can resolve our BFC offset if we aren't an empty inline. |
416 if (!Node().IsEmptyInline()) { | 416 if (!Node().IsEmptyInline()) { |
417 DCHECK(!container_builder_.BfcOffset()); | 417 DCHECK(!container_builder_.BfcOffset()); |
418 LayoutUnit bfc_block_offset = constraint_space_->BfcOffset().block_offset + | 418 LayoutUnit bfc_block_offset = constraint_space_->BfcOffset().block_offset + |
419 constraint_space_->MarginStrut().Sum(); | 419 constraint_space_->MarginStrut().Sum(); |
420 MaybeUpdateFragmentBfcOffset(*constraint_space_, bfc_block_offset, | 420 MaybeUpdateFragmentBfcOffset(*constraint_space_, bfc_block_offset, |
421 &container_builder_); | 421 &container_builder_); |
422 PositionPendingFloats(bfc_block_offset, &container_builder_, | 422 |
423 constraint_space_); | 423 // If we have unpositioned floats from a previous sibling, we need to abort |
424 // our layout, and tell our parent that we now know our BFC offset. | |
425 if (!unpositioned_floats_.IsEmpty()) { | |
426 // TODO(ikilpatrick): This should be swapping in its unpositioned floats | |
427 // before aborting, but as because NGLayoutInputNode::IsInline isn't | |
428 // stable, we can't do this yet. | |
429 // container_builder_.SwapUnpositionedFloats(&unpositioned_floats_); | |
430 return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved); | |
431 } | |
424 } | 432 } |
425 | 433 |
426 NGLineBreaker line_breaker(Node(), constraint_space_, &container_builder_, | 434 NGLineBreaker line_breaker(Node(), constraint_space_, &container_builder_, |
427 BreakToken()); | 435 &unpositioned_floats_, BreakToken()); |
428 NGLineInfo line_info; | 436 NGLineInfo line_info; |
429 while (line_breaker.NextLine(&line_info, {LayoutUnit(), content_size_})) | 437 while (line_breaker.NextLine(&line_info, {LayoutUnit(), content_size_})) |
430 CreateLine(&line_info, line_breaker.CreateBreakToken()); | 438 CreateLine(&line_info, line_breaker.CreateBreakToken()); |
431 | 439 |
440 // Place any remaining floats which couldn't fit on the previous line. | |
441 // TODO(ikilpatrick): This is duplicated from CreateLine, but flushes any | |
442 // floats if we didn't create a line-box. Refactor this such that this isn't | |
443 // needed. | |
444 if (container_builder_.BfcOffset()) { | |
445 NGLogicalOffset origin_point = | |
446 GetOriginPointForFloats(ContainerBfcOffset(), content_size_); | |
447 PositionPendingFloats(origin_point.block_offset, &container_builder_, | |
448 &unpositioned_floats_, MutableConstraintSpace()); | |
449 } | |
450 | |
432 // TODO(kojii): Check if the line box width should be content or available. | 451 // TODO(kojii): Check if the line box width should be content or available. |
433 NGLogicalSize size(max_inline_size_, content_size_); | 452 NGLogicalSize size(max_inline_size_, content_size_); |
434 container_builder_.SetSize(size).SetOverflowSize(size); | 453 container_builder_.SetSize(size).SetOverflowSize(size); |
435 | 454 |
436 // TODO(crbug.com/716930): We may be an empty LayoutInline due to splitting. | 455 // TODO(crbug.com/716930): We may be an empty LayoutInline due to splitting. |
437 // Margin struts shouldn't need to be passed through like this once we've | 456 // Margin struts shouldn't need to be passed through like this once we've |
438 // removed LayoutInline splitting. | 457 // removed LayoutInline splitting. |
439 if (!container_builder_.BfcOffset()) { | 458 if (!container_builder_.BfcOffset()) { |
440 container_builder_.SetEndMarginStrut(ConstraintSpace().MarginStrut()); | 459 container_builder_.SetEndMarginStrut(ConstraintSpace().MarginStrut()); |
441 } | 460 } |
442 | 461 |
462 // If we've got any unpositioned floats here, we must be an empty inline | |
463 // without a BFC offset. We need to pass our unpositioned floats to our next | |
464 // sibling. | |
465 if (!unpositioned_floats_.IsEmpty()) { | |
466 DCHECK(Node().IsEmptyInline()); | |
467 DCHECK(!container_builder_.BfcOffset()); | |
468 container_builder_.SwapUnpositionedFloats(&unpositioned_floats_); | |
eae
2017/07/10 23:27:49
This is really neat.
ikilpatrick
2017/07/11 17:20:41
Acknowledged.
| |
469 } | |
470 | |
443 return container_builder_.ToBoxFragment(); | 471 return container_builder_.ToBoxFragment(); |
444 } | 472 } |
445 | 473 |
446 } // namespace blink | 474 } // namespace blink |
OLD | NEW |