| 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_constraint_space_builder.h" | 12 #include "core/layout/ng/ng_constraint_space_builder.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_fragment.h" | |
| 15 #include "core/layout/ng/ng_fragment_builder.h" | 14 #include "core/layout/ng/ng_fragment_builder.h" |
| 16 #include "core/layout/ng/ng_inline_node.h" | 15 #include "core/layout/ng/ng_inline_node.h" |
| 17 #include "core/layout/ng/ng_layout_coordinator.h" | 16 #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" |
| 19 #include "core/layout/ng/ng_box_fragment.h" |
| 20 #include "platform/RuntimeEnabledFeatures.h" | 20 #include "platform/RuntimeEnabledFeatures.h" |
| 21 | 21 |
| 22 namespace blink { | 22 namespace blink { |
| 23 | 23 |
| 24 NGBlockNode::NGBlockNode(LayoutObject* layout_object) | 24 NGBlockNode::NGBlockNode(LayoutObject* layout_object) |
| 25 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), | 25 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), |
| 26 layout_box_(toLayoutBox(layout_object)) { | 26 layout_box_(toLayoutBox(layout_object)) { |
| 27 DCHECK(layout_box_); | 27 DCHECK(layout_box_); |
| 28 } | 28 } |
| 29 | 29 |
| 30 NGBlockNode::NGBlockNode(ComputedStyle* style) | 30 NGBlockNode::NGBlockNode(ComputedStyle* style) |
| 31 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), | 31 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), |
| 32 layout_box_(nullptr), | 32 layout_box_(nullptr), |
| 33 style_(style) { | 33 style_(style) { |
| 34 DCHECK(style_); | 34 DCHECK(style_); |
| 35 } | 35 } |
| 36 | 36 |
| 37 // 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 |
| 38 // 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 |
| 39 // included from a compilation unit that lacks the ComputedStyle definition. | 39 // included from a compilation unit that lacks the ComputedStyle definition. |
| 40 NGBlockNode::~NGBlockNode() {} | 40 NGBlockNode::~NGBlockNode() {} |
| 41 | 41 |
| 42 bool NGBlockNode::Layout(NGConstraintSpace* constraint_space, | 42 bool NGBlockNode::Layout(NGConstraintSpace* constraint_space, |
| 43 NGFragmentBase** out) { | 43 NGFragment** out) { |
| 44 DCHECK(!minmax_algorithm_) | 44 DCHECK(!minmax_algorithm_) |
| 45 << "Can't interleave Layout and ComputeMinAndMaxContentSizes"; | 45 << "Can't interleave Layout and ComputeMinAndMaxContentSizes"; |
| 46 // We can either use the new layout code to do the layout and then copy the | 46 // We can either use the new layout code to do the layout and then copy the |
| 47 // resulting size to the LayoutObject, or use the old layout code and | 47 // resulting size to the LayoutObject, or use the old layout code and |
| 48 // synthesize a fragment. | 48 // synthesize a fragment. |
| 49 if (CanUseNewLayout()) { | 49 if (CanUseNewLayout()) { |
| 50 NGPhysicalFragmentBase* fragment; | 50 NGPhysicalFragment* fragment; |
| 51 | 51 |
| 52 // Store a coordinator so Layout can preserve its existing semantic | 52 // Store a coordinator so Layout can preserve its existing semantic |
| 53 // of returning false until completed. | 53 // of returning false until completed. |
| 54 if (!layout_coordinator_) | 54 if (!layout_coordinator_) |
| 55 layout_coordinator_ = new NGLayoutCoordinator(this, constraint_space); | 55 layout_coordinator_ = new NGLayoutCoordinator(this, constraint_space); |
| 56 | 56 |
| 57 if (!layout_coordinator_->Tick(&fragment)) | 57 if (!layout_coordinator_->Tick(&fragment)) |
| 58 return false; | 58 return false; |
| 59 | 59 |
| 60 fragment_ = toNGPhysicalFragment(fragment); | 60 fragment_ = toNGPhysicalBoxFragment(fragment); |
| 61 | 61 |
| 62 UpdateLayoutBox(fragment_, constraint_space); | 62 UpdateLayoutBox(fragment_, constraint_space); |
| 63 } else { | 63 } else { |
| 64 DCHECK(layout_box_); | 64 DCHECK(layout_box_); |
| 65 fragment_ = RunOldLayout(*constraint_space); | 65 fragment_ = RunOldLayout(*constraint_space); |
| 66 } | 66 } |
| 67 *out = new NGFragment(FromPlatformWritingMode(Style()->getWritingMode()), | 67 *out = new NGBoxFragment(FromPlatformWritingMode(Style()->getWritingMode()), |
| 68 Style()->direction(), fragment_.get()); | 68 Style()->direction(), fragment_.get()); |
| 69 // Reset coordinator for future use | 69 // Reset coordinator for future use |
| 70 layout_coordinator_ = nullptr; | 70 layout_coordinator_ = nullptr; |
| 71 return true; | 71 return true; |
| 72 } | 72 } |
| 73 | 73 |
| 74 void NGBlockNode::UpdateLayoutBox(NGPhysicalFragment* fragment, | 74 void NGBlockNode::UpdateLayoutBox(NGPhysicalBoxFragment* fragment, |
| 75 const NGConstraintSpace* constraint_space) { | 75 const NGConstraintSpace* constraint_space) { |
| 76 fragment_ = fragment; | 76 fragment_ = fragment; |
| 77 if (layout_box_) { | 77 if (layout_box_) { |
| 78 CopyFragmentDataToLayoutBox(*constraint_space); | 78 CopyFragmentDataToLayoutBox(*constraint_space); |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| 82 bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { | 82 bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { |
| 83 if (!CanUseNewLayout()) { | 83 if (!CanUseNewLayout()) { |
| 84 DCHECK(layout_box_); | 84 DCHECK(layout_box_); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 return false; | 120 return false; |
| 121 DCHECK_EQ(state, NGLayoutAlgorithm::kNotImplemented); | 121 DCHECK_EQ(state, NGLayoutAlgorithm::kNotImplemented); |
| 122 | 122 |
| 123 // TODO(cbiesinger): Replace the loops below with a state machine like in | 123 // TODO(cbiesinger): Replace the loops below with a state machine like in |
| 124 // Layout. | 124 // Layout. |
| 125 | 125 |
| 126 NGLayoutCoordinator* minmax_coordinator = | 126 NGLayoutCoordinator* minmax_coordinator = |
| 127 new NGLayoutCoordinator(this, constraint_space); | 127 new NGLayoutCoordinator(this, constraint_space); |
| 128 | 128 |
| 129 // Have to synthesize this value. | 129 // Have to synthesize this value. |
| 130 NGPhysicalFragmentBase* physical_fragment; | 130 NGPhysicalFragment* physical_fragment; |
| 131 while (!minmax_coordinator->Tick(&physical_fragment)) | 131 while (!minmax_coordinator->Tick(&physical_fragment)) |
| 132 continue; | 132 continue; |
| 133 NGFragment* fragment = new NGFragment( | 133 NGBoxFragment* fragment = new NGBoxFragment( |
| 134 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), | 134 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), |
| 135 toNGPhysicalFragment(physical_fragment)); | 135 toNGPhysicalBoxFragment(physical_fragment)); |
| 136 | 136 |
| 137 sizes->min_content = fragment->InlineOverflow(); | 137 sizes->min_content = fragment->InlineOverflow(); |
| 138 | 138 |
| 139 // Now, redo with infinite space for max_content | 139 // Now, redo with infinite space for max_content |
| 140 constraint_space = | 140 constraint_space = |
| 141 NGConstraintSpaceBuilder( | 141 NGConstraintSpaceBuilder( |
| 142 FromPlatformWritingMode(Style()->getWritingMode())) | 142 FromPlatformWritingMode(Style()->getWritingMode())) |
| 143 .SetTextDirection(Style()->direction()) | 143 .SetTextDirection(Style()->direction()) |
| 144 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) | 144 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) |
| 145 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) | 145 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) |
| 146 .ToConstraintSpace(); | 146 .ToConstraintSpace(); |
| 147 | 147 |
| 148 minmax_coordinator = new NGLayoutCoordinator(this, constraint_space); | 148 minmax_coordinator = new NGLayoutCoordinator(this, constraint_space); |
| 149 while (!minmax_coordinator->Tick(&physical_fragment)) | 149 while (!minmax_coordinator->Tick(&physical_fragment)) |
| 150 continue; | 150 continue; |
| 151 | 151 |
| 152 fragment = new NGFragment(FromPlatformWritingMode(Style()->getWritingMode()), | 152 fragment = new NGBoxFragment( |
| 153 Style()->direction(), | 153 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), |
| 154 toNGPhysicalFragment(physical_fragment)); | 154 toNGPhysicalBoxFragment(physical_fragment)); |
| 155 sizes->max_content = fragment->InlineOverflow(); | 155 sizes->max_content = fragment->InlineOverflow(); |
| 156 minmax_algorithm_ = nullptr; | 156 minmax_algorithm_ = nullptr; |
| 157 return true; | 157 return true; |
| 158 } | 158 } |
| 159 | 159 |
| 160 ComputedStyle* NGBlockNode::MutableStyle() { | 160 ComputedStyle* NGBlockNode::MutableStyle() { |
| 161 if (style_) | 161 if (style_) |
| 162 return style_.get(); | 162 return style_.get(); |
| 163 DCHECK(layout_box_); | 163 DCHECK(layout_box_); |
| 164 return layout_box_->mutableStyle(); | 164 return layout_box_->mutableStyle(); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 } | 291 } |
| 292 | 292 |
| 293 if (layout_box_->isLayoutBlock()) | 293 if (layout_box_->isLayoutBlock()) |
| 294 toLayoutBlock(layout_box_)->layoutPositionedObjects(true); | 294 toLayoutBlock(layout_box_)->layoutPositionedObjects(true); |
| 295 layout_box_->clearNeedsLayout(); | 295 layout_box_->clearNeedsLayout(); |
| 296 if (layout_box_->isLayoutBlockFlow()) { | 296 if (layout_box_->isLayoutBlockFlow()) { |
| 297 toLayoutBlockFlow(layout_box_)->updateIsSelfCollapsing(); | 297 toLayoutBlockFlow(layout_box_)->updateIsSelfCollapsing(); |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 | 300 |
| 301 NGPhysicalFragment* NGBlockNode::RunOldLayout( | 301 NGPhysicalBoxFragment* NGBlockNode::RunOldLayout( |
| 302 const NGConstraintSpace& constraint_space) { | 302 const NGConstraintSpace& constraint_space) { |
| 303 NGLogicalSize available_size = constraint_space.PercentageResolutionSize(); | 303 NGLogicalSize available_size = constraint_space.PercentageResolutionSize(); |
| 304 layout_box_->setOverrideContainingBlockContentLogicalWidth( | 304 layout_box_->setOverrideContainingBlockContentLogicalWidth( |
| 305 available_size.inline_size); | 305 available_size.inline_size); |
| 306 layout_box_->setOverrideContainingBlockContentLogicalHeight( | 306 layout_box_->setOverrideContainingBlockContentLogicalHeight( |
| 307 available_size.block_size); | 307 available_size.block_size); |
| 308 // TODO(layout-ng): Does this handle scrollbars correctly? | 308 // TODO(layout-ng): Does this handle scrollbars correctly? |
| 309 if (constraint_space.IsFixedSizeInline()) { | 309 if (constraint_space.IsFixedSizeInline()) { |
| 310 layout_box_->setOverrideLogicalContentWidth( | 310 layout_box_->setOverrideLogicalContentWidth( |
| 311 constraint_space.AvailableSize().inline_size - | 311 constraint_space.AvailableSize().inline_size - |
| 312 layout_box_->borderAndPaddingLogicalWidth()); | 312 layout_box_->borderAndPaddingLogicalWidth()); |
| 313 } | 313 } |
| 314 if (constraint_space.IsFixedSizeBlock()) { | 314 if (constraint_space.IsFixedSizeBlock()) { |
| 315 layout_box_->setOverrideLogicalContentHeight( | 315 layout_box_->setOverrideLogicalContentHeight( |
| 316 constraint_space.AvailableSize().block_size - | 316 constraint_space.AvailableSize().block_size - |
| 317 layout_box_->borderAndPaddingLogicalHeight()); | 317 layout_box_->borderAndPaddingLogicalHeight()); |
| 318 } | 318 } |
| 319 | 319 |
| 320 if (layout_box_->isLayoutNGBlockFlow() && layout_box_->needsLayout()) { | 320 if (layout_box_->isLayoutNGBlockFlow() && layout_box_->needsLayout()) { |
| 321 toLayoutNGBlockFlow(layout_box_)->LayoutBlockFlow::layoutBlock(true); | 321 toLayoutNGBlockFlow(layout_box_)->LayoutBlockFlow::layoutBlock(true); |
| 322 } else { | 322 } else { |
| 323 layout_box_->forceLayout(); | 323 layout_box_->forceLayout(); |
| 324 } | 324 } |
| 325 LayoutRect overflow = layout_box_->layoutOverflowRect(); | 325 LayoutRect overflow = layout_box_->layoutOverflowRect(); |
| 326 // TODO(layout-ng): This does not handle writing modes correctly (for | 326 // TODO(layout-ng): This does not handle writing modes correctly (for |
| 327 // overflow) | 327 // overflow) |
| 328 NGFragmentBuilder builder(NGPhysicalFragmentBase::kFragmentBox); | 328 NGFragmentBuilder builder(NGPhysicalFragment::kFragmentBox); |
| 329 builder.SetInlineSize(layout_box_->logicalWidth()) | 329 builder.SetInlineSize(layout_box_->logicalWidth()) |
| 330 .SetBlockSize(layout_box_->logicalHeight()) | 330 .SetBlockSize(layout_box_->logicalHeight()) |
| 331 .SetDirection(layout_box_->styleRef().direction()) | 331 .SetDirection(layout_box_->styleRef().direction()) |
| 332 .SetWritingMode( | 332 .SetWritingMode( |
| 333 FromPlatformWritingMode(layout_box_->styleRef().getWritingMode())) | 333 FromPlatformWritingMode(layout_box_->styleRef().getWritingMode())) |
| 334 .SetInlineOverflow(overflow.width()) | 334 .SetInlineOverflow(overflow.width()) |
| 335 .SetBlockOverflow(overflow.height()); | 335 .SetBlockOverflow(overflow.height()); |
| 336 return builder.ToFragment(); | 336 return builder.ToBoxFragment(); |
| 337 } | 337 } |
| 338 | 338 |
| 339 void NGBlockNode::UseOldOutOfFlowPositioning() { | 339 void NGBlockNode::UseOldOutOfFlowPositioning() { |
| 340 DCHECK(layout_box_); | 340 DCHECK(layout_box_); |
| 341 DCHECK(layout_box_->isOutOfFlowPositioned()); | 341 DCHECK(layout_box_->isOutOfFlowPositioned()); |
| 342 layout_box_->containingBlock()->insertPositionedObject(layout_box_); | 342 layout_box_->containingBlock()->insertPositionedObject(layout_box_); |
| 343 } | 343 } |
| 344 | 344 |
| 345 } // namespace blink | 345 } // namespace blink |
| OLD | NEW |