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_block_node.h" | 5 #include "core/layout/ng/ng_block_node.h" |
| 6 | 6 |
| 7 #include "core/layout/LayoutBlockFlow.h" | 7 #include "core/layout/LayoutBlockFlow.h" |
| 8 #include "core/layout/api/LineLayoutAPIShim.h" | 8 #include "core/layout/api/LineLayoutAPIShim.h" |
| 9 #include "core/layout/line/InlineIterator.h" | 9 #include "core/layout/line/InlineIterator.h" |
| 10 #include "core/layout/ng/layout_ng_block_flow.h" | 10 #include "core/layout/ng/layout_ng_block_flow.h" |
| 11 #include "core/layout/ng/ng_block_layout_algorithm.h" | 11 #include "core/layout/ng/ng_block_layout_algorithm.h" |
| 12 #include "core/layout/ng/ng_box_fragment.h" | 12 #include "core/layout/ng/ng_box_fragment.h" |
| 13 #include "core/layout/ng/ng_constraint_space.h" | 13 #include "core/layout/ng/ng_constraint_space.h" |
| 14 #include "core/layout/ng/ng_constraint_space_builder.h" | 14 #include "core/layout/ng/ng_constraint_space_builder.h" |
| 15 #include "core/layout/ng/ng_fragment_builder.h" | 15 #include "core/layout/ng/ng_fragment_builder.h" |
| 16 #include "core/layout/ng/ng_inline_node.h" | 16 #include "core/layout/ng/ng_inline_node.h" |
| 17 #include "core/layout/ng/ng_layout_coordinator.h" | |
| 18 #include "core/layout/ng/ng_length_utils.h" | 17 #include "core/layout/ng/ng_length_utils.h" |
| 19 #include "core/layout/ng/ng_writing_mode.h" | 18 #include "core/layout/ng/ng_writing_mode.h" |
| 20 #include "core/paint/PaintLayer.h" | 19 #include "core/paint/PaintLayer.h" |
| 21 #include "platform/RuntimeEnabledFeatures.h" | 20 #include "platform/RuntimeEnabledFeatures.h" |
| 22 | 21 |
| 23 namespace blink { | 22 namespace blink { |
| 24 | 23 |
| 25 NGBlockNode::NGBlockNode(LayoutObject* layout_object) | 24 NGBlockNode::NGBlockNode(LayoutObject* layout_object) |
| 26 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), | 25 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), |
| 27 layout_box_(toLayoutBox(layout_object)) { | 26 layout_box_(toLayoutBox(layout_object)) { |
| 28 DCHECK(layout_box_); | 27 DCHECK(layout_box_); |
| 29 } | 28 } |
| 30 | 29 |
| 31 NGBlockNode::NGBlockNode(ComputedStyle* style) | 30 NGBlockNode::NGBlockNode(ComputedStyle* style) |
| 32 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), | 31 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), |
| 33 layout_box_(nullptr), | 32 layout_box_(nullptr), |
| 34 style_(style) { | 33 style_(style) { |
| 35 DCHECK(style_); | 34 DCHECK(style_); |
| 36 } | 35 } |
| 37 | 36 |
| 38 // Need an explicit destructor in the .cc file, or the MSWIN compiler will | 37 // Need an explicit destructor in the .cc file, or the MSWIN compiler will |
| 39 // produce an error when attempting to generate a default one, if the .h file is | 38 // produce an error when attempting to generate a default one, if the .h file is |
| 40 // included from a compilation unit that lacks the ComputedStyle definition. | 39 // included from a compilation unit that lacks the ComputedStyle definition. |
| 41 NGBlockNode::~NGBlockNode() {} | 40 NGBlockNode::~NGBlockNode() {} |
| 42 | 41 |
| 43 void NGBlockNode::LayoutSync(NGConstraintSpace* constraint_space, | 42 NGPhysicalFragment* NGBlockNode::Layout(NGConstraintSpace* constraint_space) { |
| 44 NGFragment** out) { | |
| 45 while (!Layout(constraint_space, out)) | |
| 46 continue; | |
| 47 } | |
| 48 | |
| 49 bool NGBlockNode::Layout(NGConstraintSpace* constraint_space, | |
| 50 NGFragment** out) { | |
| 51 // We can either use the new layout code to do the layout and then copy the | 43 // We can either use the new layout code to do the layout and then copy the |
| 52 // resulting size to the LayoutObject, or use the old layout code and | 44 // resulting size to the LayoutObject, or use the old layout code and |
| 53 // synthesize a fragment. | 45 // synthesize a fragment. |
| 54 if (CanUseNewLayout()) { | 46 if (CanUseNewLayout()) { |
| 55 NGPhysicalFragment* fragment; | 47 NGLayoutAlgorithm* algorithm = |
| 56 | 48 NGLayoutInputNode::AlgorithmForInputNode(this, constraint_space); |
| 57 // Store a coordinator so Layout can preserve its existing semantic | 49 fragment_ = toNGPhysicalBoxFragment(algorithm->Layout()); |
| 58 // of returning false until completed. | 50 CopyFragmentDataToLayoutBox(*constraint_space); |
| 59 if (!layout_coordinator_) | |
| 60 layout_coordinator_ = new NGLayoutCoordinator(this, constraint_space); | |
| 61 | |
| 62 if (!layout_coordinator_->Tick(&fragment)) | |
| 63 return false; | |
| 64 | |
| 65 fragment_ = toNGPhysicalBoxFragment(fragment); | |
| 66 | |
| 67 UpdateLayoutBox(fragment_, constraint_space); | |
| 68 } else { | 51 } else { |
| 69 DCHECK(layout_box_); | 52 DCHECK(layout_box_); |
| 70 fragment_ = RunOldLayout(*constraint_space); | 53 fragment_ = RunOldLayout(*constraint_space); |
| 71 } | 54 } |
| 72 *out = new NGBoxFragment(FromPlatformWritingMode(Style()->getWritingMode()), | |
| 73 Style()->direction(), fragment_.get()); | |
| 74 // Reset coordinator for future use | |
| 75 layout_coordinator_ = nullptr; | |
| 76 return true; | |
| 77 } | |
| 78 | 55 |
| 79 void NGBlockNode::UpdateLayoutBox(NGPhysicalBoxFragment* fragment, | 56 return fragment_; |
| 80 const NGConstraintSpace* constraint_space) { | |
| 81 fragment_ = fragment; | |
| 82 if (layout_box_) { | |
| 83 CopyFragmentDataToLayoutBox(*constraint_space); | |
| 84 } | |
| 85 } | 57 } |
| 86 | 58 |
| 87 MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizesSync() { | 59 MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizesSync() { |
| 88 MinAndMaxContentSizes sizes; | 60 MinAndMaxContentSizes sizes; |
| 89 while (!ComputeMinAndMaxContentSizes(&sizes)) | 61 while (!ComputeMinAndMaxContentSizes(&sizes)) |
| 90 continue; | 62 continue; |
| 91 return sizes; | 63 return sizes; |
| 92 } | 64 } |
| 93 | 65 |
| 94 bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { | 66 bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { |
| 95 if (!CanUseNewLayout()) { | 67 if (!CanUseNewLayout()) { |
| 96 DCHECK(layout_box_); | 68 DCHECK(layout_box_); |
| 97 // TODO(layout-ng): This could be somewhat optimized by directly calling | 69 // TODO(layout-ng): This could be somewhat optimized by directly calling |
| 98 // computeIntrinsicLogicalWidths, but that function is currently private. | 70 // computeIntrinsicLogicalWidths, but that function is currently private. |
| 99 // Consider doing that if this becomes a performance issue. | 71 // Consider doing that if this becomes a performance issue. |
| 100 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); | 72 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); |
| 101 sizes->min_content = layout_box_->computeLogicalWidthUsing( | 73 sizes->min_content = layout_box_->computeLogicalWidthUsing( |
| 102 MainOrPreferredSize, Length(MinContent), | 74 MainOrPreferredSize, Length(MinContent), |
| 103 LayoutUnit(), layout_box_->containingBlock()) - | 75 LayoutUnit(), layout_box_->containingBlock()) - |
| 104 borderAndPadding; | 76 borderAndPadding; |
| 105 sizes->max_content = layout_box_->computeLogicalWidthUsing( | 77 sizes->max_content = layout_box_->computeLogicalWidthUsing( |
| 106 MainOrPreferredSize, Length(MaxContent), | 78 MainOrPreferredSize, Length(MaxContent), |
| 107 LayoutUnit(), layout_box_->containingBlock()) - | 79 LayoutUnit(), layout_box_->containingBlock()) - |
| 108 borderAndPadding; | 80 borderAndPadding; |
| 109 return true; | 81 return true; |
| 110 } | 82 } |
| 111 DCHECK(!layout_coordinator_) | |
| 112 << "Can't interleave Layout and ComputeMinAndMaxContentSizes"; | |
| 113 | 83 |
| 114 NGConstraintSpace* constraint_space = | 84 NGConstraintSpace* constraint_space = |
| 115 NGConstraintSpaceBuilder( | 85 NGConstraintSpaceBuilder( |
| 116 FromPlatformWritingMode(Style()->getWritingMode())) | 86 FromPlatformWritingMode(Style()->getWritingMode())) |
| 117 .SetTextDirection(Style()->direction()) | 87 .SetTextDirection(Style()->direction()) |
| 118 .ToConstraintSpace(); | 88 .ToConstraintSpace(); |
| 119 | 89 |
| 120 // TODO(cbiesinger): For orthogonal children, we need to always synthesize. | 90 // TODO(cbiesinger): For orthogonal children, we need to always synthesize. |
| 121 NGBlockLayoutAlgorithm minmax_algorithm(Style(), toNGBlockNode(FirstChild()), | 91 NGBlockLayoutAlgorithm minmax_algorithm(Style(), toNGBlockNode(FirstChild()), |
| 122 constraint_space); | 92 constraint_space); |
| 123 if (minmax_algorithm.ComputeMinAndMaxContentSizes(sizes)) | 93 if (minmax_algorithm.ComputeMinAndMaxContentSizes(sizes)) |
| 124 return true; | 94 return true; |
| 125 | 95 |
| 126 NGLayoutCoordinator* minmax_coordinator = | |
| 127 new NGLayoutCoordinator(this, constraint_space); | |
| 128 | |
| 129 // Have to synthesize this value. | 96 // Have to synthesize this value. |
| 130 NGPhysicalFragment* physical_fragment; | 97 NGPhysicalFragment* physical_fragment = this->Layout(constraint_space); |
|
cbiesinger
2017/01/20 21:21:56
Why the "this->"?
ikilpatrick
2017/01/20 23:19:57
Because I am a doofus :), done.
| |
| 131 while (!minmax_coordinator->Tick(&physical_fragment)) | |
| 132 continue; | |
| 133 NGBoxFragment* fragment = new NGBoxFragment( | 98 NGBoxFragment* fragment = new NGBoxFragment( |
| 134 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), | 99 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), |
| 135 toNGPhysicalBoxFragment(physical_fragment)); | 100 toNGPhysicalBoxFragment(physical_fragment)); |
| 136 | 101 |
| 137 sizes->min_content = fragment->InlineOverflow(); | 102 sizes->min_content = fragment->InlineOverflow(); |
| 138 | 103 |
| 139 // Now, redo with infinite space for max_content | 104 // Now, redo with infinite space for max_content |
| 140 constraint_space = | 105 constraint_space = |
| 141 NGConstraintSpaceBuilder( | 106 NGConstraintSpaceBuilder( |
| 142 FromPlatformWritingMode(Style()->getWritingMode())) | 107 FromPlatformWritingMode(Style()->getWritingMode())) |
| 143 .SetTextDirection(Style()->direction()) | 108 .SetTextDirection(Style()->direction()) |
| 144 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) | 109 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) |
| 145 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) | 110 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) |
| 146 .ToConstraintSpace(); | 111 .ToConstraintSpace(); |
| 147 | 112 |
| 148 minmax_coordinator = new NGLayoutCoordinator(this, constraint_space); | 113 physical_fragment = this->Layout(constraint_space); |
| 149 while (!minmax_coordinator->Tick(&physical_fragment)) | |
| 150 continue; | |
| 151 | |
| 152 fragment = new NGBoxFragment( | 114 fragment = new NGBoxFragment( |
| 153 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), | 115 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), |
| 154 toNGPhysicalBoxFragment(physical_fragment)); | 116 toNGPhysicalBoxFragment(physical_fragment)); |
| 155 sizes->max_content = fragment->InlineOverflow(); | 117 sizes->max_content = fragment->InlineOverflow(); |
| 156 return true; | 118 return true; |
| 157 } | 119 } |
| 158 | 120 |
| 159 ComputedStyle* NGBlockNode::MutableStyle() { | 121 ComputedStyle* NGBlockNode::MutableStyle() { |
| 160 if (style_) | 122 if (style_) |
| 161 return style_.get(); | 123 return style_.get(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 | 162 |
| 201 void NGBlockNode::SetFirstChild(NGLayoutInputNode* child) { | 163 void NGBlockNode::SetFirstChild(NGLayoutInputNode* child) { |
| 202 first_child_ = child; | 164 first_child_ = child; |
| 203 } | 165 } |
| 204 | 166 |
| 205 NGBreakToken* NGBlockNode::CurrentBreakToken() const { | 167 NGBreakToken* NGBlockNode::CurrentBreakToken() const { |
| 206 return fragment_ ? fragment_->BreakToken() : nullptr; | 168 return fragment_ ? fragment_->BreakToken() : nullptr; |
| 207 } | 169 } |
| 208 | 170 |
| 209 DEFINE_TRACE(NGBlockNode) { | 171 DEFINE_TRACE(NGBlockNode) { |
| 210 visitor->trace(layout_coordinator_); | |
| 211 visitor->trace(fragment_); | 172 visitor->trace(fragment_); |
| 212 visitor->trace(next_sibling_); | 173 visitor->trace(next_sibling_); |
| 213 visitor->trace(first_child_); | 174 visitor->trace(first_child_); |
| 214 NGLayoutInputNode::trace(visitor); | 175 NGLayoutInputNode::trace(visitor); |
| 215 } | 176 } |
| 216 | 177 |
| 217 void NGBlockNode::PositionUpdated() { | 178 void NGBlockNode::PositionUpdated() { |
| 218 if (!layout_box_) | 179 if (!layout_box_) |
| 219 return; | 180 return; |
| 220 DCHECK(layout_box_->parent()) << "Should be called on children only."; | 181 DCHECK(layout_box_->parent()) << "Should be called on children only."; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 if (child->isInline()) | 213 if (child->isInline()) |
| 253 return true; | 214 return true; |
| 254 child = child->nextSibling(); | 215 child = child->nextSibling(); |
| 255 } | 216 } |
| 256 | 217 |
| 257 return false; | 218 return false; |
| 258 } | 219 } |
| 259 | 220 |
| 260 void NGBlockNode::CopyFragmentDataToLayoutBox( | 221 void NGBlockNode::CopyFragmentDataToLayoutBox( |
| 261 const NGConstraintSpace& constraint_space) { | 222 const NGConstraintSpace& constraint_space) { |
| 262 DCHECK(layout_box_); | 223 // We may not have a layout_box_ during unit tests. |
| 224 if (!layout_box_) | |
| 225 return; | |
| 226 | |
| 263 layout_box_->setWidth(fragment_->Width()); | 227 layout_box_->setWidth(fragment_->Width()); |
| 264 layout_box_->setHeight(fragment_->Height()); | 228 layout_box_->setHeight(fragment_->Height()); |
| 265 NGBoxStrut border_and_padding = | 229 NGBoxStrut border_and_padding = |
| 266 ComputeBorders(*Style()) + ComputePadding(constraint_space, *Style()); | 230 ComputeBorders(*Style()) + ComputePadding(constraint_space, *Style()); |
| 267 LayoutUnit intrinsic_logical_height = | 231 LayoutUnit intrinsic_logical_height = |
| 268 layout_box_->style()->isHorizontalWritingMode() | 232 layout_box_->style()->isHorizontalWritingMode() |
| 269 ? fragment_->HeightOverflow() | 233 ? fragment_->HeightOverflow() |
| 270 : fragment_->WidthOverflow(); | 234 : fragment_->WidthOverflow(); |
| 271 intrinsic_logical_height -= border_and_padding.BlockSum(); | 235 intrinsic_logical_height -= border_and_padding.BlockSum(); |
| 272 layout_box_->setIntrinsicContentLogicalHeight(intrinsic_logical_height); | 236 layout_box_->setIntrinsicContentLogicalHeight(intrinsic_logical_height); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 // Save static position for legacy AbsPos layout. | 311 // Save static position for legacy AbsPos layout. |
| 348 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { | 312 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { |
| 349 DCHECK(layout_box_); | 313 DCHECK(layout_box_); |
| 350 DCHECK(layout_box_->isOutOfFlowPositioned()); | 314 DCHECK(layout_box_->isOutOfFlowPositioned()); |
| 351 DCHECK(layout_box_->layer()); | 315 DCHECK(layout_box_->layer()); |
| 352 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); | 316 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); |
| 353 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); | 317 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); |
| 354 } | 318 } |
| 355 | 319 |
| 356 } // namespace blink | 320 } // namespace blink |
| OLD | NEW |