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_layout_algorithm.h" | 5 #include "core/layout/ng/ng_block_layout_algorithm.h" |
6 | 6 |
7 #include "core/layout/ng/ng_break_token.h" | 7 #include "core/layout/ng/ng_break_token.h" |
8 #include "core/layout/ng/ng_constraint_space.h" | 8 #include "core/layout/ng/ng_constraint_space.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_base.h" | 10 #include "core/layout/ng/ng_fragment_base.h" |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 } | 174 } |
175 | 175 |
176 } // namespace | 176 } // namespace |
177 | 177 |
178 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( | 178 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( |
179 PassRefPtr<const ComputedStyle> style, | 179 PassRefPtr<const ComputedStyle> style, |
180 NGBlockNode* first_child, | 180 NGBlockNode* first_child, |
181 NGConstraintSpace* constraint_space, | 181 NGConstraintSpace* constraint_space, |
182 NGBreakToken* break_token) | 182 NGBreakToken* break_token) |
183 : NGLayoutAlgorithm(kBlockLayoutAlgorithm), | 183 : NGLayoutAlgorithm(kBlockLayoutAlgorithm), |
184 state_(kStateInit), | 184 layout_state_(kStateInit), |
| 185 compute_minmax_state_(kStateInit), |
185 style_(style), | 186 style_(style), |
186 first_child_(first_child), | 187 first_child_(first_child), |
187 constraint_space_(constraint_space), | 188 constraint_space_(constraint_space), |
188 break_token_(break_token), | 189 break_token_(break_token), |
189 is_fragment_margin_strut_block_start_updated_(false) { | 190 is_fragment_margin_strut_block_start_updated_(false) { |
190 DCHECK(style_); | 191 DCHECK(style_); |
191 } | 192 } |
192 | 193 |
| 194 NGLayoutAlgorithm::MinAndMaxState |
| 195 NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes( |
| 196 MinAndMaxContentSizes* sizes) { |
| 197 switch (compute_minmax_state_) { |
| 198 case kStateInit: |
| 199 pending_minmax_sizes_.min_content = pending_minmax_sizes_.max_content = |
| 200 LayoutUnit(); |
| 201 // Size-contained elements don't consider their contents for intrinsic |
| 202 // sizing. |
| 203 if (style_->containsSize()) |
| 204 return kSuccess; |
| 205 current_minmax_child_ = first_child_; |
| 206 compute_minmax_state_ = kStateChildLayout; |
| 207 case kStateChildLayout: |
| 208 // TODO: handle floats & orthogonal children |
| 209 if (current_minmax_child_) { |
| 210 Optional<MinAndMaxContentSizes> child_minmax; |
| 211 if (NeedMinAndMaxContentSizesForContentContribution( |
| 212 *current_minmax_child_->Style())) { |
| 213 child_minmax = MinAndMaxContentSizes(); |
| 214 if (!current_minmax_child_->ComputeMinAndMaxContentSizes( |
| 215 &*child_minmax)) |
| 216 return kPending; |
| 217 } |
| 218 MinAndMaxContentSizes child_sizes = ComputeMinAndMaxContentContribution( |
| 219 *current_minmax_child_->Style(), child_minmax); |
| 220 pending_minmax_sizes_.min_content = std::max( |
| 221 pending_minmax_sizes_.min_content, child_sizes.min_content); |
| 222 pending_minmax_sizes_.max_content = std::max( |
| 223 pending_minmax_sizes_.max_content, child_sizes.max_content); |
| 224 |
| 225 current_minmax_child_ = current_minmax_child_->NextSibling(); |
| 226 if (current_minmax_child_) |
| 227 return kPending; |
| 228 } |
| 229 |
| 230 *sizes = pending_minmax_sizes_; |
| 231 sizes->max_content = std::max(sizes->min_content, sizes->max_content); |
| 232 compute_minmax_state_ = kStateInit; |
| 233 return kSuccess; |
| 234 default: |
| 235 NOTREACHED(); |
| 236 return kSuccess; |
| 237 }; |
| 238 } |
| 239 |
193 NGLayoutStatus NGBlockLayoutAlgorithm::Layout( | 240 NGLayoutStatus NGBlockLayoutAlgorithm::Layout( |
194 NGPhysicalFragmentBase* child_fragment, | 241 NGPhysicalFragmentBase* child_fragment, |
195 NGPhysicalFragmentBase** fragment_out, | 242 NGPhysicalFragmentBase** fragment_out, |
196 NGLayoutAlgorithm** algorithm_out) { | 243 NGLayoutAlgorithm** algorithm_out) { |
197 switch (state_) { | 244 switch (layout_state_) { |
198 case kStateInit: { | 245 case kStateInit: { |
| 246 WTF::Optional<MinAndMaxContentSizes> sizes; |
| 247 if (NeedMinAndMaxContentSizes(Style())) { |
| 248 sizes = MinAndMaxContentSizes(); |
| 249 if (ComputeMinAndMaxContentSizes(&*sizes) == kPending) |
| 250 return kNotFinished; |
| 251 } |
| 252 |
199 border_and_padding_ = | 253 border_and_padding_ = |
200 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); | 254 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); |
201 | 255 |
202 WTF::Optional<MinAndMaxContentSizes> sizes; | |
203 if (NeedMinAndMaxContentSizes(Style())) { | |
204 // TODOO(layout-ng): Implement | |
205 sizes = MinAndMaxContentSizes(); | |
206 } | |
207 LayoutUnit inline_size = | 256 LayoutUnit inline_size = |
208 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); | 257 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); |
209 LayoutUnit adjusted_inline_size = | 258 LayoutUnit adjusted_inline_size = |
210 inline_size - border_and_padding_.InlineSum(); | 259 inline_size - border_and_padding_.InlineSum(); |
211 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of | 260 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of |
212 // -1? | 261 // -1? |
213 LayoutUnit block_size = ComputeBlockSizeForFragment( | 262 LayoutUnit block_size = ComputeBlockSizeForFragment( |
214 ConstraintSpace(), Style(), NGSizeIndefinite); | 263 ConstraintSpace(), Style(), NGSizeIndefinite); |
215 LayoutUnit adjusted_block_size(block_size); | 264 LayoutUnit adjusted_block_size(block_size); |
216 // Our calculated block-axis size may be indefinite at this point. | 265 // Our calculated block-axis size may be indefinite at this point. |
(...skipping 14 matching lines...) Expand all Loading... |
231 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); | 280 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); |
232 | 281 |
233 content_size_ = border_and_padding_.block_start; | 282 content_size_ = border_and_padding_.block_start; |
234 | 283 |
235 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::kFragmentBox); | 284 builder_ = new NGFragmentBuilder(NGPhysicalFragmentBase::kFragmentBox); |
236 builder_->SetDirection(constraint_space_->Direction()); | 285 builder_->SetDirection(constraint_space_->Direction()); |
237 builder_->SetWritingMode(constraint_space_->WritingMode()); | 286 builder_->SetWritingMode(constraint_space_->WritingMode()); |
238 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); | 287 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); |
239 | 288 |
240 current_child_ = first_child_; | 289 current_child_ = first_child_; |
241 state_ = kStatePrepareForChildLayout; | 290 layout_state_ = kStatePrepareForChildLayout; |
242 return kNotFinished; | 291 return kNotFinished; |
243 } | 292 } |
244 case kStatePrepareForChildLayout: { | 293 case kStatePrepareForChildLayout: { |
245 if (current_child_) { | 294 if (current_child_) { |
246 // TODO(atotic): uncomment this code when implementing oof layout. | 295 // TODO(atotic): uncomment this code when implementing oof layout. |
247 // This code cannot be turned on because it prevents layout of | 296 // This code cannot be turned on because it prevents layout of |
248 // oof children, and non-layedout objects trigger a DCHECK. | 297 // oof children, and non-layedout objects trigger a DCHECK. |
249 // EPosition position = current_child_->Style()->position(); | 298 // EPosition position = current_child_->Style()->position(); |
250 // if ((position == AbsolutePosition || position == FixedPosition)) { | 299 // if ((position == AbsolutePosition || position == FixedPosition)) { |
251 // builder_->AddOutOfFlowCandidateChild(current_child_, | 300 // builder_->AddOutOfFlowCandidateChild(current_child_, |
252 // GetChildSpaceOffset()); | 301 // GetChildSpaceOffset()); |
253 // } | 302 // } |
254 // else | 303 // else |
255 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); | 304 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); |
256 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( | 305 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( |
257 current_child_, space_for_current_child_); | 306 current_child_, space_for_current_child_); |
258 state_ = kStateChildLayout; | 307 layout_state_ = kStateChildLayout; |
259 return kChildAlgorithmRequired; | 308 return kChildAlgorithmRequired; |
260 } | 309 } |
261 | 310 |
262 state_ = kStateFinalize; | 311 layout_state_ = kStateFinalize; |
263 return kNotFinished; | 312 return kNotFinished; |
264 } | 313 } |
265 case kStateChildLayout: { | 314 case kStateChildLayout: { |
266 DCHECK(current_child_); | 315 DCHECK(current_child_); |
267 DCHECK(child_fragment); | 316 DCHECK(child_fragment); |
268 | 317 |
269 // TODO(layout_ng): Seems like a giant hack to call this here. | 318 // TODO(layout_ng): Seems like a giant hack to call this here. |
270 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), | 319 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), |
271 space_for_current_child_); | 320 space_for_current_child_); |
272 | 321 |
273 FinishCurrentChildLayout(new NGFragment( | 322 FinishCurrentChildLayout(new NGFragment( |
274 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), | 323 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), |
275 toNGPhysicalFragment(child_fragment))); | 324 toNGPhysicalFragment(child_fragment))); |
276 current_child_ = current_child_->NextSibling(); | 325 current_child_ = current_child_->NextSibling(); |
277 state_ = kStatePrepareForChildLayout; | 326 layout_state_ = kStatePrepareForChildLayout; |
278 return kNotFinished; | 327 return kNotFinished; |
279 } | 328 } |
280 case kStateFinalize: { | 329 case kStateFinalize: { |
281 content_size_ += border_and_padding_.block_end; | 330 content_size_ += border_and_padding_.block_end; |
282 | 331 |
283 // Recompute the block-axis size now that we know our content size. | 332 // Recompute the block-axis size now that we know our content size. |
284 LayoutUnit block_size = ComputeBlockSizeForFragment( | 333 LayoutUnit block_size = ComputeBlockSizeForFragment( |
285 ConstraintSpace(), Style(), content_size_); | 334 ConstraintSpace(), Style(), content_size_); |
286 | 335 |
287 builder_->SetBlockSize(block_size) | 336 builder_->SetBlockSize(block_size) |
288 .SetInlineOverflow(max_inline_size_) | 337 .SetInlineOverflow(max_inline_size_) |
289 .SetBlockOverflow(content_size_); | 338 .SetBlockOverflow(content_size_); |
290 *fragment_out = builder_->ToFragment(); | 339 *fragment_out = builder_->ToFragment(); |
291 state_ = kStateInit; | 340 layout_state_ = kStateInit; |
292 return kNewFragment; | 341 return kNewFragment; |
293 } | 342 } |
294 }; | 343 }; |
295 NOTREACHED(); | 344 NOTREACHED(); |
296 *fragment_out = nullptr; | 345 *fragment_out = nullptr; |
297 return kNewFragment; | 346 return kNewFragment; |
298 } | 347 } |
299 | 348 |
300 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( | 349 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( |
301 NGFragmentBase* fragment) { | 350 NGFragmentBase* fragment) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 | 508 |
460 DEFINE_TRACE(NGBlockLayoutAlgorithm) { | 509 DEFINE_TRACE(NGBlockLayoutAlgorithm) { |
461 NGLayoutAlgorithm::trace(visitor); | 510 NGLayoutAlgorithm::trace(visitor); |
462 visitor->trace(first_child_); | 511 visitor->trace(first_child_); |
463 visitor->trace(constraint_space_); | 512 visitor->trace(constraint_space_); |
464 visitor->trace(break_token_); | 513 visitor->trace(break_token_); |
465 visitor->trace(builder_); | 514 visitor->trace(builder_); |
466 visitor->trace(space_builder_); | 515 visitor->trace(space_builder_); |
467 visitor->trace(space_for_current_child_); | 516 visitor->trace(space_for_current_child_); |
468 visitor->trace(current_child_); | 517 visitor->trace(current_child_); |
| 518 visitor->trace(current_minmax_child_); |
469 } | 519 } |
470 | 520 |
471 } // namespace blink | 521 } // namespace blink |
OLD | NEW |