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" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 | 78 |
79 // Need an explicit destructor in the .cc file, or the MSWIN compiler will | 79 // Need an explicit destructor in the .cc file, or the MSWIN compiler will |
80 // produce an error when attempting to generate a default one, if the .h file is | 80 // produce an error when attempting to generate a default one, if the .h file is |
81 // included from a compilation unit that lacks the ComputedStyle definition. | 81 // included from a compilation unit that lacks the ComputedStyle definition. |
82 NGBlockNode::~NGBlockNode() {} | 82 NGBlockNode::~NGBlockNode() {} |
83 | 83 |
84 RefPtr<NGLayoutResult> NGBlockNode::Layout(NGConstraintSpace* constraint_space, | 84 RefPtr<NGLayoutResult> NGBlockNode::Layout(NGConstraintSpace* constraint_space, |
85 NGBreakToken* break_token) { | 85 NGBreakToken* break_token) { |
86 // Use the old layout code and synthesize a fragment. | 86 // Use the old layout code and synthesize a fragment. |
87 if (!CanUseNewLayout()) { | 87 if (!CanUseNewLayout()) { |
88 DCHECK(layout_box_); | |
89 return RunOldLayout(*constraint_space); | 88 return RunOldLayout(*constraint_space); |
90 } | 89 } |
91 | 90 |
92 RefPtr<NGLayoutResult> layout_result = | 91 RefPtr<NGLayoutResult> layout_result = |
93 NGBlockLayoutAlgorithm(this, constraint_space, | 92 NGBlockLayoutAlgorithm(this, constraint_space, |
94 toNGBlockBreakToken(break_token)) | 93 toNGBlockBreakToken(break_token)) |
95 .Layout(); | 94 .Layout(); |
96 | 95 |
97 CopyFragmentDataToLayoutBox(*constraint_space, layout_result.get()); | 96 CopyFragmentDataToLayoutBox(*constraint_space, layout_result.get()); |
98 return layout_result; | 97 return layout_result; |
99 } | 98 } |
100 | 99 |
101 MinMaxContentSize NGBlockNode::ComputeMinMaxContentSize() { | 100 MinMaxContentSize NGBlockNode::ComputeMinMaxContentSize() { |
102 MinMaxContentSize sizes; | 101 MinMaxContentSize sizes; |
103 if (!CanUseNewLayout()) { | 102 if (!CanUseNewLayout()) { |
104 DCHECK(layout_box_); | |
105 // TODO(layout-ng): This could be somewhat optimized by directly calling | 103 // TODO(layout-ng): This could be somewhat optimized by directly calling |
106 // computeIntrinsicLogicalWidths, but that function is currently private. | 104 // computeIntrinsicLogicalWidths, but that function is currently private. |
107 // Consider doing that if this becomes a performance issue. | 105 // Consider doing that if this becomes a performance issue. |
108 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); | 106 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); |
109 sizes.min_content = layout_box_->computeLogicalWidthUsing( | 107 sizes.min_content = layout_box_->computeLogicalWidthUsing( |
110 MainOrPreferredSize, Length(MinContent), | 108 MainOrPreferredSize, Length(MinContent), |
111 LayoutUnit(), layout_box_->containingBlock()) - | 109 LayoutUnit(), layout_box_->containingBlock()) - |
112 borderAndPadding; | 110 borderAndPadding; |
113 sizes.max_content = layout_box_->computeLogicalWidthUsing( | 111 sizes.max_content = layout_box_->computeLogicalWidthUsing( |
114 MainOrPreferredSize, Length(MaxContent), | 112 MainOrPreferredSize, Length(MaxContent), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 147 |
150 layout_result = Layout(constraint_space.get()); | 148 layout_result = Layout(constraint_space.get()); |
151 physical_fragment = layout_result->PhysicalFragment().get(); | 149 physical_fragment = layout_result->PhysicalFragment().get(); |
152 NGBoxFragment max_fragment(FromPlatformWritingMode(Style().getWritingMode()), | 150 NGBoxFragment max_fragment(FromPlatformWritingMode(Style().getWritingMode()), |
153 toNGPhysicalBoxFragment(physical_fragment)); | 151 toNGPhysicalBoxFragment(physical_fragment)); |
154 sizes.max_content = max_fragment.InlineOverflow(); | 152 sizes.max_content = max_fragment.InlineOverflow(); |
155 return sizes; | 153 return sizes; |
156 } | 154 } |
157 | 155 |
158 const ComputedStyle& NGBlockNode::Style() const { | 156 const ComputedStyle& NGBlockNode::Style() const { |
159 DCHECK(layout_box_); | |
160 return layout_box_->styleRef(); | 157 return layout_box_->styleRef(); |
161 } | 158 } |
162 | 159 |
163 NGLayoutInputNode* NGBlockNode::NextSibling() { | 160 NGLayoutInputNode* NGBlockNode::NextSibling() { |
164 if (!next_sibling_) { | 161 if (!next_sibling_) { |
165 LayoutObject* next_sibling = | 162 LayoutObject* next_sibling = layout_box_->nextSibling(); |
166 layout_box_ ? layout_box_->nextSibling() : nullptr; | |
167 if (next_sibling) { | 163 if (next_sibling) { |
168 if (next_sibling->isInline()) | 164 if (next_sibling->isInline()) |
169 next_sibling_ = new NGInlineNode(next_sibling, &Style()); | 165 next_sibling_ = new NGInlineNode(next_sibling, &Style()); |
170 else | 166 else |
171 next_sibling_ = new NGBlockNode(next_sibling); | 167 next_sibling_ = new NGBlockNode(next_sibling); |
172 } | 168 } |
173 } | 169 } |
174 return next_sibling_; | 170 return next_sibling_; |
175 } | 171 } |
176 | 172 |
177 LayoutObject* NGBlockNode::GetLayoutObject() { | 173 LayoutObject* NGBlockNode::GetLayoutObject() { |
178 return layout_box_; | 174 return layout_box_; |
179 } | 175 } |
180 | 176 |
181 NGLayoutInputNode* NGBlockNode::FirstChild() { | 177 NGLayoutInputNode* NGBlockNode::FirstChild() { |
182 if (!first_child_) { | 178 if (!first_child_) { |
183 LayoutObject* child = layout_box_ ? layout_box_->slowFirstChild() : nullptr; | 179 LayoutObject* child = layout_box_->slowFirstChild(); |
184 if (child) { | 180 if (child) { |
185 if (child->isInline()) { | 181 if (child->isInline()) { |
186 first_child_ = new NGInlineNode(child, &Style()); | 182 first_child_ = new NGInlineNode(child, &Style()); |
187 } else { | 183 } else { |
188 first_child_ = new NGBlockNode(child); | 184 first_child_ = new NGBlockNode(child); |
189 } | 185 } |
190 } | 186 } |
191 } | 187 } |
192 return first_child_; | 188 return first_child_; |
193 } | 189 } |
194 | 190 |
195 DEFINE_TRACE(NGBlockNode) { | 191 DEFINE_TRACE(NGBlockNode) { |
196 visitor->trace(next_sibling_); | 192 visitor->trace(next_sibling_); |
197 visitor->trace(first_child_); | 193 visitor->trace(first_child_); |
198 NGLayoutInputNode::trace(visitor); | 194 NGLayoutInputNode::trace(visitor); |
199 } | 195 } |
200 | 196 |
201 bool NGBlockNode::CanUseNewLayout() { | 197 bool NGBlockNode::CanUseNewLayout() { |
202 if (!layout_box_) | |
203 return true; | |
204 if (!layout_box_->isLayoutBlockFlow()) | 198 if (!layout_box_->isLayoutBlockFlow()) |
205 return false; | 199 return false; |
206 return RuntimeEnabledFeatures::layoutNGInlineEnabled() || | 200 return RuntimeEnabledFeatures::layoutNGInlineEnabled() || |
207 !HasInlineChildren(); | 201 !HasInlineChildren(); |
208 } | 202 } |
209 | 203 |
210 bool NGBlockNode::HasInlineChildren() { | 204 bool NGBlockNode::HasInlineChildren() { |
211 if (!layout_box_ || !layout_box_->isLayoutBlockFlow()) | 205 if (!layout_box_->isLayoutBlockFlow()) |
212 return false; | 206 return false; |
213 | 207 |
214 const LayoutBlockFlow* block_flow = toLayoutBlockFlow(layout_box_); | 208 const LayoutBlockFlow* block_flow = toLayoutBlockFlow(layout_box_); |
215 if (!block_flow->childrenInline()) | 209 if (!block_flow->childrenInline()) |
216 return false; | 210 return false; |
217 LayoutObject* child = block_flow->firstChild(); | 211 LayoutObject* child = block_flow->firstChild(); |
218 while (child) { | 212 while (child) { |
219 if (child->isInline()) | 213 if (child->isInline()) |
220 return true; | 214 return true; |
221 child = child->nextSibling(); | 215 child = child->nextSibling(); |
222 } | 216 } |
223 | 217 |
224 return false; | 218 return false; |
225 } | 219 } |
226 | 220 |
227 void NGBlockNode::CopyFragmentDataToLayoutBox( | 221 void NGBlockNode::CopyFragmentDataToLayoutBox( |
228 const NGConstraintSpace& constraint_space, | 222 const NGConstraintSpace& constraint_space, |
229 NGLayoutResult* layout_result) { | 223 NGLayoutResult* layout_result) { |
230 // We may not have a layout_box_ during unit tests. | |
231 if (!layout_box_) | |
232 return; | |
233 | |
234 NGPhysicalBoxFragment* fragment = | 224 NGPhysicalBoxFragment* fragment = |
235 toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get()); | 225 toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get()); |
236 | 226 |
237 layout_box_->setWidth(fragment->Width()); | 227 layout_box_->setWidth(fragment->Width()); |
238 layout_box_->setHeight(fragment->Height()); | 228 layout_box_->setHeight(fragment->Height()); |
239 NGBoxStrut border_and_padding = ComputeBorders(constraint_space, Style()) + | 229 NGBoxStrut border_and_padding = ComputeBorders(constraint_space, Style()) + |
240 ComputePadding(constraint_space, Style()); | 230 ComputePadding(constraint_space, Style()); |
241 LayoutUnit intrinsic_logical_height = | 231 LayoutUnit intrinsic_logical_height = |
242 layout_box_->style()->isHorizontalWritingMode() | 232 layout_box_->style()->isHorizontalWritingMode() |
243 ? fragment->HeightOverflow() | 233 ? fragment->HeightOverflow() |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 .SetBlockSize(layout_box_->logicalHeight()) | 325 .SetBlockSize(layout_box_->logicalHeight()) |
336 .SetDirection(layout_box_->styleRef().direction()) | 326 .SetDirection(layout_box_->styleRef().direction()) |
337 .SetWritingMode( | 327 .SetWritingMode( |
338 FromPlatformWritingMode(layout_box_->styleRef().getWritingMode())) | 328 FromPlatformWritingMode(layout_box_->styleRef().getWritingMode())) |
339 .SetInlineOverflow(overflow.width()) | 329 .SetInlineOverflow(overflow.width()) |
340 .SetBlockOverflow(overflow.height()); | 330 .SetBlockOverflow(overflow.height()); |
341 return builder.ToBoxFragment(); | 331 return builder.ToBoxFragment(); |
342 } | 332 } |
343 | 333 |
344 void NGBlockNode::UseOldOutOfFlowPositioning() { | 334 void NGBlockNode::UseOldOutOfFlowPositioning() { |
345 DCHECK(layout_box_); | |
346 DCHECK(layout_box_->isOutOfFlowPositioned()); | 335 DCHECK(layout_box_->isOutOfFlowPositioned()); |
347 layout_box_->containingBlock()->insertPositionedObject(layout_box_); | 336 layout_box_->containingBlock()->insertPositionedObject(layout_box_); |
348 } | 337 } |
349 | 338 |
350 // Save static position for legacy AbsPos layout. | 339 // Save static position for legacy AbsPos layout. |
351 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { | 340 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { |
352 DCHECK(layout_box_); | |
353 DCHECK(layout_box_->isOutOfFlowPositioned()); | 341 DCHECK(layout_box_->isOutOfFlowPositioned()); |
354 DCHECK(layout_box_->layer()); | 342 DCHECK(layout_box_->layer()); |
355 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); | 343 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); |
356 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); | 344 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); |
357 } | 345 } |
358 | 346 |
359 } // namespace blink | 347 } // namespace blink |
OLD | NEW |