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