Chromium Code Reviews| 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_out_of_flow_layout_part.h" | 5 #include "core/layout/ng/ng_out_of_flow_layout_part.h" |
| 6 | 6 |
| 7 #include "core/layout/ng/ng_absolute_utils.h" | 7 #include "core/layout/ng/ng_absolute_utils.h" |
| 8 #include "core/layout/ng/ng_block_node.h" | 8 #include "core/layout/ng/ng_block_node.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.h" | 10 #include "core/layout/ng/ng_fragment.h" |
| 11 #include "core/layout/ng/ng_length_utils.h" | 11 #include "core/layout/ng/ng_length_utils.h" |
| 12 #include "core/layout/ng/ng_physical_fragment.h" | 12 #include "core/layout/ng/ng_physical_fragment.h" |
| 13 #include "core/style/ComputedStyle.h" | 13 #include "core/style/ComputedStyle.h" |
| 14 | 14 |
| 15 namespace blink { | 15 namespace blink { |
| 16 | 16 |
| 17 NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart( | 17 NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart( |
| 18 PassRefPtr<const ComputedStyle> container_style, | 18 PassRefPtr<const ComputedStyle> container_style, |
| 19 NGLogicalSize container_size) { | 19 NGLogicalSize container_size) { |
| 20 contains_fixed_ = container_style->canContainFixedPositionObjects(); | 20 NGWritingMode writing_mode( |
| 21 contains_absolute_ = | 21 FromPlatformWritingMode(container_style->getWritingMode())); |
| 22 container_style->canContainAbsolutePositionObjects() || contains_fixed_; | 22 |
| 23 // Initialize ConstraintSpace | 23 NGBoxStrut borders = ComputeBorders(*container_style); |
| 24 parent_border_offset_ = | |
| 25 NGLogicalOffset{borders.inline_start, borders.block_start}; | |
| 26 parent_border_physical_offset_ = parent_border_offset_.ConvertToPhysical( | |
| 27 writing_mode, container_style->direction(), | |
| 28 container_size.ConvertToPhysical(writing_mode), NGPhysicalSize()); | |
| 29 | |
| 24 NGLogicalSize space_size = container_size; | 30 NGLogicalSize space_size = container_size; |
| 25 NGBoxStrut borders = ComputeBorders(*container_style); | |
| 26 space_size.block_size -= borders.BlockSum(); | 31 space_size.block_size -= borders.BlockSum(); |
| 27 space_size.inline_size -= borders.InlineSum(); | 32 space_size.inline_size -= borders.InlineSum(); |
| 28 parent_offset_ = NGLogicalOffset{borders.inline_start, borders.block_start}; | 33 |
| 29 parent_physical_offset_ = parent_offset_.ConvertToPhysical( | 34 // Initialize ConstraintSpace |
| 30 FromPlatformWritingMode(container_style->getWritingMode()), | 35 NGConstraintSpaceBuilder space_builder(writing_mode); |
| 31 container_style->direction(), | |
| 32 container_size.ConvertToPhysical( | |
| 33 FromPlatformWritingMode(container_style->getWritingMode())), | |
| 34 NGPhysicalSize()); | |
| 35 NGConstraintSpaceBuilder space_builder( | |
| 36 FromPlatformWritingMode(container_style->getWritingMode())); | |
| 37 space_builder.SetAvailableSize(space_size); | 36 space_builder.SetAvailableSize(space_size); |
| 38 space_builder.SetPercentageResolutionSize(space_size); | 37 space_builder.SetPercentageResolutionSize(space_size); |
|
atotic
2017/01/18 18:48:49
SetIsNewFormattingContext() has been removed. Why?
ikilpatrick
2017/01/18 19:32:13
Yeah NewFormattingContext means basically this:
ht
| |
| 39 space_builder.SetIsNewFormattingContext(true); | |
| 40 space_builder.SetTextDirection(container_style->direction()); | 38 space_builder.SetTextDirection(container_style->direction()); |
| 41 parent_space_ = space_builder.ToConstraintSpace(); | 39 parent_space_ = space_builder.ToConstraintSpace(); |
| 42 } | 40 } |
| 43 | 41 |
| 44 bool NGOutOfFlowLayoutPart::StartLayout( | 42 void NGOutOfFlowLayoutPart::Layout(NGBlockNode& node, |
| 45 NGBlockNode* node, | 43 NGStaticPosition static_position, |
| 46 const NGStaticPosition& static_position) { | 44 NGFragment** fragment_out, |
| 47 EPosition position = node->Style()->position(); | 45 NGLogicalOffset* offset) { |
| 48 if ((contains_absolute_ && position == AbsolutePosition) || | 46 // Adjust the static_position origin. The static_position coordinate origin is |
| 49 (contains_fixed_ && position == FixedPosition)) { | 47 // relative to the parent's border box, ng_absolute_utils expects it to be |
| 50 node_ = node; | 48 // relative to the parent's padding box. |
| 51 static_position_ = static_position; | 49 static_position.offset -= parent_border_physical_offset_; |
| 52 // Adjust static_position origin. static_position coordinate origin is | 50 |
| 53 // border_box, absolute position coordinate origin is padding box. | 51 NGFragment* fragment = nullptr; |
| 54 static_position_.offset -= parent_physical_offset_; | 52 Optional<MinAndMaxContentSizes> inline_estimate; |
| 55 node_fragment_ = nullptr; | 53 Optional<LayoutUnit> block_estimate; |
| 56 node_position_ = NGAbsolutePhysicalPosition(); | 54 |
| 57 inline_estimate_.reset(); | 55 if (AbsoluteNeedsChildInlineSize(*node.Style())) { |
| 58 block_estimate_.reset(); | 56 inline_estimate = node.ComputeMinAndMaxContentSizesSync(); |
| 59 state_ = kComputeInlineEstimate; | |
| 60 return true; | |
| 61 } | 57 } |
| 62 return false; | 58 |
| 59 NGAbsolutePhysicalPosition node_position = | |
| 60 ComputePartialAbsoluteWithChildInlineSize( | |
| 61 *parent_space_, *node.Style(), static_position, inline_estimate); | |
| 62 | |
| 63 if (AbsoluteNeedsChildBlockSize(*node.Style())) { | |
| 64 fragment = GenerateFragment(node, block_estimate, node_position); | |
| 65 block_estimate = fragment->BlockSize(); | |
| 66 } | |
| 67 | |
| 68 ComputeFullAbsoluteWithChildBlockSize(*parent_space_, *node.Style(), | |
| 69 static_position, block_estimate, | |
| 70 &node_position); | |
| 71 | |
| 72 // Skip this step if we produced a fragment when estimating the block size. | |
| 73 if (!fragment) { | |
| 74 block_estimate = | |
| 75 node_position.size.ConvertToLogical(parent_space_->WritingMode()) | |
| 76 .block_size; | |
| 77 fragment = GenerateFragment(node, block_estimate, node_position); | |
| 78 } | |
| 79 | |
| 80 *fragment_out = fragment; | |
| 81 | |
| 82 // Compute logical offset, NGAbsolutePhysicalPosition is calculated relative | |
| 83 // to the padding box so add back the parent's borders. | |
| 84 NGBoxStrut inset = node_position.inset.ConvertToLogical( | |
| 85 parent_space_->WritingMode(), parent_space_->Direction()); | |
| 86 offset->inline_offset = | |
| 87 inset.inline_start + parent_border_offset_.inline_offset; | |
| 88 offset->block_offset = inset.block_start + parent_border_offset_.block_offset; | |
| 63 } | 89 } |
| 64 | 90 |
| 65 NGLayoutStatus NGOutOfFlowLayoutPart::Layout(NGFragment** fragment, | 91 NGFragment* NGOutOfFlowLayoutPart::GenerateFragment( |
| 66 NGLogicalOffset* offset) { | 92 NGBlockNode& node, |
| 67 DCHECK(node_); | 93 const Optional<LayoutUnit>& block_estimate, |
| 68 switch (state_) { | 94 const NGAbsolutePhysicalPosition node_position) { |
| 69 case kComputeInlineEstimate: | 95 // The fragment is generated in one of these two scenarios: |
| 70 if (ComputeInlineSizeEstimate()) | 96 // 1. To estimate child's block size, in this case block_size is parent's |
| 71 state_ = kPartialPosition; | 97 // available size. |
| 72 break; | 98 // 2. To compute final fragment, when block size is known from the absolute |
| 73 case kPartialPosition: | 99 // position calculation. |
| 74 node_position_ = ComputePartialAbsoluteWithChildInlineSize( | 100 LayoutUnit inline_size = |
| 75 *parent_space_, *node_->Style(), static_position_, inline_estimate_); | 101 node_position.size.ConvertToLogical(parent_space_->WritingMode()) |
| 76 state_ = kComputeBlockEstimate; | 102 .inline_size; |
| 77 break; | 103 LayoutUnit block_size = block_estimate |
| 78 case kComputeBlockEstimate: | 104 ? *block_estimate |
| 79 if (ComputeBlockSizeEstimate()) | 105 : parent_space_->AvailableSize().block_size; |
| 80 state_ = kFullPosition; | |
| 81 break; | |
| 82 case kFullPosition: | |
| 83 ComputeFullAbsoluteWithChildBlockSize(*parent_space_, *node_->Style(), | |
| 84 static_position_, block_estimate_, | |
| 85 &node_position_); | |
| 86 state_ = kGenerateFragment; | |
| 87 break; | |
| 88 case kGenerateFragment: | |
| 89 block_estimate_ = | |
| 90 node_position_.size.ConvertToLogical(parent_space_->WritingMode()) | |
| 91 .block_size; | |
| 92 if (!ComputeNodeFragment()) | |
| 93 return kNotFinished; | |
| 94 state_ = kDone; | |
| 95 break; | |
| 96 case kDone: | |
| 97 *fragment = node_fragment_; | |
| 98 // Compute offset | |
| 99 NGBoxStrut inset = node_position_.inset.ConvertToLogical( | |
| 100 parent_space_->WritingMode(), parent_space_->Direction()); | |
| 101 offset->inline_offset = inset.inline_start + parent_offset_.inline_offset; | |
| 102 offset->block_offset = inset.block_start + parent_offset_.block_offset; | |
| 103 return kNewFragment; | |
| 104 } | |
| 105 return kNotFinished; | |
| 106 } | |
| 107 | 106 |
| 108 bool NGOutOfFlowLayoutPart::ComputeInlineSizeEstimate() { | 107 NGLogicalSize available_size{inline_size, block_size}; |
| 109 if (AbsoluteNeedsChildInlineSize(*node_->Style())) { | |
| 110 MinAndMaxContentSizes size; | |
| 111 if (node_->ComputeMinAndMaxContentSizes(&size)) { | |
| 112 inline_estimate_ = size; | |
| 113 return true; | |
| 114 } | |
| 115 return false; | |
| 116 } | |
| 117 return true; | |
| 118 } | |
| 119 | 108 |
| 120 bool NGOutOfFlowLayoutPart::ComputeBlockSizeEstimate() { | 109 NGConstraintSpaceBuilder builder(parent_space_->WritingMode()); |
| 121 if (AbsoluteNeedsChildBlockSize(*node_->Style())) { | 110 builder.SetAvailableSize(available_size); |
| 122 if (ComputeNodeFragment()) { | 111 builder.SetPercentageResolutionSize(parent_space_->AvailableSize()); |
| 123 block_estimate_ = node_fragment_->BlockSize(); | 112 if (block_estimate) |
| 124 return true; | 113 builder.SetIsFixedSizeBlock(true); |
| 125 } | 114 builder.SetIsFixedSizeInline(true); |
| 126 return false; | 115 builder.SetIsNewFormattingContext(true); |
| 127 } | 116 NGConstraintSpace* space = builder.ToConstraintSpace(); |
| 128 return true; | |
| 129 } | |
| 130 | 117 |
| 131 bool NGOutOfFlowLayoutPart::ComputeNodeFragment() { | |
| 132 if (node_fragment_) | |
| 133 return true; | |
| 134 if (!node_space_) { | |
| 135 NGConstraintSpaceBuilder builder(parent_space_->WritingMode()); | |
| 136 LayoutUnit inline_width = | |
| 137 node_position_.size.ConvertToLogical(parent_space_->WritingMode()) | |
| 138 .inline_size; | |
| 139 // Node fragment is computed in one of these two scenarios: | |
| 140 // 1. To estimate block size | |
| 141 // In this case, available block_size is parent's size. | |
| 142 // 2. To compute final block fragment, when block size is known. | |
| 143 | |
| 144 NGLogicalSize available_size = | |
| 145 NGLogicalSize(inline_width, parent_space_->AvailableSize().block_size); | |
| 146 if (block_estimate_) | |
| 147 available_size.block_size = *block_estimate_; | |
| 148 builder.SetAvailableSize(available_size); | |
| 149 builder.SetPercentageResolutionSize(parent_space_->AvailableSize()); | |
| 150 if (block_estimate_) | |
| 151 builder.SetIsFixedSizeBlock(true); | |
| 152 builder.SetIsFixedSizeInline(true); | |
| 153 builder.SetIsNewFormattingContext(true); | |
| 154 node_space_ = builder.ToConstraintSpace(); | |
| 155 } | |
| 156 NGFragment* fragment; | 118 NGFragment* fragment; |
| 157 if (node_->Layout(node_space_, &fragment)) { | 119 node.LayoutSync(space, &fragment); |
| 158 node_fragment_ = fragment; | 120 return fragment; |
| 159 return true; | |
| 160 } | |
| 161 return false; | |
| 162 } | 121 } |
| 163 | 122 |
| 164 DEFINE_TRACE(NGOutOfFlowLayoutPart) { | 123 DEFINE_TRACE(NGOutOfFlowLayoutPart) { |
| 165 visitor->trace(node_); | |
| 166 visitor->trace(parent_space_); | 124 visitor->trace(parent_space_); |
| 167 visitor->trace(node_fragment_); | |
| 168 visitor->trace(node_space_); | |
| 169 } | 125 } |
| 170 } | 126 |
| 127 } // namespace blink | |
| OLD | NEW |