OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 if (child->isFloatingOrOutOfFlowPositioned() || child->isColumnSpanAll()) | 384 if (child->isFloatingOrOutOfFlowPositioned() || child->isColumnSpanAll()) |
385 continue; | 385 continue; |
386 if (!child->isSelfCollapsingBlock()) | 386 if (!child->isSelfCollapsingBlock()) |
387 return false; | 387 return false; |
388 } | 388 } |
389 return true; | 389 return true; |
390 } | 390 } |
391 return false; | 391 return false; |
392 } | 392 } |
393 | 393 |
| 394 DISABLE_CFI_PERF |
394 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) { | 395 void LayoutBlockFlow::layoutBlock(bool relayoutChildren) { |
395 ASSERT(needsLayout()); | 396 ASSERT(needsLayout()); |
396 ASSERT(isInlineBlockOrInlineTable() || !isInline()); | 397 ASSERT(isInlineBlockOrInlineTable() || !isInline()); |
397 | 398 |
398 if (!relayoutChildren && simplifiedLayout()) | 399 if (!relayoutChildren && simplifiedLayout()) |
399 return; | 400 return; |
400 | 401 |
401 LayoutAnalyzer::BlockScope analyzer(*this); | 402 LayoutAnalyzer::BlockScope analyzer(*this); |
402 SubtreeLayoutScope layoutScope(*this); | 403 SubtreeLayoutScope layoutScope(*this); |
403 | 404 |
| 405 LayoutUnit previousHeight = logicalHeight(); |
| 406 LayoutUnit oldLeft = logicalLeft(); |
| 407 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); |
| 408 relayoutChildren |= logicalWidthChanged; |
| 409 |
| 410 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope); |
| 411 LayoutState state(*this, logicalWidthChanged); |
| 412 |
| 413 if (m_paginationStateChanged) { |
| 414 // We now need a deep layout to clean up struts after pagination, if we |
| 415 // just ceased to be paginated, or, if we just became paginated on the |
| 416 // other hand, we now need the deep layout, to insert pagination struts. |
| 417 m_paginationStateChanged = false; |
| 418 state.setPaginationStateChanged(); |
| 419 } |
| 420 |
| 421 bool preferredLogicalWidthsWereDirty = preferredLogicalWidthsDirty(); |
| 422 |
404 // Multiple passes might be required for column based layout. | 423 // Multiple passes might be required for column based layout. |
405 // The number of passes could be as high as the number of columns. | 424 // The number of passes could be as high as the number of columns. |
406 LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread(); | 425 LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread(); |
407 do { | 426 do { |
408 layoutBlockFlow(relayoutChildren, layoutScope); | 427 layoutChildren(relayoutChildren, layoutScope); |
| 428 |
| 429 if (!preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty()) { |
| 430 // The only thing that should dirty preferred widths at this point is the |
| 431 // addition of overflow:auto scrollbars in a descendant. To avoid a |
| 432 // potential infinite loop, run layout again with auto scrollbars frozen |
| 433 // in their current state. |
| 434 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; |
| 435 relayoutChildren |= updateLogicalWidthAndColumnWidth(); |
| 436 layoutChildren(relayoutChildren, layoutScope); |
| 437 } |
409 | 438 |
410 if (flowThread && flowThread->columnHeightsChanged()) { | 439 if (flowThread && flowThread->columnHeightsChanged()) { |
411 setChildNeedsLayout(MarkOnlyThis); | 440 setChildNeedsLayout(MarkOnlyThis); |
412 continue; | 441 continue; |
413 } | 442 } |
414 | 443 |
415 if (shouldBreakAtLineToAvoidWidow()) { | 444 if (shouldBreakAtLineToAvoidWidow()) { |
416 setEverHadLayout(); | 445 setEverHadLayout(); |
417 continue; | 446 continue; |
418 } | 447 } |
419 break; | 448 break; |
420 } while (true); | 449 } while (true); |
421 | 450 |
| 451 // Remember the automatic logical height we got from laying out the children. |
| 452 LayoutUnit unconstrainedHeight = logicalHeight(); |
| 453 LayoutUnit unconstrainedClientAfterEdge = clientLogicalBottom(); |
| 454 |
| 455 // Adjust logical height to satisfy whatever computed style requires. |
| 456 updateLogicalHeight(); |
| 457 |
| 458 if (!childrenInline()) |
| 459 addOverhangingFloatsFromChildren(unconstrainedHeight); |
| 460 |
| 461 if (logicalHeight() != previousHeight || isDocumentElement()) |
| 462 relayoutChildren = true; |
| 463 |
| 464 PositionedLayoutBehavior behavior = DefaultLayout; |
| 465 if (oldLeft != logicalLeft()) |
| 466 behavior = ForcedLayoutAfterContainingBlockMoved; |
| 467 layoutPositionedObjects(relayoutChildren, behavior); |
| 468 |
| 469 // Add overflow from children. |
| 470 computeOverflow(unconstrainedClientAfterEdge); |
| 471 |
| 472 m_descendantsWithFloatsMarkedForLayout = false; |
| 473 |
422 updateLayerTransformAfterLayout(); | 474 updateLayerTransformAfterLayout(); |
423 | 475 |
424 updateAfterLayout(); | 476 updateAfterLayout(); |
425 | 477 |
426 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) | 478 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) |
427 positionDialog(); | 479 positionDialog(); |
428 | 480 |
429 clearNeedsLayout(); | 481 clearNeedsLayout(); |
430 updateIsSelfCollapsing(); | 482 updateIsSelfCollapsing(); |
431 } | 483 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 // exists *between* in-flow siblings (i.e. not before the first child and | 519 // exists *between* in-flow siblings (i.e. not before the first child and |
468 // not after the last child). | 520 // not after the last child). |
469 // | 521 // |
470 // [1] https://drafts.csswg.org/css-break/#possible-breaks | 522 // [1] https://drafts.csswg.org/css-break/#possible-breaks |
471 setBreakBefore(LayoutBlock::breakBefore()); | 523 setBreakBefore(LayoutBlock::breakBefore()); |
472 setBreakAfter(LayoutBlock::breakAfter()); | 524 setBreakAfter(LayoutBlock::breakAfter()); |
473 } | 525 } |
474 } | 526 } |
475 | 527 |
476 DISABLE_CFI_PERF | 528 DISABLE_CFI_PERF |
477 inline void LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, | 529 void LayoutBlockFlow::layoutChildren(bool relayoutChildren, |
478 SubtreeLayoutScope& layoutScope) { | 530 SubtreeLayoutScope& layoutScope) { |
479 LayoutUnit oldLeft = logicalLeft(); | |
480 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); | |
481 relayoutChildren |= logicalWidthChanged; | |
482 | |
483 LayoutState state(*this, logicalWidthChanged); | |
484 | |
485 if (m_paginationStateChanged) { | |
486 // We now need a deep layout to clean up struts after pagination, if we | |
487 // just ceased to be paginated, or, if we just became paginated on the | |
488 // other hand, we now need the deep layout, to insert pagination struts. | |
489 m_paginationStateChanged = false; | |
490 state.setPaginationStateChanged(); | |
491 } | |
492 | |
493 LayoutUnit previousHeight = logicalHeight(); | |
494 resetLayout(); | 531 resetLayout(); |
495 | 532 |
496 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | 533 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); |
497 LayoutUnit afterEdge = | 534 LayoutUnit afterEdge = |
498 borderAfter() + paddingAfter() + scrollbarLogicalHeight(); | 535 borderAfter() + paddingAfter() + scrollbarLogicalHeight(); |
499 setLogicalHeight(beforeEdge); | 536 setLogicalHeight(beforeEdge); |
500 | 537 |
501 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope); | |
502 | |
503 bool preferredLogicalWidthsWereDirty = preferredLogicalWidthsDirty(); | |
504 | |
505 if (childrenInline()) | 538 if (childrenInline()) |
506 layoutInlineChildren(relayoutChildren, afterEdge); | 539 layoutInlineChildren(relayoutChildren, afterEdge); |
507 else | 540 else |
508 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); | 541 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); |
509 | 542 |
510 bool preferredLogicalWidthsBecameDirty = | |
511 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty(); | |
512 if (preferredLogicalWidthsBecameDirty) { | |
513 // The only thing that should dirty preferred widths at this point is the | |
514 // addition of overflow:auto scrollbars in a descendant. To avoid a | |
515 // potential infinite loop, run layout again with auto scrollbars frozen in | |
516 // their current state. | |
517 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; | |
518 layoutBlockFlow(relayoutChildren, layoutScope); | |
519 return; | |
520 } | |
521 | |
522 // Expand our intrinsic height to encompass floats. | 543 // Expand our intrinsic height to encompass floats. |
523 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && | 544 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && |
524 createsNewFormattingContext()) | 545 createsNewFormattingContext()) |
525 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); | 546 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); |
526 | |
527 // Remember the automatic logical height we got from laying out the children. | |
528 LayoutUnit unconstrainedHeight = logicalHeight(); | |
529 LayoutUnit unconstrainedClientAfterEdge = clientLogicalBottom(); | |
530 | |
531 // Adjust logical height to satisfy whatever computed style requires. | |
532 updateLogicalHeight(); | |
533 | |
534 if (!childrenInline()) | |
535 addOverhangingFloatsFromChildren(unconstrainedHeight); | |
536 | |
537 if (previousHeight != logicalHeight() || isDocumentElement()) | |
538 relayoutChildren = true; | |
539 | |
540 PositionedLayoutBehavior behavior = DefaultLayout; | |
541 if (oldLeft != logicalLeft()) | |
542 behavior = ForcedLayoutAfterContainingBlockMoved; | |
543 layoutPositionedObjects(relayoutChildren, behavior); | |
544 | |
545 // Add overflow from children (unless we're multi-column, since in that case | |
546 // all our child overflow is clipped anyway). | |
547 computeOverflow(unconstrainedClientAfterEdge); | |
548 | |
549 m_descendantsWithFloatsMarkedForLayout = false; | |
550 } | 547 } |
551 | 548 |
552 void LayoutBlockFlow::addOverhangingFloatsFromChildren( | 549 void LayoutBlockFlow::addOverhangingFloatsFromChildren( |
553 LayoutUnit unconstrainedHeight) { | 550 LayoutUnit unconstrainedHeight) { |
554 LayoutBlockFlow* lowestBlock = nullptr; | 551 LayoutBlockFlow* lowestBlock = nullptr; |
555 bool addedOverhangingFloats = false; | 552 bool addedOverhangingFloats = false; |
556 // One of our children's floats may have become an overhanging float for us. | 553 // One of our children's floats may have become an overhanging float for us. |
557 for (LayoutObject* child = lastChild(); child; | 554 for (LayoutObject* child = lastChild(); child; |
558 child = child->previousSibling()) { | 555 child = child->previousSibling()) { |
559 // TODO(robhogan): We should exclude blocks that create formatting | 556 // TODO(robhogan): We should exclude blocks that create formatting |
(...skipping 4004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4564 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4561 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
4565 } | 4562 } |
4566 | 4563 |
4567 void LayoutBlockFlow::invalidateDisplayItemClients( | 4564 void LayoutBlockFlow::invalidateDisplayItemClients( |
4568 PaintInvalidationReason invalidationReason) const { | 4565 PaintInvalidationReason invalidationReason) const { |
4569 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4566 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
4570 invalidationReason); | 4567 invalidationReason); |
4571 } | 4568 } |
4572 | 4569 |
4573 } // namespace blink | 4570 } // namespace blink |
OLD | NEW |