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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 RenderBlockFlow* renderer = new RenderBlockFlow(0); | 183 RenderBlockFlow* renderer = new RenderBlockFlow(0); |
184 renderer->setDocumentForAnonymous(document); | 184 renderer->setDocumentForAnonymous(document); |
185 return renderer; | 185 return renderer; |
186 } | 186 } |
187 | 187 |
188 RenderObject* RenderBlockFlow::layoutSpecialExcludedChild(bool relayoutChildren,
SubtreeLayoutScope& layoutScope) | 188 RenderObject* RenderBlockFlow::layoutSpecialExcludedChild(bool relayoutChildren,
SubtreeLayoutScope& layoutScope) |
189 { | 189 { |
190 RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread(); | 190 RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread(); |
191 if (!flowThread) | 191 if (!flowThread) |
192 return 0; | 192 return 0; |
193 setLogicalTopForChild(flowThread, borderBefore() + paddingBefore()); | 193 setLogicalTopForChild(*flowThread, borderBefore() + paddingBefore()); |
194 flowThread->layoutColumns(relayoutChildren, layoutScope); | 194 flowThread->layoutColumns(relayoutChildren, layoutScope); |
195 determineLogicalLeftPositionForChild(flowThread); | 195 determineLogicalLeftPositionForChild(*flowThread); |
196 return flowThread; | 196 return flowThread; |
197 } | 197 } |
198 | 198 |
199 bool RenderBlockFlow::updateLogicalWidthAndColumnWidth() | 199 bool RenderBlockFlow::updateLogicalWidthAndColumnWidth() |
200 { | 200 { |
201 bool relayoutChildren = RenderBlock::updateLogicalWidthAndColumnWidth(); | 201 bool relayoutChildren = RenderBlock::updateLogicalWidthAndColumnWidth(); |
202 if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 202 if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
203 if (flowThread->needsNewWidth()) | 203 if (flowThread->needsNewWidth()) |
204 return true; | 204 return true; |
205 } | 205 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 | 494 |
495 layoutPositionedObjects(relayoutChildren || isDocumentElement(), oldLeft !=
logicalLeft() ? ForcedLayoutAfterContainingBlockMoved : DefaultLayout); | 495 layoutPositionedObjects(relayoutChildren || isDocumentElement(), oldLeft !=
logicalLeft() ? ForcedLayoutAfterContainingBlockMoved : DefaultLayout); |
496 | 496 |
497 // Add overflow from children (unless we're multi-column, since in that case
all our child overflow is clipped anyway). | 497 // Add overflow from children (unless we're multi-column, since in that case
all our child overflow is clipped anyway). |
498 computeOverflow(oldClientAfterEdge); | 498 computeOverflow(oldClientAfterEdge); |
499 | 499 |
500 m_descendantsWithFloatsMarkedForLayout = false; | 500 m_descendantsWithFloatsMarkedForLayout = false; |
501 return true; | 501 return true; |
502 } | 502 } |
503 | 503 |
504 void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox* child) | 504 void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox& child) |
505 { | 505 { |
506 LayoutUnit startPosition = borderStart() + paddingStart(); | 506 LayoutUnit startPosition = borderStart() + paddingStart(); |
507 LayoutUnit initialStartPosition = startPosition; | 507 LayoutUnit initialStartPosition = startPosition; |
508 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) | 508 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) |
509 startPosition -= verticalScrollbarWidth(); | 509 startPosition -= verticalScrollbarWidth(); |
510 LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + ava
ilableLogicalWidth(); | 510 LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + ava
ilableLogicalWidth(); |
511 | 511 |
512 LayoutUnit childMarginStart = marginStartForChild(child); | 512 LayoutUnit childMarginStart = marginStartForChild(child); |
513 LayoutUnit newPosition = startPosition + childMarginStart; | 513 LayoutUnit newPosition = startPosition + childMarginStart; |
514 | 514 |
515 LayoutUnit positionToAvoidFloats; | 515 LayoutUnit positionToAvoidFloats; |
516 if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock(
)) | 516 if (child.avoidsFloats() && containsFloats() && !flowThreadContainingBlock()
) |
517 positionToAvoidFloats = startOffsetForLine(logicalTopForChild(child), fa
lse, logicalHeightForChild(child)); | 517 positionToAvoidFloats = startOffsetForLine(logicalTopForChild(child), fa
lse, logicalHeightForChild(child)); |
518 | 518 |
519 // If the child has an offset from the content edge to avoid floats then use
that, otherwise let any negative | 519 // If the child has an offset from the content edge to avoid floats then use
that, otherwise let any negative |
520 // margin pull it back over the content edge or any positive margin push it
out. | 520 // margin pull it back over the content edge or any positive margin push it
out. |
521 // If the child is being centred then the margin calculated to do that has f
actored in any offset required to | 521 // If the child is being centred then the margin calculated to do that has f
actored in any offset required to |
522 // avoid floats, so use it if necessary. | 522 // avoid floats, so use it if necessary. |
523 if (style()->textAlign() == WEBKIT_CENTER || child->style()->marginStartUsin
g(style()).isAuto()) | 523 if (style()->textAlign() == WEBKIT_CENTER || child.style()->marginStartUsing
(style()).isAuto()) |
524 newPosition = std::max(newPosition, positionToAvoidFloats + childMarginS
tart); | 524 newPosition = std::max(newPosition, positionToAvoidFloats + childMarginS
tart); |
525 else if (positionToAvoidFloats > initialStartPosition) | 525 else if (positionToAvoidFloats > initialStartPosition) |
526 newPosition = std::max(newPosition, positionToAvoidFloats); | 526 newPosition = std::max(newPosition, positionToAvoidFloats); |
527 | 527 |
528 setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPositio
n : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child)); | 528 setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPositio
n : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child)); |
529 } | 529 } |
530 | 530 |
531 void RenderBlockFlow::setLogicalLeftForChild(RenderBox* child, LayoutUnit logica
lLeft) | 531 void RenderBlockFlow::setLogicalLeftForChild(RenderBox& child, LayoutUnit logica
lLeft) |
532 { | 532 { |
533 if (isHorizontalWritingMode()) { | 533 if (isHorizontalWritingMode()) { |
534 child->setX(logicalLeft); | 534 child.setX(logicalLeft); |
535 } else { | 535 } else { |
536 child->setY(logicalLeft); | 536 child.setY(logicalLeft); |
537 } | 537 } |
538 } | 538 } |
539 | 539 |
540 void RenderBlockFlow::setLogicalTopForChild(RenderBox* child, LayoutUnit logical
Top) | 540 void RenderBlockFlow::setLogicalTopForChild(RenderBox& child, LayoutUnit logical
Top) |
541 { | 541 { |
542 if (isHorizontalWritingMode()) { | 542 if (isHorizontalWritingMode()) { |
543 child->setY(logicalTop); | 543 child.setY(logicalTop); |
544 } else { | 544 } else { |
545 child->setX(logicalTop); | 545 child.setX(logicalTop); |
546 } | 546 } |
547 } | 547 } |
548 | 548 |
549 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
LayoutUnit& previousFloatLogicalBottom) | 549 void RenderBlockFlow::layoutBlockChild(RenderBox& child, MarginInfo& marginInfo,
LayoutUnit& previousFloatLogicalBottom) |
550 { | 550 { |
551 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); | 551 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); |
552 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); | 552 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); |
553 | 553 |
554 // The child is a normal flow object. Compute the margins we will use for co
llapsing now. | 554 // The child is a normal flow object. Compute the margins we will use for co
llapsing now. |
555 child->computeAndSetBlockDirectionMargins(this); | 555 child.computeAndSetBlockDirectionMargins(this); |
556 | 556 |
557 // Try to guess our correct logical top position. In most cases this guess w
ill | 557 // Try to guess our correct logical top position. In most cases this guess w
ill |
558 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) | 558 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) |
559 // will we have to potentially relayout. | 559 // will we have to potentially relayout. |
560 LayoutUnit estimateWithoutPagination; | 560 LayoutUnit estimateWithoutPagination; |
561 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo
, estimateWithoutPagination); | 561 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo
, estimateWithoutPagination); |
562 | 562 |
563 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. | 563 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. |
564 LayoutRect oldRect = child->frameRect(); | 564 LayoutRect oldRect = child.frameRect(); |
565 LayoutUnit oldLogicalTop = logicalTopForChild(child); | 565 LayoutUnit oldLogicalTop = logicalTopForChild(child); |
566 | 566 |
567 // Go ahead and position the child as though it didn't collapse with the top
. | 567 // Go ahead and position the child as though it didn't collapse with the top
. |
568 setLogicalTopForChild(child, logicalTopEstimate); | 568 setLogicalTopForChild(child, logicalTopEstimate); |
569 | 569 |
570 RenderBlockFlow* childRenderBlockFlow = child->isRenderBlockFlow() ? toRende
rBlockFlow(child) : 0; | 570 RenderBlockFlow* childRenderBlockFlow = child.isRenderBlockFlow() ? toRender
BlockFlow(&child) : 0; |
571 bool markDescendantsWithFloats = false; | 571 bool markDescendantsWithFloats = false; |
572 if (logicalTopEstimate != oldLogicalTop && childRenderBlockFlow && !childRen
derBlockFlow->avoidsFloats() && childRenderBlockFlow->containsFloats()) { | 572 if (logicalTopEstimate != oldLogicalTop && childRenderBlockFlow && !childRen
derBlockFlow->avoidsFloats() && childRenderBlockFlow->containsFloats()) { |
573 markDescendantsWithFloats = true; | 573 markDescendantsWithFloats = true; |
574 } else if (UNLIKELY(logicalTopEstimate.mightBeSaturated())) { | 574 } else if (UNLIKELY(logicalTopEstimate.mightBeSaturated())) { |
575 // logicalTopEstimate, returned by estimateLogicalTopPosition, might be
saturated for | 575 // logicalTopEstimate, returned by estimateLogicalTopPosition, might be
saturated for |
576 // very large elements. If it does the comparison with oldLogicalTop mig
ht yield a | 576 // very large elements. If it does the comparison with oldLogicalTop mig
ht yield a |
577 // false negative as adding and removing margins, borders etc from a sat
urated number | 577 // false negative as adding and removing margins, borders etc from a sat
urated number |
578 // might yield incorrect results. If this is the case always mark for la
yout. | 578 // might yield incorrect results. If this is the case always mark for la
yout. |
579 markDescendantsWithFloats = true; | 579 markDescendantsWithFloats = true; |
580 } else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { | 580 } else if (!child.avoidsFloats() || child.shrinkToAvoidFloats()) { |
581 // If an element might be affected by the presence of floats, then alway
s mark it for | 581 // If an element might be affected by the presence of floats, then alway
s mark it for |
582 // layout. | 582 // layout. |
583 LayoutUnit fb = std::max(previousFloatLogicalBottom, lowestFloatLogicalB
ottom()); | 583 LayoutUnit fb = std::max(previousFloatLogicalBottom, lowestFloatLogicalB
ottom()); |
584 if (fb > logicalTopEstimate) | 584 if (fb > logicalTopEstimate) |
585 markDescendantsWithFloats = true; | 585 markDescendantsWithFloats = true; |
586 } | 586 } |
587 | 587 |
588 if (childRenderBlockFlow) { | 588 if (childRenderBlockFlow) { |
589 if (markDescendantsWithFloats) | 589 if (markDescendantsWithFloats) |
590 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); | 590 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); |
591 if (!child->isWritingModeRoot()) | 591 if (!child.isWritingModeRoot()) |
592 previousFloatLogicalBottom = std::max(previousFloatLogicalBottom, ol
dLogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom()); | 592 previousFloatLogicalBottom = std::max(previousFloatLogicalBottom, ol
dLogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom()); |
593 } | 593 } |
594 | 594 |
595 SubtreeLayoutScope layoutScope(*child); | 595 SubtreeLayoutScope layoutScope(child); |
596 if (!child->needsLayout()) | 596 if (!child.needsLayout()) |
597 child->markForPaginationRelayoutIfNeeded(layoutScope); | 597 child.markForPaginationRelayoutIfNeeded(layoutScope); |
598 | 598 |
599 bool childNeededLayout = child->needsLayout(); | 599 bool childNeededLayout = child.needsLayout(); |
600 if (childNeededLayout) | 600 if (childNeededLayout) |
601 child->layout(); | 601 child.layout(); |
602 | 602 |
603 // Cache if we are at the top of the block right now. | 603 // Cache if we are at the top of the block right now. |
604 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); | 604 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); |
605 bool childIsSelfCollapsing = child->isSelfCollapsingBlock(); | 605 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); |
606 | 606 |
607 // Now determine the correct ypos based off examination of collapsing margin | 607 // Now determine the correct ypos based off examination of collapsing margin |
608 // values. | 608 // values. |
609 LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo, childI
sSelfCollapsing); | 609 LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo, childI
sSelfCollapsing); |
610 | 610 |
611 // Now check for clear. | 611 // Now check for clear. |
612 LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, old
PosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear, childIsSelfCollapsin
g); | 612 LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, old
PosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear, childIsSelfCollapsin
g); |
613 | 613 |
614 bool paginated = view()->layoutState()->isPaginated(); | 614 bool paginated = view()->layoutState()->isPaginated(); |
615 if (paginated) { | 615 if (paginated) { |
616 logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClea
r, estimateWithoutPagination, child, | 616 logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClea
r, estimateWithoutPagination, child, |
617 atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear
); | 617 atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear
); |
618 } | 618 } |
619 | 619 |
620 setLogicalTopForChild(child, logicalTopAfterClear); | 620 setLogicalTopForChild(child, logicalTopAfterClear); |
621 | 621 |
622 // Now we have a final top position. See if it really does end up being diff
erent from our estimate. | 622 // Now we have a final top position. See if it really does end up being diff
erent from our estimate. |
623 // clearFloatsIfNeeded can also mark the child as needing a layout even thou
gh we didn't move. This happens | 623 // clearFloatsIfNeeded can also mark the child as needing a layout even thou
gh we didn't move. This happens |
624 // when collapseMargins dynamically adds overhanging floats because of a chi
ld with negative margins. | 624 // when collapseMargins dynamically adds overhanging floats because of a chi
ld with negative margins. |
625 if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout() || (p
aginated && childRenderBlockFlow && childRenderBlockFlow->shouldBreakAtLineToAvo
idWidow())) { | 625 if (logicalTopAfterClear != logicalTopEstimate || child.needsLayout() || (pa
ginated && childRenderBlockFlow && childRenderBlockFlow->shouldBreakAtLineToAvoi
dWidow())) { |
626 SubtreeLayoutScope layoutScope(*child); | 626 SubtreeLayoutScope layoutScope(child); |
627 if (child->shrinkToAvoidFloats()) { | 627 if (child.shrinkToAvoidFloats()) { |
628 // The child's width depends on the line width. | 628 // The child's width depends on the line width. |
629 // When the child shifts to clear an item, its width can | 629 // When the child shifts to clear an item, its width can |
630 // change (because it has more available line width). | 630 // change (because it has more available line width). |
631 // So go ahead and mark the item as dirty. | 631 // So go ahead and mark the item as dirty. |
632 layoutScope.setChildNeedsLayout(child); | 632 layoutScope.setChildNeedsLayout(&child); |
633 } | 633 } |
634 | 634 |
635 if (childRenderBlockFlow && !childRenderBlockFlow->avoidsFloats() && chi
ldRenderBlockFlow->containsFloats()) | 635 if (childRenderBlockFlow && !childRenderBlockFlow->avoidsFloats() && chi
ldRenderBlockFlow->containsFloats()) |
636 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); | 636 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); |
637 | 637 |
638 if (!child->needsLayout()) | 638 if (!child.needsLayout()) |
639 child->markForPaginationRelayoutIfNeeded(layoutScope); | 639 child.markForPaginationRelayoutIfNeeded(layoutScope); |
640 | 640 |
641 // Our guess was wrong. Make the child lay itself out again. | 641 // Our guess was wrong. Make the child lay itself out again. |
642 child->layoutIfNeeded(); | 642 child.layoutIfNeeded(); |
643 } | 643 } |
644 | 644 |
645 // If we previously encountered a self-collapsing sibling of this child that
had clearance then | 645 // If we previously encountered a self-collapsing sibling of this child that
had clearance then |
646 // we set this bit to ensure we would not collapse the child's margins, and
those of any subsequent | 646 // we set this bit to ensure we would not collapse the child's margins, and
those of any subsequent |
647 // self-collapsing siblings, with our parent. If this child is not self-coll
apsing then it can | 647 // self-collapsing siblings, with our parent. If this child is not self-coll
apsing then it can |
648 // collapse its margins with the parent so reset the bit. | 648 // collapse its margins with the parent so reset the bit. |
649 if (!marginInfo.canCollapseMarginAfterWithLastChild() && !childIsSelfCollaps
ing) | 649 if (!marginInfo.canCollapseMarginAfterWithLastChild() && !childIsSelfCollaps
ing) |
650 marginInfo.setCanCollapseMarginAfterWithLastChild(true); | 650 marginInfo.setCanCollapseMarginAfterWithLastChild(true); |
651 | 651 |
652 // We are no longer at the top of the block if we encounter a non-empty chil
d. | 652 // We are no longer at the top of the block if we encounter a non-empty chil
d. |
653 // This has to be done after checking for clear, so that margins can be rese
t if a clear occurred. | 653 // This has to be done after checking for clear, so that margins can be rese
t if a clear occurred. |
654 if (marginInfo.atBeforeSideOfBlock() && !childIsSelfCollapsing) | 654 if (marginInfo.atBeforeSideOfBlock() && !childIsSelfCollapsing) |
655 marginInfo.setAtBeforeSideOfBlock(false); | 655 marginInfo.setAtBeforeSideOfBlock(false); |
656 | 656 |
657 // Now place the child in the correct left position | 657 // Now place the child in the correct left position |
658 determineLogicalLeftPositionForChild(child); | 658 determineLogicalLeftPositionForChild(child); |
659 | 659 |
660 LayoutSize childOffset = child->location() - oldRect.location(); | 660 LayoutSize childOffset = child.location() - oldRect.location(); |
661 | 661 |
662 // Update our height now that the child has been placed in the correct posit
ion. | 662 // Update our height now that the child has been placed in the correct posit
ion. |
663 setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); | 663 setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); |
664 if (mustSeparateMarginAfterForChild(child)) { | 664 if (mustSeparateMarginAfterForChild(child)) { |
665 setLogicalHeight(logicalHeight() + marginAfterForChild(child)); | 665 setLogicalHeight(logicalHeight() + marginAfterForChild(child)); |
666 marginInfo.clearMargin(); | 666 marginInfo.clearMargin(); |
667 } | 667 } |
668 // If the child has overhanging floats that intrude into following siblings
(or possibly out | 668 // If the child has overhanging floats that intrude into following siblings
(or possibly out |
669 // of this block), then the parent gets notified of the floats now. | 669 // of this block), then the parent gets notified of the floats now. |
670 if (childRenderBlockFlow) | 670 if (childRenderBlockFlow) |
671 addOverhangingFloats(childRenderBlockFlow, !childNeededLayout); | 671 addOverhangingFloats(childRenderBlockFlow, !childNeededLayout); |
672 | 672 |
673 // If the child moved, we have to invalidate its paint as well as any floati
ng/positioned | 673 // If the child moved, we have to invalidate its paint as well as any floati
ng/positioned |
674 // descendants. An exception is if we need a layout. In this case, we know w
e're going to | 674 // descendants. An exception is if we need a layout. In this case, we know w
e're going to |
675 // invalidate our paint (and the child) anyway. | 675 // invalidate our paint (and the child) anyway. |
676 if (!selfNeedsLayout() && (childOffset.width() || childOffset.height())) | 676 if (!selfNeedsLayout() && (childOffset.width() || childOffset.height())) |
677 child->invalidatePaintForOverhangingFloats(true); | 677 child.invalidatePaintForOverhangingFloats(true); |
678 | 678 |
679 if (paginated) { | 679 if (paginated) { |
680 // Check for an after page/column break. | 680 // Check for an after page/column break. |
681 LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInf
o); | 681 LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInf
o); |
682 if (newHeight != height()) | 682 if (newHeight != height()) |
683 setLogicalHeight(newHeight); | 683 setLogicalHeight(newHeight); |
684 } | 684 } |
685 } | 685 } |
686 | 686 |
687 LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA
fterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBefore
SideOfBlock) | 687 LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA
fterClear, LayoutUnit estimateWithoutPagination, RenderBox& child, bool atBefore
SideOfBlock) |
688 { | 688 { |
689 RenderBlockFlow* childBlockFlow = child->isRenderBlockFlow() ? toRenderBlock
Flow(child) : 0; | 689 RenderBlockFlow* childBlockFlow = child.isRenderBlockFlow() ? toRenderBlockF
low(&child) : 0; |
690 | 690 |
691 if (estimateWithoutPagination != logicalTopAfterClear) { | 691 if (estimateWithoutPagination != logicalTopAfterClear) { |
692 // Our guess prior to pagination movement was wrong. Before we attempt t
o paginate, let's try again at the new | 692 // Our guess prior to pagination movement was wrong. Before we attempt t
o paginate, let's try again at the new |
693 // position. | 693 // position. |
694 setLogicalHeight(logicalTopAfterClear); | 694 setLogicalHeight(logicalTopAfterClear); |
695 setLogicalTopForChild(child, logicalTopAfterClear); | 695 setLogicalTopForChild(child, logicalTopAfterClear); |
696 | 696 |
697 if (child->shrinkToAvoidFloats()) { | 697 if (child.shrinkToAvoidFloats()) { |
698 // The child's width depends on the line width. | 698 // The child's width depends on the line width. |
699 // When the child shifts to clear an item, its width can | 699 // When the child shifts to clear an item, its width can |
700 // change (because it has more available line width). | 700 // change (because it has more available line width). |
701 // So go ahead and mark the item as dirty. | 701 // So go ahead and mark the item as dirty. |
702 child->setChildNeedsLayout(MarkOnlyThis); | 702 child.setChildNeedsLayout(MarkOnlyThis); |
703 } | 703 } |
704 | 704 |
705 SubtreeLayoutScope layoutScope(*child); | 705 SubtreeLayoutScope layoutScope(child); |
706 | 706 |
707 if (childBlockFlow) { | 707 if (childBlockFlow) { |
708 if (!childBlockFlow->avoidsFloats() && childBlockFlow->containsFloat
s()) | 708 if (!childBlockFlow->avoidsFloats() && childBlockFlow->containsFloat
s()) |
709 childBlockFlow->markAllDescendantsWithFloatsForLayout(); | 709 childBlockFlow->markAllDescendantsWithFloatsForLayout(); |
710 if (!child->needsLayout()) | 710 if (!child.needsLayout()) |
711 child->markForPaginationRelayoutIfNeeded(layoutScope); | 711 child.markForPaginationRelayoutIfNeeded(layoutScope); |
712 } | 712 } |
713 | 713 |
714 // Our guess was wrong. Make the child lay itself out again. | 714 // Our guess was wrong. Make the child lay itself out again. |
715 child->layoutIfNeeded(); | 715 child.layoutIfNeeded(); |
716 } | 716 } |
717 | 717 |
718 LayoutUnit oldTop = logicalTopAfterClear; | 718 LayoutUnit oldTop = logicalTopAfterClear; |
719 | 719 |
720 // If the object has a page or column break value of "before", then we shoul
d shift to the top of the next page. | 720 // If the object has a page or column break value of "before", then we shoul
d shift to the top of the next page. |
721 LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear); | 721 LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear); |
722 | 722 |
723 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. | 723 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. |
724 LayoutUnit logicalTopBeforeUnsplittableAdjustment = result; | 724 LayoutUnit logicalTopBeforeUnsplittableAdjustment = result; |
725 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil
d(child, result); | 725 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil
d(child, result); |
726 | 726 |
727 LayoutUnit paginationStrut = 0; | 727 LayoutUnit paginationStrut = 0; |
728 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme
nt - logicalTopBeforeUnsplittableAdjustment; | 728 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme
nt - logicalTopBeforeUnsplittableAdjustment; |
729 LayoutUnit childLogicalHeight = child->logicalHeight(); | 729 LayoutUnit childLogicalHeight = child.logicalHeight(); |
730 if (unsplittableAdjustmentDelta) { | 730 if (unsplittableAdjustmentDelta) { |
731 setPageBreak(result, childLogicalHeight - unsplittableAdjustmentDelta); | 731 setPageBreak(result, childLogicalHeight - unsplittableAdjustmentDelta); |
732 paginationStrut = unsplittableAdjustmentDelta; | 732 paginationStrut = unsplittableAdjustmentDelta; |
733 } else if (childBlockFlow && childBlockFlow->paginationStrut()) { | 733 } else if (childBlockFlow && childBlockFlow->paginationStrut()) { |
734 paginationStrut = childBlockFlow->paginationStrut(); | 734 paginationStrut = childBlockFlow->paginationStrut(); |
735 } | 735 } |
736 | 736 |
737 if (paginationStrut) { | 737 if (paginationStrut) { |
738 // We are willing to propagate out to our parent block as long as we wer
e at the top of the block prior | 738 // We are willing to propagate out to our parent block as long as we wer
e at the top of the block prior |
739 // to collapsing our margins, and as long as we didn't clear or move as
a result of other pagination. | 739 // to collapsing our margins, and as long as we didn't clear or move as
a result of other pagination. |
(...skipping 14 matching lines...) Expand all Loading... |
754 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(result, ExcludePageBoundary); | 754 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(result, ExcludePageBoundary); |
755 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; | 755 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; |
756 if (spaceShortage > 0) { | 756 if (spaceShortage > 0) { |
757 // If the child crosses a column boundary, report a break, in ca
se nothing inside it | 757 // If the child crosses a column boundary, report a break, in ca
se nothing inside it |
758 // has already done so. The column balancer needs to know how mu
ch it has to stretch | 758 // has already done so. The column balancer needs to know how mu
ch it has to stretch |
759 // the columns to make more content fit. If no breaks are report
ed (but do occur), | 759 // the columns to make more content fit. If no breaks are report
ed (but do occur), |
760 // the balancer will have no clue. Only measure the space after
the last column | 760 // the balancer will have no clue. Only measure the space after
the last column |
761 // boundary, in case it crosses more than one. | 761 // boundary, in case it crosses more than one. |
762 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag
eLogicalHeight); | 762 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag
eLogicalHeight); |
763 setPageBreak(result, spaceShortageInLastColumn ? spaceShortageIn
LastColumn : spaceShortage); | 763 setPageBreak(result, spaceShortageInLastColumn ? spaceShortageIn
LastColumn : spaceShortage); |
764 } else if (remainingLogicalHeight == pageLogicalHeight && offsetFrom
LogicalTopOfFirstPage() + child->logicalTop()) { | 764 } else if (remainingLogicalHeight == pageLogicalHeight && offsetFrom
LogicalTopOfFirstPage() + child.logicalTop()) { |
765 // We're at the very top of a page or column, and it's not the f
irst one. This child | 765 // We're at the very top of a page or column, and it's not the f
irst one. This child |
766 // may turn out to be the smallest piece of content that causes
a page break, so we | 766 // may turn out to be the smallest piece of content that causes
a page break, so we |
767 // need to report it. | 767 // need to report it. |
768 setPageBreak(result, childLogicalHeight); | 768 setPageBreak(result, childLogicalHeight); |
769 } | 769 } |
770 } | 770 } |
771 } | 771 } |
772 | 772 |
773 // Similar to how we apply clearance. Go ahead and boost height() to be the
place where we're going to position the child. | 773 // Similar to how we apply clearance. Go ahead and boost height() to be the
place where we're going to position the child. |
774 setLogicalHeight(logicalHeight() + (result - oldTop)); | 774 setLogicalHeight(logicalHeight() + (result - oldTop)); |
(...skipping 13 matching lines...) Expand all Loading... |
788 line = line->prevRootBox(); | 788 line = line->prevRootBox(); |
789 | 789 |
790 // FIXME: Paginating using line overflow isn't all fine. See FIXME in | 790 // FIXME: Paginating using line overflow isn't all fine. See FIXME in |
791 // adjustLinePositionForPagination() for more details. | 791 // adjustLinePositionForPagination() for more details. |
792 LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), l
ine->lineBottom()); | 792 LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), l
ine->lineBottom()); |
793 lineTop = std::min(line->lineTopWithLeading(), overflow.y()); | 793 lineTop = std::min(line->lineTopWithLeading(), overflow.y()); |
794 } | 794 } |
795 return lineBottom - lineTop; | 795 return lineBottom - lineTop; |
796 } | 796 } |
797 | 797 |
798 void RenderBlockFlow::adjustLinePositionForPagination(RootInlineBox* lineBox, La
youtUnit& delta, RenderFlowThread* flowThread) | 798 void RenderBlockFlow::adjustLinePositionForPagination(RootInlineBox& lineBox, La
youtUnit& delta, RenderFlowThread* flowThread) |
799 { | 799 { |
800 // FIXME: For now we paginate using line overflow. This ensures that lines d
on't overlap at all when we | 800 // FIXME: For now we paginate using line overflow. This ensures that lines d
on't overlap at all when we |
801 // put a strut between them for pagination purposes. However, this really is
n't the desired rendering, since | 801 // put a strut between them for pagination purposes. However, this really is
n't the desired rendering, since |
802 // the line on the top of the next page will appear too far down relative to
the same kind of line at the top | 802 // the line on the top of the next page will appear too far down relative to
the same kind of line at the top |
803 // of the first column. | 803 // of the first column. |
804 // | 804 // |
805 // The rendering we would like to see is one where the lineTopWithLeading is
at the top of the column, and any line overflow | 805 // The rendering we would like to see is one where the lineTopWithLeading is
at the top of the column, and any line overflow |
806 // simply spills out above the top of the column. This effect would match wh
at happens at the top of the first column. | 806 // simply spills out above the top of the column. This effect would match wh
at happens at the top of the first column. |
807 // We can't achieve this rendering, however, until we stop columns from clip
ping to the column bounds (thus allowing | 807 // We can't achieve this rendering, however, until we stop columns from clip
ping to the column bounds (thus allowing |
808 // for overflow to occur), and then cache visible overflow for each column r
ect. | 808 // for overflow to occur), and then cache visible overflow for each column r
ect. |
809 // | 809 // |
810 // Furthermore, the paint we have to do when a column has overflow has to be
special. We need to exclude | 810 // Furthermore, the paint we have to do when a column has overflow has to be
special. We need to exclude |
811 // content that paints in a previous column (and content that paints in the
following column). | 811 // content that paints in a previous column (and content that paints in the
following column). |
812 // | 812 // |
813 // For now we'll at least honor the lineTopWithLeading when paginating if it
is above the logical top overflow. This will | 813 // For now we'll at least honor the lineTopWithLeading when paginating if it
is above the logical top overflow. This will |
814 // at least make positive leading work in typical cases. | 814 // at least make positive leading work in typical cases. |
815 // | 815 // |
816 // FIXME: Another problem with simply moving lines is that the available lin
e width may change (because of floats). | 816 // FIXME: Another problem with simply moving lines is that the available lin
e width may change (because of floats). |
817 // Technically if the location we move the line to has a different line widt
h than our old position, then we need to dirty the | 817 // Technically if the location we move the line to has a different line widt
h than our old position, then we need to dirty the |
818 // line and all following lines. | 818 // line and all following lines. |
819 LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBo
x->lineTop(), lineBox->lineBottom()); | 819 LayoutRect logicalVisualOverflow = lineBox.logicalVisualOverflowRect(lineBox
.lineTop(), lineBox.lineBottom()); |
820 LayoutUnit logicalOffset = std::min(lineBox->lineTopWithLeading(), logicalVi
sualOverflow.y()); | 820 LayoutUnit logicalOffset = std::min(lineBox.lineTopWithLeading(), logicalVis
ualOverflow.y()); |
821 LayoutUnit logicalBottom = std::max(lineBox->lineBottomWithLeading(), logica
lVisualOverflow.maxY()); | 821 LayoutUnit logicalBottom = std::max(lineBox.lineBottomWithLeading(), logical
VisualOverflow.maxY()); |
822 LayoutUnit lineHeight = logicalBottom - logicalOffset; | 822 LayoutUnit lineHeight = logicalBottom - logicalOffset; |
823 updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), l
ineBox, logicalOffset, logicalBottom)); | 823 updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), &
lineBox, logicalOffset, logicalBottom)); |
824 logicalOffset += delta; | 824 logicalOffset += delta; |
825 lineBox->setPaginationStrut(0); | 825 lineBox.setPaginationStrut(0); |
826 lineBox->setIsFirstAfterPageBreak(false); | 826 lineBox.setIsFirstAfterPageBreak(false); |
827 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); | 827 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); |
828 bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUni
formLogicalHeight(); | 828 bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUni
formLogicalHeight(); |
829 // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflo
w.height() still fits, we are | 829 // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflo
w.height() still fits, we are |
830 // still going to add a strut, so that the visible overflow fits on a single
page. | 830 // still going to add a strut, so that the visible overflow fits on a single
page. |
831 if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverf
low.height() > pageLogicalHeight)) { | 831 if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverf
low.height() > pageLogicalHeight)) { |
832 // FIXME: In case the line aligns with the top of the page (or it's slig
htly shifted downwards) it will not be marked as the first line in the page. | 832 // FIXME: In case the line aligns with the top of the page (or it's slig
htly shifted downwards) it will not be marked as the first line in the page. |
833 // From here, the fix is not straightforward because it's not easy to al
ways determine when the current line is the first in the page. | 833 // From here, the fix is not straightforward because it's not easy to al
ways determine when the current line is the first in the page. |
834 return; | 834 return; |
835 } | 835 } |
836 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logi
calOffset, ExcludePageBoundary); | 836 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logi
calOffset, ExcludePageBoundary); |
837 | 837 |
838 int lineIndex = lineCount(lineBox); | 838 int lineIndex = lineCount(&lineBox); |
839 if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow()
&& lineBreakToAvoidWidow() == lineIndex)) { | 839 if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow()
&& lineBreakToAvoidWidow() == lineIndex)) { |
840 if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIn
dex) { | 840 if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIn
dex) { |
841 clearShouldBreakAtLineToAvoidWidow(); | 841 clearShouldBreakAtLineToAvoidWidow(); |
842 setDidBreakAtLineToAvoidWidow(); | 842 setDidBreakAtLineToAvoidWidow(); |
843 } | 843 } |
844 if (lineHeight > pageLogicalHeight) { | 844 if (lineHeight > pageLogicalHeight) { |
845 // Split the top margin in order to avoid splitting the visible part
of the line. | 845 // Split the top margin in order to avoid splitting the visible part
of the line. |
846 remainingLogicalHeight -= std::min(lineHeight - pageLogicalHeight, s
td::max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()
)); | 846 remainingLogicalHeight -= std::min(lineHeight - pageLogicalHeight, s
td::max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox.lineTopWithLeading())
); |
847 } | 847 } |
848 LayoutUnit totalLogicalHeight = lineHeight + std::max<LayoutUnit>(0, log
icalOffset); | 848 LayoutUnit totalLogicalHeight = lineHeight + std::max<LayoutUnit>(0, log
icalOffset); |
849 LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ?
pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalH
eight); | 849 LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ?
pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalH
eight); |
850 setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight); | 850 setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight); |
851 if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeigh
tAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineIndex)
) | 851 if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeigh
tAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineIndex)
) |
852 && !isOutOfFlowPositioned() && !isTableCell()) { | 852 && !isOutOfFlowPositioned() && !isTableCell()) { |
853 setPaginationStrut(remainingLogicalHeight + std::max<LayoutUnit>(0,
logicalOffset)); | 853 setPaginationStrut(remainingLogicalHeight + std::max<LayoutUnit>(0,
logicalOffset)); |
854 } else { | 854 } else { |
855 delta += remainingLogicalHeight; | 855 delta += remainingLogicalHeight; |
856 lineBox->setPaginationStrut(remainingLogicalHeight); | 856 lineBox.setPaginationStrut(remainingLogicalHeight); |
857 lineBox->setIsFirstAfterPageBreak(true); | 857 lineBox.setIsFirstAfterPageBreak(true); |
858 } | 858 } |
859 } else if (remainingLogicalHeight == pageLogicalHeight) { | 859 } else if (remainingLogicalHeight == pageLogicalHeight) { |
860 // We're at the very top of a page or column. | 860 // We're at the very top of a page or column. |
861 if (lineBox != firstRootBox()) | 861 if (lineBox != firstRootBox()) |
862 lineBox->setIsFirstAfterPageBreak(true); | 862 lineBox.setIsFirstAfterPageBreak(true); |
863 if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage()) | 863 if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage()) |
864 setPageBreak(logicalOffset, lineHeight); | 864 setPageBreak(logicalOffset, lineHeight); |
865 } | 865 } |
866 } | 866 } |
867 | 867 |
868 LayoutUnit RenderBlockFlow::adjustForUnsplittableChild(RenderBox* child, LayoutU
nit logicalOffset, bool includeMargins) | 868 LayoutUnit RenderBlockFlow::adjustForUnsplittableChild(RenderBox& child, LayoutU
nit logicalOffset, bool includeMargins) |
869 { | 869 { |
870 bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns() || flo
wThreadContainingBlock(); | 870 bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns() || flo
wThreadContainingBlock(); |
871 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); | 871 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); |
872 bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBr
eaks && child->style()->columnBreakInside() == PBAVOID) | 872 bool isUnsplittable = child.isUnsplittableForPagination() || (checkColumnBre
aks && child.style()->columnBreakInside() == PBAVOID) |
873 || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID); | 873 || (checkPageBreaks && child.style()->pageBreakInside() == PBAVOID); |
874 if (!isUnsplittable) | 874 if (!isUnsplittable) |
875 return logicalOffset; | 875 return logicalOffset; |
876 LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargi
ns ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit()); | 876 LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargi
ns ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit()); |
877 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); | 877 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); |
878 updateMinimumPageHeight(logicalOffset, childLogicalHeight); | 878 updateMinimumPageHeight(logicalOffset, childLogicalHeight); |
879 if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight) | 879 if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight) |
880 return logicalOffset; | 880 return logicalOffset; |
881 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logi
calOffset, ExcludePageBoundary); | 881 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logi
calOffset, ExcludePageBoundary); |
882 if (remainingLogicalHeight < childLogicalHeight) | 882 if (remainingLogicalHeight < childLogicalHeight) |
883 return logicalOffset + remainingLogicalHeight; | 883 return logicalOffset + remainingLogicalHeight; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 | 1038 |
1039 while (next) { | 1039 while (next) { |
1040 RenderBox* child = next; | 1040 RenderBox* child = next; |
1041 next = child->nextSiblingBox(); | 1041 next = child->nextSiblingBox(); |
1042 | 1042 |
1043 child->setMayNeedPaintInvalidation(true); | 1043 child->setMayNeedPaintInvalidation(true); |
1044 | 1044 |
1045 if (childToExclude == child) | 1045 if (childToExclude == child) |
1046 continue; // Skip this child, since it will be positioned by the spe
cialized subclass (fieldsets and ruby runs). | 1046 continue; // Skip this child, since it will be positioned by the spe
cialized subclass (fieldsets and ruby runs). |
1047 | 1047 |
1048 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child); | 1048 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *child); |
1049 | 1049 |
1050 if (child->isOutOfFlowPositioned()) { | 1050 if (child->isOutOfFlowPositioned()) { |
1051 child->containingBlock()->insertPositionedObject(child); | 1051 child->containingBlock()->insertPositionedObject(child); |
1052 adjustPositionedBlock(child, marginInfo); | 1052 adjustPositionedBlock(*child, marginInfo); |
1053 continue; | 1053 continue; |
1054 } | 1054 } |
1055 if (child->isFloating()) { | 1055 if (child->isFloating()) { |
1056 insertFloatingObject(child); | 1056 insertFloatingObject(*child); |
1057 adjustFloatingBlock(marginInfo); | 1057 adjustFloatingBlock(marginInfo); |
1058 continue; | 1058 continue; |
1059 } | 1059 } |
1060 | 1060 |
1061 // Lay out the child. | 1061 // Lay out the child. |
1062 layoutBlockChild(child, marginInfo, previousFloatLogicalBottom); | 1062 layoutBlockChild(*child, marginInfo, previousFloatLogicalBottom); |
1063 lastNormalFlowChild = child; | 1063 lastNormalFlowChild = child; |
1064 } | 1064 } |
1065 | 1065 |
1066 // Now do the handling of the bottom of the block, adding in our bottom bord
er/padding and | 1066 // Now do the handling of the bottom of the block, adding in our bottom bord
er/padding and |
1067 // determining the correct collapsed bottom margin information. | 1067 // determining the correct collapsed bottom margin information. |
1068 handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, marginInf
o); | 1068 handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, marginInf
o); |
1069 } | 1069 } |
1070 | 1070 |
1071 // Our MarginInfo state used when laying out block children. | 1071 // Our MarginInfo state used when laying out block children. |
1072 MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin
g, LayoutUnit afterBorderPadding) | 1072 MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin
g, LayoutUnit afterBorderPadding) |
(...skipping 19 matching lines...) Expand all Loading... |
1092 && (blockStyle->logicalHeight().isAuto() && !blockStyle->logicalHeight()
.value()) && blockStyle->marginAfterCollapse() != MSEPARATE; | 1092 && (blockStyle->logicalHeight().isAuto() && !blockStyle->logicalHeight()
.value()) && blockStyle->marginAfterCollapse() != MSEPARATE; |
1093 | 1093 |
1094 m_quirkContainer = blockFlow->isTableCell() || blockFlow->isBody(); | 1094 m_quirkContainer = blockFlow->isTableCell() || blockFlow->isBody(); |
1095 | 1095 |
1096 m_discardMargin = m_canCollapseMarginBeforeWithChildren && blockFlow->mustDi
scardMarginBefore(); | 1096 m_discardMargin = m_canCollapseMarginBeforeWithChildren && blockFlow->mustDi
scardMarginBefore(); |
1097 | 1097 |
1098 m_positiveMargin = (m_canCollapseMarginBeforeWithChildren && !blockFlow->mus
tDiscardMarginBefore()) ? blockFlow->maxPositiveMarginBefore() : LayoutUnit(); | 1098 m_positiveMargin = (m_canCollapseMarginBeforeWithChildren && !blockFlow->mus
tDiscardMarginBefore()) ? blockFlow->maxPositiveMarginBefore() : LayoutUnit(); |
1099 m_negativeMargin = (m_canCollapseMarginBeforeWithChildren && !blockFlow->mus
tDiscardMarginBefore()) ? blockFlow->maxNegativeMarginBefore() : LayoutUnit(); | 1099 m_negativeMargin = (m_canCollapseMarginBeforeWithChildren && !blockFlow->mus
tDiscardMarginBefore()) ? blockFlow->maxNegativeMarginBefore() : LayoutUnit(); |
1100 } | 1100 } |
1101 | 1101 |
1102 RenderBlockFlow::MarginValues RenderBlockFlow::marginValuesForChild(RenderBox* c
hild) const | 1102 RenderBlockFlow::MarginValues RenderBlockFlow::marginValuesForChild(RenderBox& c
hild) const |
1103 { | 1103 { |
1104 LayoutUnit childBeforePositive = 0; | 1104 LayoutUnit childBeforePositive = 0; |
1105 LayoutUnit childBeforeNegative = 0; | 1105 LayoutUnit childBeforeNegative = 0; |
1106 LayoutUnit childAfterPositive = 0; | 1106 LayoutUnit childAfterPositive = 0; |
1107 LayoutUnit childAfterNegative = 0; | 1107 LayoutUnit childAfterNegative = 0; |
1108 | 1108 |
1109 LayoutUnit beforeMargin = 0; | 1109 LayoutUnit beforeMargin = 0; |
1110 LayoutUnit afterMargin = 0; | 1110 LayoutUnit afterMargin = 0; |
1111 | 1111 |
1112 RenderBlockFlow* childRenderBlockFlow = child->isRenderBlockFlow() ? toRende
rBlockFlow(child) : 0; | 1112 RenderBlockFlow* childRenderBlockFlow = child.isRenderBlockFlow() ? toRender
BlockFlow(&child) : 0; |
1113 | 1113 |
1114 // If the child has the same directionality as we do, then we can just retur
n its | 1114 // If the child has the same directionality as we do, then we can just retur
n its |
1115 // margins in the same direction. | 1115 // margins in the same direction. |
1116 if (!child->isWritingModeRoot()) { | 1116 if (!child.isWritingModeRoot()) { |
1117 if (childRenderBlockFlow) { | 1117 if (childRenderBlockFlow) { |
1118 childBeforePositive = childRenderBlockFlow->maxPositiveMarginBefore(
); | 1118 childBeforePositive = childRenderBlockFlow->maxPositiveMarginBefore(
); |
1119 childBeforeNegative = childRenderBlockFlow->maxNegativeMarginBefore(
); | 1119 childBeforeNegative = childRenderBlockFlow->maxNegativeMarginBefore(
); |
1120 childAfterPositive = childRenderBlockFlow->maxPositiveMarginAfter(); | 1120 childAfterPositive = childRenderBlockFlow->maxPositiveMarginAfter(); |
1121 childAfterNegative = childRenderBlockFlow->maxNegativeMarginAfter(); | 1121 childAfterNegative = childRenderBlockFlow->maxNegativeMarginAfter(); |
1122 } else { | 1122 } else { |
1123 beforeMargin = child->marginBefore(); | 1123 beforeMargin = child.marginBefore(); |
1124 afterMargin = child->marginAfter(); | 1124 afterMargin = child.marginAfter(); |
1125 } | 1125 } |
1126 } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) { | 1126 } else if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) { |
1127 // The child has a different directionality. If the child is parallel, t
hen it's just | 1127 // The child has a different directionality. If the child is parallel, t
hen it's just |
1128 // flipped relative to us. We can use the margins for the opposite edges
. | 1128 // flipped relative to us. We can use the margins for the opposite edges
. |
1129 if (childRenderBlockFlow) { | 1129 if (childRenderBlockFlow) { |
1130 childBeforePositive = childRenderBlockFlow->maxPositiveMarginAfter()
; | 1130 childBeforePositive = childRenderBlockFlow->maxPositiveMarginAfter()
; |
1131 childBeforeNegative = childRenderBlockFlow->maxNegativeMarginAfter()
; | 1131 childBeforeNegative = childRenderBlockFlow->maxNegativeMarginAfter()
; |
1132 childAfterPositive = childRenderBlockFlow->maxPositiveMarginBefore()
; | 1132 childAfterPositive = childRenderBlockFlow->maxPositiveMarginBefore()
; |
1133 childAfterNegative = childRenderBlockFlow->maxNegativeMarginBefore()
; | 1133 childAfterNegative = childRenderBlockFlow->maxNegativeMarginBefore()
; |
1134 } else { | 1134 } else { |
1135 beforeMargin = child->marginAfter(); | 1135 beforeMargin = child.marginAfter(); |
1136 afterMargin = child->marginBefore(); | 1136 afterMargin = child.marginBefore(); |
1137 } | 1137 } |
1138 } else { | 1138 } else { |
1139 // The child is perpendicular to us, which means its margins don't colla
pse but are on the | 1139 // The child is perpendicular to us, which means its margins don't colla
pse but are on the |
1140 // "logical left/right" sides of the child box. We can just return the r
aw margin in this case. | 1140 // "logical left/right" sides of the child box. We can just return the r
aw margin in this case. |
1141 beforeMargin = marginBeforeForChild(child); | 1141 beforeMargin = marginBeforeForChild(child); |
1142 afterMargin = marginAfterForChild(child); | 1142 afterMargin = marginAfterForChild(child); |
1143 } | 1143 } |
1144 | 1144 |
1145 // Resolve uncollapsing margins into their positive/negative buckets. | 1145 // Resolve uncollapsing margins into their positive/negative buckets. |
1146 if (beforeMargin) { | 1146 if (beforeMargin) { |
1147 if (beforeMargin > 0) | 1147 if (beforeMargin > 0) |
1148 childBeforePositive = beforeMargin; | 1148 childBeforePositive = beforeMargin; |
1149 else | 1149 else |
1150 childBeforeNegative = -beforeMargin; | 1150 childBeforeNegative = -beforeMargin; |
1151 } | 1151 } |
1152 if (afterMargin) { | 1152 if (afterMargin) { |
1153 if (afterMargin > 0) | 1153 if (afterMargin > 0) |
1154 childAfterPositive = afterMargin; | 1154 childAfterPositive = afterMargin; |
1155 else | 1155 else |
1156 childAfterNegative = -afterMargin; | 1156 childAfterNegative = -afterMargin; |
1157 } | 1157 } |
1158 | 1158 |
1159 return RenderBlockFlow::MarginValues(childBeforePositive, childBeforeNegativ
e, childAfterPositive, childAfterNegative); | 1159 return RenderBlockFlow::MarginValues(childBeforePositive, childBeforeNegativ
e, childAfterPositive, childAfterNegative); |
1160 } | 1160 } |
1161 | 1161 |
1162 LayoutUnit RenderBlockFlow::collapseMargins(RenderBox* child, MarginInfo& margin
Info, bool childIsSelfCollapsing) | 1162 LayoutUnit RenderBlockFlow::collapseMargins(RenderBox& child, MarginInfo& margin
Info, bool childIsSelfCollapsing) |
1163 { | 1163 { |
1164 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); | 1164 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); |
1165 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); | 1165 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); |
1166 | 1166 |
1167 // The child discards the before margin when the the after margin has discar
d in the case of a self collapsing block. | 1167 // The child discards the before margin when the the after margin has discar
d in the case of a self collapsing block. |
1168 childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAf
ter && childIsSelfCollapsing); | 1168 childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAf
ter && childIsSelfCollapsing); |
1169 | 1169 |
1170 // Get the four margin values for the child and cache them. | 1170 // Get the four margin values for the child and cache them. |
1171 const RenderBlockFlow::MarginValues childMargins = marginValuesForChild(chil
d); | 1171 const RenderBlockFlow::MarginValues childMargins = marginValuesForChild(chil
d); |
1172 | 1172 |
1173 // Get our max pos and neg top margins. | 1173 // Get our max pos and neg top margins. |
1174 LayoutUnit posTop = childMargins.positiveMarginBefore(); | 1174 LayoutUnit posTop = childMargins.positiveMarginBefore(); |
1175 LayoutUnit negTop = childMargins.negativeMarginBefore(); | 1175 LayoutUnit negTop = childMargins.negativeMarginBefore(); |
1176 | 1176 |
1177 // For self-collapsing blocks, collapse our bottom margins into our | 1177 // For self-collapsing blocks, collapse our bottom margins into our |
1178 // top to get new posTop and negTop values. | 1178 // top to get new posTop and negTop values. |
1179 if (childIsSelfCollapsing) { | 1179 if (childIsSelfCollapsing) { |
1180 posTop = std::max(posTop, childMargins.positiveMarginAfter()); | 1180 posTop = std::max(posTop, childMargins.positiveMarginAfter()); |
1181 negTop = std::max(negTop, childMargins.negativeMarginAfter()); | 1181 negTop = std::max(negTop, childMargins.negativeMarginAfter()); |
1182 } | 1182 } |
1183 | 1183 |
1184 // See if the top margin is quirky. We only care if this child has | 1184 // See if the top margin is quirky. We only care if this child has |
1185 // margins that will collapse with us. | 1185 // margins that will collapse with us. |
1186 bool topQuirk = hasMarginBeforeQuirk(child); | 1186 bool topQuirk = hasMarginBeforeQuirk(&child); |
1187 | 1187 |
1188 if (marginInfo.canCollapseWithMarginBefore()) { | 1188 if (marginInfo.canCollapseWithMarginBefore()) { |
1189 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { | 1189 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { |
1190 // This child is collapsing with the top of the | 1190 // This child is collapsing with the top of the |
1191 // block. If it has larger margin values, then we need to update | 1191 // block. If it has larger margin values, then we need to update |
1192 // our own maximal values. | 1192 // our own maximal values. |
1193 if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !t
opQuirk) | 1193 if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !t
opQuirk) |
1194 setMaxMarginBeforeValues(std::max(posTop, maxPositiveMarginBefor
e()), std::max(negTop, maxNegativeMarginBefore())); | 1194 setMaxMarginBeforeValues(std::max(posTop, maxPositiveMarginBefor
e()), std::max(negTop, maxNegativeMarginBefore())); |
1195 | 1195 |
1196 // The minute any of the margins involved isn't a quirk, don't | 1196 // The minute any of the margins involved isn't a quirk, don't |
(...skipping 25 matching lines...) Expand all Loading... |
1222 marginInfo.clearMargin(); | 1222 marginInfo.clearMargin(); |
1223 } | 1223 } |
1224 | 1224 |
1225 if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posT
op - negTop)) | 1225 if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posT
op - negTop)) |
1226 marginInfo.setHasMarginBeforeQuirk(topQuirk); | 1226 marginInfo.setHasMarginBeforeQuirk(topQuirk); |
1227 | 1227 |
1228 LayoutUnit beforeCollapseLogicalTop = logicalHeight(); | 1228 LayoutUnit beforeCollapseLogicalTop = logicalHeight(); |
1229 LayoutUnit logicalTop = beforeCollapseLogicalTop; | 1229 LayoutUnit logicalTop = beforeCollapseLogicalTop; |
1230 | 1230 |
1231 LayoutUnit clearanceForSelfCollapsingBlock; | 1231 LayoutUnit clearanceForSelfCollapsingBlock; |
1232 RenderObject* prev = child->previousSibling(); | 1232 RenderObject* prev = child.previousSibling(); |
1233 RenderBlockFlow* previousBlockFlow = prev && prev->isRenderBlockFlow() && !
prev->isFloatingOrOutOfFlowPositioned() ? toRenderBlockFlow(prev) : 0; | 1233 RenderBlockFlow* previousBlockFlow = prev && prev->isRenderBlockFlow() && !
prev->isFloatingOrOutOfFlowPositioned() ? toRenderBlockFlow(prev) : 0; |
1234 // If the child's previous sibling is a self-collapsing block that cleared a
float then its top border edge has been set at the bottom border edge | 1234 // If the child's previous sibling is a self-collapsing block that cleared a
float then its top border edge has been set at the bottom border edge |
1235 // of the float. Since we want to collapse the child's top margin with the s
elf-collapsing block's top and bottom margins we need to adjust our parent's hei
ght to match the | 1235 // of the float. Since we want to collapse the child's top margin with the s
elf-collapsing block's top and bottom margins we need to adjust our parent's hei
ght to match the |
1236 // margin top of the self-collapsing block. If the resulting collapsed margi
n leaves the child still intruding into the float then we will want to clear it. | 1236 // margin top of the self-collapsing block. If the resulting collapsed margi
n leaves the child still intruding into the float then we will want to clear it. |
1237 if (!marginInfo.canCollapseWithMarginBefore() && previousBlockFlow && previo
usBlockFlow->isSelfCollapsingBlock()) { | 1237 if (!marginInfo.canCollapseWithMarginBefore() && previousBlockFlow && previo
usBlockFlow->isSelfCollapsingBlock()) { |
1238 clearanceForSelfCollapsingBlock = previousBlockFlow->marginOffsetForSelf
CollapsingBlock(); | 1238 clearanceForSelfCollapsingBlock = previousBlockFlow->marginOffsetForSelf
CollapsingBlock(); |
1239 setLogicalHeight(logicalHeight() - clearanceForSelfCollapsingBlock); | 1239 setLogicalHeight(logicalHeight() - clearanceForSelfCollapsingBlock); |
1240 } | 1240 } |
1241 | 1241 |
1242 if (childIsSelfCollapsing) { | 1242 if (childIsSelfCollapsing) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 marginInfo.setDiscardMargin(childDiscardMarginAfter); | 1284 marginInfo.setDiscardMargin(childDiscardMarginAfter); |
1285 | 1285 |
1286 if (!marginInfo.discardMargin()) { | 1286 if (!marginInfo.discardMargin()) { |
1287 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); | 1287 marginInfo.setPositiveMargin(childMargins.positiveMarginAfter()); |
1288 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); | 1288 marginInfo.setNegativeMargin(childMargins.negativeMarginAfter()); |
1289 } else { | 1289 } else { |
1290 marginInfo.clearMargin(); | 1290 marginInfo.clearMargin(); |
1291 } | 1291 } |
1292 | 1292 |
1293 if (marginInfo.margin()) | 1293 if (marginInfo.margin()) |
1294 marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(child)); | 1294 marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(&child)); |
1295 } | 1295 } |
1296 | 1296 |
1297 // If margins would pull us past the top of the next page, then we need to p
ull back and pretend like the margins | 1297 // If margins would pull us past the top of the next page, then we need to p
ull back and pretend like the margins |
1298 // collapsed into the page edge. | 1298 // collapsed into the page edge. |
1299 LayoutState* layoutState = view()->layoutState(); | 1299 LayoutState* layoutState = view()->layoutState(); |
1300 if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logica
lTop > beforeCollapseLogicalTop) { | 1300 if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logica
lTop > beforeCollapseLogicalTop) { |
1301 LayoutUnit oldLogicalTop = logicalTop; | 1301 LayoutUnit oldLogicalTop = logicalTop; |
1302 logicalTop = std::min(logicalTop, nextPageLogicalTop(beforeCollapseLogic
alTop)); | 1302 logicalTop = std::min(logicalTop, nextPageLogicalTop(beforeCollapseLogic
alTop)); |
1303 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); | 1303 setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); |
1304 } | 1304 } |
1305 | 1305 |
1306 if (previousBlockFlow) { | 1306 if (previousBlockFlow) { |
1307 // If |child| is a self-collapsing block it may have collapsed into a pr
evious sibling and although it hasn't reduced the height of the parent yet | 1307 // If |child| is a self-collapsing block it may have collapsed into a pr
evious sibling and although it hasn't reduced the height of the parent yet |
1308 // any floats from the parent will now overhang. | 1308 // any floats from the parent will now overhang. |
1309 LayoutUnit oldLogicalHeight = logicalHeight(); | 1309 LayoutUnit oldLogicalHeight = logicalHeight(); |
1310 setLogicalHeight(logicalTop); | 1310 setLogicalHeight(logicalTop); |
1311 if (!previousBlockFlow->avoidsFloats() && (previousBlockFlow->logicalTop
() + previousBlockFlow->lowestFloatLogicalBottom()) > logicalTop) | 1311 if (!previousBlockFlow->avoidsFloats() && (previousBlockFlow->logicalTop
() + previousBlockFlow->lowestFloatLogicalBottom()) > logicalTop) |
1312 addOverhangingFloats(previousBlockFlow, false); | 1312 addOverhangingFloats(previousBlockFlow, false); |
1313 setLogicalHeight(oldLogicalHeight); | 1313 setLogicalHeight(oldLogicalHeight); |
1314 | 1314 |
1315 // If |child|'s previous sibling is a self-collapsing block that cleared
a float and margin collapsing resulted in |child| moving up | 1315 // If |child|'s previous sibling is a self-collapsing block that cleared
a float and margin collapsing resulted in |child| moving up |
1316 // into the margin area of the self-collapsing block then the float it c
lears is now intruding into |child|. Layout again so that we can look for | 1316 // into the margin area of the self-collapsing block then the float it c
lears is now intruding into |child|. Layout again so that we can look for |
1317 // floats in the parent that overhang |child|'s new logical top. | 1317 // floats in the parent that overhang |child|'s new logical top. |
1318 bool logicalTopIntrudesIntoFloat = clearanceForSelfCollapsingBlock > 0 &
& logicalTop < beforeCollapseLogicalTop; | 1318 bool logicalTopIntrudesIntoFloat = clearanceForSelfCollapsingBlock > 0 &
& logicalTop < beforeCollapseLogicalTop; |
1319 if (logicalTopIntrudesIntoFloat && containsFloats() && !child->avoidsFlo
ats() && lowestFloatLogicalBottom() > logicalTop) | 1319 if (logicalTopIntrudesIntoFloat && containsFloats() && !child.avoidsFloa
ts() && lowestFloatLogicalBottom() > logicalTop) |
1320 child->setNeedsLayoutAndFullPaintInvalidation(); | 1320 child.setNeedsLayoutAndFullPaintInvalidation(); |
1321 } | 1321 } |
1322 | 1322 |
1323 return logicalTop; | 1323 return logicalTop; |
1324 } | 1324 } |
1325 | 1325 |
1326 void RenderBlockFlow::adjustPositionedBlock(RenderBox* child, const MarginInfo&
marginInfo) | 1326 void RenderBlockFlow::adjustPositionedBlock(RenderBox& child, const MarginInfo&
marginInfo) |
1327 { | 1327 { |
1328 bool isHorizontal = isHorizontalWritingMode(); | 1328 bool isHorizontal = isHorizontalWritingMode(); |
1329 bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHoriz
ontal); | 1329 bool hasStaticBlockPosition = child.style()->hasStaticBlockPosition(isHorizo
ntal); |
1330 | 1330 |
1331 LayoutUnit logicalTop = logicalHeight(); | 1331 LayoutUnit logicalTop = logicalHeight(); |
1332 updateStaticInlinePositionForChild(child, logicalTop); | 1332 updateStaticInlinePositionForChild(child, logicalTop); |
1333 | 1333 |
1334 if (!marginInfo.canCollapseWithMarginBefore()) { | 1334 if (!marginInfo.canCollapseWithMarginBefore()) { |
1335 // Positioned blocks don't collapse margins, so add the margin provided
by | 1335 // Positioned blocks don't collapse margins, so add the margin provided
by |
1336 // the container now. The child's own margin is added later when calcula
ting its logical top. | 1336 // the container now. The child's own margin is added later when calcula
ting its logical top. |
1337 LayoutUnit collapsedBeforePos = marginInfo.positiveMargin(); | 1337 LayoutUnit collapsedBeforePos = marginInfo.positiveMargin(); |
1338 LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin(); | 1338 LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin(); |
1339 logicalTop += collapsedBeforePos - collapsedBeforeNeg; | 1339 logicalTop += collapsedBeforePos - collapsedBeforeNeg; |
1340 } | 1340 } |
1341 | 1341 |
1342 RenderLayer* childLayer = child->layer(); | 1342 RenderLayer* childLayer = child.layer(); |
1343 if (childLayer->staticBlockPosition() != logicalTop) { | 1343 if (childLayer->staticBlockPosition() != logicalTop) { |
1344 childLayer->setStaticBlockPosition(logicalTop); | 1344 childLayer->setStaticBlockPosition(logicalTop); |
1345 if (hasStaticBlockPosition) | 1345 if (hasStaticBlockPosition) |
1346 child->setChildNeedsLayout(MarkOnlyThis); | 1346 child.setChildNeedsLayout(MarkOnlyThis); |
1347 } | 1347 } |
1348 } | 1348 } |
1349 | 1349 |
1350 LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox* child, MarginInfo& ma
rginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPo
s, bool childIsSelfCollapsing) | 1350 LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox& child, MarginInfo& ma
rginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPo
s, bool childIsSelfCollapsing) |
1351 { | 1351 { |
1352 LayoutUnit heightIncrease = getClearDelta(child, yPos); | 1352 LayoutUnit heightIncrease = getClearDelta(&child, yPos); |
1353 if (!heightIncrease) | 1353 if (!heightIncrease) |
1354 return yPos; | 1354 return yPos; |
1355 | 1355 |
1356 if (childIsSelfCollapsing) { | 1356 if (childIsSelfCollapsing) { |
1357 bool childDiscardMargin = mustDiscardMarginBeforeForChild(child) || must
DiscardMarginAfterForChild(child); | 1357 bool childDiscardMargin = mustDiscardMarginBeforeForChild(child) || must
DiscardMarginAfterForChild(child); |
1358 | 1358 |
1359 // For self-collapsing blocks that clear, they can still collapse their | 1359 // For self-collapsing blocks that clear, they can still collapse their |
1360 // margins with following siblings. Reset the current margins to represe
nt | 1360 // margins with following siblings. Reset the current margins to represe
nt |
1361 // the self-collapsing block's margins only. | 1361 // the self-collapsing block's margins only. |
1362 // If DISCARD is specified for -webkit-margin-collapse, reset the margin
values. | 1362 // If DISCARD is specified for -webkit-margin-collapse, reset the margin
values. |
(...skipping 13 matching lines...) Expand all Loading... |
1376 // this happens; it will get reset if we encounter an in-flow sibling th
at is not self-collapsing. | 1376 // this happens; it will get reset if we encounter an in-flow sibling th
at is not self-collapsing. |
1377 marginInfo.setCanCollapseMarginAfterWithLastChild(false); | 1377 marginInfo.setCanCollapseMarginAfterWithLastChild(false); |
1378 | 1378 |
1379 // For now set the border-top of |child| flush with the bottom border-ed
ge of the float so it can layout any floating or positioned children of | 1379 // For now set the border-top of |child| flush with the bottom border-ed
ge of the float so it can layout any floating or positioned children of |
1380 // its own at the correct vertical position. If subsequent siblings atte
mpt to collapse with |child|'s margins in |collapseMargins| we will | 1380 // its own at the correct vertical position. If subsequent siblings atte
mpt to collapse with |child|'s margins in |collapseMargins| we will |
1381 // adjust the height of the parent to |child|'s margin top (which if it
is positive sits up 'inside' the float it's clearing) so that all three | 1381 // adjust the height of the parent to |child|'s margin top (which if it
is positive sits up 'inside' the float it's clearing) so that all three |
1382 // margins can collapse at the correct vertical position. | 1382 // margins can collapse at the correct vertical position. |
1383 // Per CSS2.1 we need to ensure that any negative margin-top clears |chi
ld| beyond the bottom border-edge of the float so that the top border edge of th
e child | 1383 // Per CSS2.1 we need to ensure that any negative margin-top clears |chi
ld| beyond the bottom border-edge of the float so that the top border edge of th
e child |
1384 // (i.e. its clearance) is at a position that satisfies the equation: "
the amount of clearance is set so that clearance + margin-top = [height of float
], | 1384 // (i.e. its clearance) is at a position that satisfies the equation: "
the amount of clearance is set so that clearance + margin-top = [height of float
], |
1385 // i.e., clearance = [height of float] - margin-top". | 1385 // i.e., clearance = [height of float] - margin-top". |
1386 setLogicalHeight(child->logicalTop() + childMargins.negativeMarginBefore
()); | 1386 setLogicalHeight(child.logicalTop() + childMargins.negativeMarginBefore(
)); |
1387 } else { | 1387 } else { |
1388 // Increase our height by the amount we had to clear. | 1388 // Increase our height by the amount we had to clear. |
1389 setLogicalHeight(logicalHeight() + heightIncrease); | 1389 setLogicalHeight(logicalHeight() + heightIncrease); |
1390 } | 1390 } |
1391 | 1391 |
1392 if (marginInfo.canCollapseWithMarginBefore()) { | 1392 if (marginInfo.canCollapseWithMarginBefore()) { |
1393 // We can no longer collapse with the top of the block since a clear | 1393 // We can no longer collapse with the top of the block since a clear |
1394 // occurred. The empty blocks collapse into the cleared block. | 1394 // occurred. The empty blocks collapse into the cleared block. |
1395 setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin); | 1395 setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin); |
1396 marginInfo.setAtBeforeSideOfBlock(false); | 1396 marginInfo.setAtBeforeSideOfBlock(false); |
(...skipping 24 matching lines...) Expand all Loading... |
1421 | 1421 |
1422 if (marginInfo.hasMarginAfterQuirk() && !marginAfter()) { | 1422 if (marginInfo.hasMarginAfterQuirk() && !marginAfter()) { |
1423 // We have no bottom margin and our last child has a quirky margin. | 1423 // We have no bottom margin and our last child has a quirky margin. |
1424 // We will pick up this quirky margin and pass it through. | 1424 // We will pick up this quirky margin and pass it through. |
1425 // This deals with the <td><div><p> case. | 1425 // This deals with the <td><div><p> case. |
1426 setHasMarginAfterQuirk(true); | 1426 setHasMarginAfterQuirk(true); |
1427 } | 1427 } |
1428 } | 1428 } |
1429 } | 1429 } |
1430 | 1430 |
1431 void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox* child, LayoutUnit&
positiveMarginBefore, LayoutUnit& negativeMarginBefore, bool& discardMarginBefo
re) const | 1431 void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox& child, LayoutUnit&
positiveMarginBefore, LayoutUnit& negativeMarginBefore, bool& discardMarginBefo
re) const |
1432 { | 1432 { |
1433 // Give up if in quirks mode and we're a body/table cell and the top margin
of the child box is quirky. | 1433 // Give up if in quirks mode and we're a body/table cell and the top margin
of the child box is quirky. |
1434 // Give up if the child specified -webkit-margin-collapse: separate that pre
vents collapsing. | 1434 // Give up if the child specified -webkit-margin-collapse: separate that pre
vents collapsing. |
1435 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. | 1435 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. |
1436 if ((document().inQuirksMode() && hasMarginBeforeQuirk(child) && (isTableCel
l() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE) | 1436 if ((document().inQuirksMode() && hasMarginBeforeQuirk(&child) && (isTableCe
ll() || isBody())) || child.style()->marginBeforeCollapse() == MSEPARATE) |
1437 return; | 1437 return; |
1438 | 1438 |
1439 // The margins are discarded by a child that specified -webkit-margin-collap
se: discard. | 1439 // The margins are discarded by a child that specified -webkit-margin-collap
se: discard. |
1440 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. | 1440 // FIXME: Use writing mode independent accessor for marginBeforeCollapse. |
1441 if (child->style()->marginBeforeCollapse() == MDISCARD) { | 1441 if (child.style()->marginBeforeCollapse() == MDISCARD) { |
1442 positiveMarginBefore = 0; | 1442 positiveMarginBefore = 0; |
1443 negativeMarginBefore = 0; | 1443 negativeMarginBefore = 0; |
1444 discardMarginBefore = true; | 1444 discardMarginBefore = true; |
1445 return; | 1445 return; |
1446 } | 1446 } |
1447 | 1447 |
1448 LayoutUnit beforeChildMargin = marginBeforeForChild(child); | 1448 LayoutUnit beforeChildMargin = marginBeforeForChild(child); |
1449 positiveMarginBefore = std::max(positiveMarginBefore, beforeChildMargin); | 1449 positiveMarginBefore = std::max(positiveMarginBefore, beforeChildMargin); |
1450 negativeMarginBefore = std::max(negativeMarginBefore, -beforeChildMargin); | 1450 negativeMarginBefore = std::max(negativeMarginBefore, -beforeChildMargin); |
1451 | 1451 |
1452 if (!child->isRenderBlockFlow()) | 1452 if (!child.isRenderBlockFlow()) |
1453 return; | 1453 return; |
1454 | 1454 |
1455 RenderBlockFlow* childBlockFlow = toRenderBlockFlow(child); | 1455 RenderBlockFlow* childBlockFlow = toRenderBlockFlow(&child); |
1456 if (childBlockFlow->childrenInline() || childBlockFlow->isWritingModeRoot()) | 1456 if (childBlockFlow->childrenInline() || childBlockFlow->isWritingModeRoot()) |
1457 return; | 1457 return; |
1458 | 1458 |
1459 MarginInfo childMarginInfo(childBlockFlow, childBlockFlow->borderBefore() +
childBlockFlow->paddingBefore(), childBlockFlow->borderAfter() + childBlockFlow-
>paddingAfter()); | 1459 MarginInfo childMarginInfo(childBlockFlow, childBlockFlow->borderBefore() +
childBlockFlow->paddingBefore(), childBlockFlow->borderAfter() + childBlockFlow-
>paddingAfter()); |
1460 if (!childMarginInfo.canCollapseMarginBeforeWithChildren()) | 1460 if (!childMarginInfo.canCollapseMarginBeforeWithChildren()) |
1461 return; | 1461 return; |
1462 | 1462 |
1463 RenderBox* grandchildBox = childBlockFlow->firstChildBox(); | 1463 RenderBox* grandchildBox = childBlockFlow->firstChildBox(); |
1464 for ( ; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) { | 1464 for ( ; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) { |
1465 if (!grandchildBox->isFloatingOrOutOfFlowPositioned()) | 1465 if (!grandchildBox->isFloatingOrOutOfFlowPositioned()) |
1466 break; | 1466 break; |
1467 } | 1467 } |
1468 | 1468 |
1469 if (!grandchildBox) | 1469 if (!grandchildBox) |
1470 return; | 1470 return; |
1471 | 1471 |
1472 // Make sure to update the block margins now for the grandchild box so that
we're looking at current values. | 1472 // Make sure to update the block margins now for the grandchild box so that
we're looking at current values. |
1473 if (grandchildBox->needsLayout()) { | 1473 if (grandchildBox->needsLayout()) { |
1474 grandchildBox->computeAndSetBlockDirectionMargins(this); | 1474 grandchildBox->computeAndSetBlockDirectionMargins(this); |
1475 if (grandchildBox->isRenderBlock()) { | 1475 if (grandchildBox->isRenderBlock()) { |
1476 RenderBlock* grandchildBlock = toRenderBlock(grandchildBox); | 1476 RenderBlock* grandchildBlock = toRenderBlock(grandchildBox); |
1477 grandchildBlock->setHasMarginBeforeQuirk(grandchildBox->style()->has
MarginBeforeQuirk()); | 1477 grandchildBlock->setHasMarginBeforeQuirk(grandchildBox->style()->has
MarginBeforeQuirk()); |
1478 grandchildBlock->setHasMarginAfterQuirk(grandchildBox->style()->hasM
arginAfterQuirk()); | 1478 grandchildBlock->setHasMarginAfterQuirk(grandchildBox->style()->hasM
arginAfterQuirk()); |
1479 } | 1479 } |
1480 } | 1480 } |
1481 | 1481 |
1482 // If we have a 'clear' value but also have a margin we may not actually req
uire clearance to move past any floats. | 1482 // If we have a 'clear' value but also have a margin we may not actually req
uire clearance to move past any floats. |
1483 // If that's the case we want to be sure we estimate the correct position in
cluding margins after any floats rather | 1483 // If that's the case we want to be sure we estimate the correct position in
cluding margins after any floats rather |
1484 // than use 'clearance' later which could give us the wrong position. | 1484 // than use 'clearance' later which could give us the wrong position. |
1485 if (grandchildBox->style()->clear() != CNONE && childBlockFlow->marginBefore
ForChild(grandchildBox) == 0) | 1485 if (grandchildBox->style()->clear() != CNONE && childBlockFlow->marginBefore
ForChild(*grandchildBox) == 0) |
1486 return; | 1486 return; |
1487 | 1487 |
1488 // Collapse the margin of the grandchild box with our own to produce an esti
mate. | 1488 // Collapse the margin of the grandchild box with our own to produce an esti
mate. |
1489 childBlockFlow->marginBeforeEstimateForChild(grandchildBox, positiveMarginBe
fore, negativeMarginBefore, discardMarginBefore); | 1489 childBlockFlow->marginBeforeEstimateForChild(*grandchildBox, positiveMarginB
efore, negativeMarginBefore, discardMarginBefore); |
1490 } | 1490 } |
1491 | 1491 |
1492 LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox* child, const M
arginInfo& marginInfo, LayoutUnit& estimateWithoutPagination) | 1492 LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox& child, const M
arginInfo& marginInfo, LayoutUnit& estimateWithoutPagination) |
1493 { | 1493 { |
1494 // FIXME: We need to eliminate the estimation of vertical position, because
when it's wrong we sometimes trigger a pathological | 1494 // FIXME: We need to eliminate the estimation of vertical position, because
when it's wrong we sometimes trigger a pathological |
1495 // relayout if there are intruding floats. | 1495 // relayout if there are intruding floats. |
1496 LayoutUnit logicalTopEstimate = logicalHeight(); | 1496 LayoutUnit logicalTopEstimate = logicalHeight(); |
1497 if (!marginInfo.canCollapseWithMarginBefore()) { | 1497 if (!marginInfo.canCollapseWithMarginBefore()) { |
1498 LayoutUnit positiveMarginBefore = 0; | 1498 LayoutUnit positiveMarginBefore = 0; |
1499 LayoutUnit negativeMarginBefore = 0; | 1499 LayoutUnit negativeMarginBefore = 0; |
1500 bool discardMarginBefore = false; | 1500 bool discardMarginBefore = false; |
1501 if (child->selfNeedsLayout()) { | 1501 if (child.selfNeedsLayout()) { |
1502 // Try to do a basic estimation of how the collapse is going to go. | 1502 // Try to do a basic estimation of how the collapse is going to go. |
1503 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMa
rginBefore, discardMarginBefore); | 1503 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMa
rginBefore, discardMarginBefore); |
1504 } else { | 1504 } else { |
1505 // Use the cached collapsed margin values from a previous layout. Mo
st of the time they | 1505 // Use the cached collapsed margin values from a previous layout. Mo
st of the time they |
1506 // will be right. | 1506 // will be right. |
1507 RenderBlockFlow::MarginValues marginValues = marginValuesForChild(ch
ild); | 1507 RenderBlockFlow::MarginValues marginValues = marginValuesForChild(ch
ild); |
1508 positiveMarginBefore = std::max(positiveMarginBefore, marginValues.p
ositiveMarginBefore()); | 1508 positiveMarginBefore = std::max(positiveMarginBefore, marginValues.p
ositiveMarginBefore()); |
1509 negativeMarginBefore = std::max(negativeMarginBefore, marginValues.n
egativeMarginBefore()); | 1509 negativeMarginBefore = std::max(negativeMarginBefore, marginValues.n
egativeMarginBefore()); |
1510 discardMarginBefore = mustDiscardMarginBeforeForChild(child); | 1510 discardMarginBefore = mustDiscardMarginBeforeForChild(child); |
1511 } | 1511 } |
1512 | 1512 |
1513 // Collapse the result with our current margins. | 1513 // Collapse the result with our current margins. |
1514 if (!discardMarginBefore) | 1514 if (!discardMarginBefore) |
1515 logicalTopEstimate += std::max(marginInfo.positiveMargin(), positive
MarginBefore) - std::max(marginInfo.negativeMargin(), negativeMarginBefore); | 1515 logicalTopEstimate += std::max(marginInfo.positiveMargin(), positive
MarginBefore) - std::max(marginInfo.negativeMargin(), negativeMarginBefore); |
1516 } | 1516 } |
1517 | 1517 |
1518 // Adjust logicalTopEstimate down to the next page if the margins are so lar
ge that we don't fit on the current | 1518 // Adjust logicalTopEstimate down to the next page if the margins are so lar
ge that we don't fit on the current |
1519 // page. | 1519 // page. |
1520 LayoutState* layoutState = view()->layoutState(); | 1520 LayoutState* layoutState = view()->layoutState(); |
1521 if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logica
lTopEstimate > logicalHeight()) | 1521 if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logica
lTopEstimate > logicalHeight()) |
1522 logicalTopEstimate = std::min(logicalTopEstimate, nextPageLogicalTop(log
icalHeight())); | 1522 logicalTopEstimate = std::min(logicalTopEstimate, nextPageLogicalTop(log
icalHeight())); |
1523 | 1523 |
1524 logicalTopEstimate += getClearDelta(child, logicalTopEstimate); | 1524 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); |
1525 | 1525 |
1526 estimateWithoutPagination = logicalTopEstimate; | 1526 estimateWithoutPagination = logicalTopEstimate; |
1527 | 1527 |
1528 if (layoutState->isPaginated()) { | 1528 if (layoutState->isPaginated()) { |
1529 // If the object has a page or column break value of "before", then we s
hould shift to the top of the next page. | 1529 // If the object has a page or column break value of "before", then we s
hould shift to the top of the next page. |
1530 logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate); | 1530 logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate); |
1531 | 1531 |
1532 // For replaced elements and scrolled elements, we want to shift them to
the next page if they don't fit on the current one. | 1532 // For replaced elements and scrolled elements, we want to shift them to
the next page if they don't fit on the current one. |
1533 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimat
e); | 1533 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimat
e); |
1534 | 1534 |
1535 if (!child->selfNeedsLayout() && child->isRenderBlockFlow()) | 1535 if (!child.selfNeedsLayout() && child.isRenderBlockFlow()) |
1536 logicalTopEstimate += toRenderBlockFlow(child)->paginationStrut(); | 1536 logicalTopEstimate += toRenderBlockFlow(&child)->paginationStrut(); |
1537 } | 1537 } |
1538 | 1538 |
1539 return logicalTopEstimate; | 1539 return logicalTopEstimate; |
1540 } | 1540 } |
1541 | 1541 |
1542 LayoutUnit RenderBlockFlow::marginOffsetForSelfCollapsingBlock() | 1542 LayoutUnit RenderBlockFlow::marginOffsetForSelfCollapsingBlock() |
1543 { | 1543 { |
1544 ASSERT(isSelfCollapsingBlock()); | 1544 ASSERT(isSelfCollapsingBlock()); |
1545 RenderBlockFlow* parentBlock = toRenderBlockFlow(parent()); | 1545 RenderBlockFlow* parentBlock = toRenderBlockFlow(parent()); |
1546 if (parentBlock && style()->clear() && parentBlock->getClearDelta(this, logi
calHeight())) | 1546 if (parentBlock && style()->clear() && parentBlock->getClearDelta(this, logi
calHeight())) |
1547 return marginValuesForChild(this).positiveMarginBefore(); | 1547 return marginValuesForChild(*this).positiveMarginBefore(); |
1548 return LayoutUnit(); | 1548 return LayoutUnit(); |
1549 } | 1549 } |
1550 | 1550 |
1551 void RenderBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) | 1551 void RenderBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) |
1552 { | 1552 { |
1553 // The float should be positioned taking into account the bottom margin | 1553 // The float should be positioned taking into account the bottom margin |
1554 // of the previous flow. We add that margin into the height, get the | 1554 // of the previous flow. We add that margin into the height, get the |
1555 // float positioned properly, and then subtract the margin out of the | 1555 // float positioned properly, and then subtract the margin out of the |
1556 // height again. In the case of self-collapsing blocks, we always just | 1556 // height again. In the case of self-collapsing blocks, we always just |
1557 // use the top margins, since the self-collapsing block collapsed its | 1557 // use the top margins, since the self-collapsing block collapsed its |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 bool RenderBlockFlow::mustDiscardMarginBefore() const | 1633 bool RenderBlockFlow::mustDiscardMarginBefore() const |
1634 { | 1634 { |
1635 return style()->marginBeforeCollapse() == MDISCARD || (m_rareData && m_rareD
ata->m_discardMarginBefore); | 1635 return style()->marginBeforeCollapse() == MDISCARD || (m_rareData && m_rareD
ata->m_discardMarginBefore); |
1636 } | 1636 } |
1637 | 1637 |
1638 bool RenderBlockFlow::mustDiscardMarginAfter() const | 1638 bool RenderBlockFlow::mustDiscardMarginAfter() const |
1639 { | 1639 { |
1640 return style()->marginAfterCollapse() == MDISCARD || (m_rareData && m_rareDa
ta->m_discardMarginAfter); | 1640 return style()->marginAfterCollapse() == MDISCARD || (m_rareData && m_rareDa
ta->m_discardMarginAfter); |
1641 } | 1641 } |
1642 | 1642 |
1643 bool RenderBlockFlow::mustDiscardMarginBeforeForChild(const RenderBox* child) co
nst | 1643 bool RenderBlockFlow::mustDiscardMarginBeforeForChild(const RenderBox& child) co
nst |
1644 { | 1644 { |
1645 ASSERT(!child->selfNeedsLayout()); | 1645 ASSERT(!child.selfNeedsLayout()); |
1646 if (!child->isWritingModeRoot()) | 1646 if (!child.isWritingModeRoot()) |
1647 return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscar
dMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD); | 1647 return child.isRenderBlockFlow() ? toRenderBlockFlow(&child)->mustDiscar
dMarginBefore() : (child.style()->marginBeforeCollapse() == MDISCARD); |
1648 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 1648 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
1649 return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscar
dMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD); | 1649 return child.isRenderBlockFlow() ? toRenderBlockFlow(&child)->mustDiscar
dMarginAfter() : (child.style()->marginAfterCollapse() == MDISCARD); |
1650 | 1650 |
1651 // FIXME: We return false here because the implementation is not geometrical
ly complete. We have values only for before/after, not start/end. | 1651 // FIXME: We return false here because the implementation is not geometrical
ly complete. We have values only for before/after, not start/end. |
1652 // In case the boxes are perpendicular we assume the property is not specifi
ed. | 1652 // In case the boxes are perpendicular we assume the property is not specifi
ed. |
1653 return false; | 1653 return false; |
1654 } | 1654 } |
1655 | 1655 |
1656 bool RenderBlockFlow::mustDiscardMarginAfterForChild(const RenderBox* child) con
st | 1656 bool RenderBlockFlow::mustDiscardMarginAfterForChild(const RenderBox& child) con
st |
1657 { | 1657 { |
1658 ASSERT(!child->selfNeedsLayout()); | 1658 ASSERT(!child.selfNeedsLayout()); |
1659 if (!child->isWritingModeRoot()) | 1659 if (!child.isWritingModeRoot()) |
1660 return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscar
dMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD); | 1660 return child.isRenderBlockFlow() ? toRenderBlockFlow(&child)->mustDiscar
dMarginAfter() : (child.style()->marginAfterCollapse() == MDISCARD); |
1661 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 1661 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
1662 return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscar
dMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD); | 1662 return child.isRenderBlockFlow() ? toRenderBlockFlow(&child)->mustDiscar
dMarginBefore() : (child.style()->marginBeforeCollapse() == MDISCARD); |
1663 | 1663 |
1664 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 1664 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
1665 return false; | 1665 return false; |
1666 } | 1666 } |
1667 | 1667 |
1668 void RenderBlockFlow::setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg) | 1668 void RenderBlockFlow::setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg) |
1669 { | 1669 { |
1670 if (!m_rareData) { | 1670 if (!m_rareData) { |
1671 if (pos == RenderBlockFlowRareData::positiveMarginBeforeDefault(this) &&
neg == RenderBlockFlowRareData::negativeMarginBeforeDefault(this)) | 1671 if (pos == RenderBlockFlowRareData::positiveMarginBeforeDefault(this) &&
neg == RenderBlockFlowRareData::negativeMarginBeforeDefault(this)) |
1672 return; | 1672 return; |
1673 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this)); | 1673 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this)); |
1674 } | 1674 } |
1675 m_rareData->m_margins.setPositiveMarginBefore(pos); | 1675 m_rareData->m_margins.setPositiveMarginBefore(pos); |
1676 m_rareData->m_margins.setNegativeMarginBefore(neg); | 1676 m_rareData->m_margins.setNegativeMarginBefore(neg); |
1677 } | 1677 } |
1678 | 1678 |
1679 void RenderBlockFlow::setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg) | 1679 void RenderBlockFlow::setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg) |
1680 { | 1680 { |
1681 if (!m_rareData) { | 1681 if (!m_rareData) { |
1682 if (pos == RenderBlockFlowRareData::positiveMarginAfterDefault(this) &&
neg == RenderBlockFlowRareData::negativeMarginAfterDefault(this)) | 1682 if (pos == RenderBlockFlowRareData::positiveMarginAfterDefault(this) &&
neg == RenderBlockFlowRareData::negativeMarginAfterDefault(this)) |
1683 return; | 1683 return; |
1684 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this)); | 1684 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this)); |
1685 } | 1685 } |
1686 m_rareData->m_margins.setPositiveMarginAfter(pos); | 1686 m_rareData->m_margins.setPositiveMarginAfter(pos); |
1687 m_rareData->m_margins.setNegativeMarginAfter(neg); | 1687 m_rareData->m_margins.setNegativeMarginAfter(neg); |
1688 } | 1688 } |
1689 | 1689 |
1690 bool RenderBlockFlow::mustSeparateMarginBeforeForChild(const RenderBox* child) c
onst | 1690 bool RenderBlockFlow::mustSeparateMarginBeforeForChild(const RenderBox& child) c
onst |
1691 { | 1691 { |
1692 ASSERT(!child->selfNeedsLayout()); | 1692 ASSERT(!child.selfNeedsLayout()); |
1693 const RenderStyle* childStyle = child->style(); | 1693 const RenderStyle* childStyle = child.style(); |
1694 if (!child->isWritingModeRoot()) | 1694 if (!child.isWritingModeRoot()) |
1695 return childStyle->marginBeforeCollapse() == MSEPARATE; | 1695 return childStyle->marginBeforeCollapse() == MSEPARATE; |
1696 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 1696 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
1697 return childStyle->marginAfterCollapse() == MSEPARATE; | 1697 return childStyle->marginAfterCollapse() == MSEPARATE; |
1698 | 1698 |
1699 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 1699 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
1700 return false; | 1700 return false; |
1701 } | 1701 } |
1702 | 1702 |
1703 bool RenderBlockFlow::mustSeparateMarginAfterForChild(const RenderBox* child) co
nst | 1703 bool RenderBlockFlow::mustSeparateMarginAfterForChild(const RenderBox& child) co
nst |
1704 { | 1704 { |
1705 ASSERT(!child->selfNeedsLayout()); | 1705 ASSERT(!child.selfNeedsLayout()); |
1706 const RenderStyle* childStyle = child->style(); | 1706 const RenderStyle* childStyle = child.style(); |
1707 if (!child->isWritingModeRoot()) | 1707 if (!child.isWritingModeRoot()) |
1708 return childStyle->marginAfterCollapse() == MSEPARATE; | 1708 return childStyle->marginAfterCollapse() == MSEPARATE; |
1709 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 1709 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
1710 return childStyle->marginBeforeCollapse() == MSEPARATE; | 1710 return childStyle->marginBeforeCollapse() == MSEPARATE; |
1711 | 1711 |
1712 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 1712 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
1713 return false; | 1713 return false; |
1714 } | 1714 } |
1715 | 1715 |
1716 LayoutUnit RenderBlockFlow::applyBeforeBreak(RenderBox* child, LayoutUnit logica
lOffset) | 1716 LayoutUnit RenderBlockFlow::applyBeforeBreak(RenderBox& child, LayoutUnit logica
lOffset) |
1717 { | 1717 { |
1718 // FIXME: Add page break checking here when we support printing. | 1718 // FIXME: Add page break checking here when we support printing. |
1719 RenderFlowThread* flowThread = flowThreadContainingBlock(); | 1719 RenderFlowThread* flowThread = flowThreadContainingBlock(); |
1720 bool isInsideMulticolFlowThread = flowThread; | 1720 bool isInsideMulticolFlowThread = flowThread; |
1721 bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()
->isPaginatingColumns(); | 1721 bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()
->isPaginatingColumns(); |
1722 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. | 1722 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. |
1723 bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBe
fore() == PBALWAYS) | 1723 bool checkBeforeAlways = (checkColumnBreaks && child.style()->columnBreakBef
ore() == PBALWAYS) |
1724 || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS); | 1724 || (checkPageBreaks && child.style()->pageBreakBefore() == PBALWAYS); |
1725 if (checkBeforeAlways && inNormalFlow(child)) { | 1725 if (checkBeforeAlways && inNormalFlow(&child)) { |
1726 if (checkColumnBreaks) { | 1726 if (checkColumnBreaks) { |
1727 if (isInsideMulticolFlowThread) { | 1727 if (isInsideMulticolFlowThread) { |
1728 LayoutUnit offsetBreakAdjustment = 0; | 1728 LayoutUnit offsetBreakAdjustment = 0; |
1729 if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirst
Page() + logicalOffset, child, true, &offsetBreakAdjustment)) | 1729 if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirst
Page() + logicalOffset, &child, true, &offsetBreakAdjustment)) |
1730 return logicalOffset + offsetBreakAdjustment; | 1730 return logicalOffset + offsetBreakAdjustment; |
1731 } else { | 1731 } else { |
1732 view()->layoutState()->addForcedColumnBreak(*child, logicalOffse
t); | 1732 view()->layoutState()->addForcedColumnBreak(child, logicalOffset
); |
1733 } | 1733 } |
1734 } | 1734 } |
1735 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); | 1735 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); |
1736 } | 1736 } |
1737 return logicalOffset; | 1737 return logicalOffset; |
1738 } | 1738 } |
1739 | 1739 |
1740 LayoutUnit RenderBlockFlow::applyAfterBreak(RenderBox* child, LayoutUnit logical
Offset, MarginInfo& marginInfo) | 1740 LayoutUnit RenderBlockFlow::applyAfterBreak(RenderBox& child, LayoutUnit logical
Offset, MarginInfo& marginInfo) |
1741 { | 1741 { |
1742 // FIXME: Add page break checking here when we support printing. | 1742 // FIXME: Add page break checking here when we support printing. |
1743 RenderFlowThread* flowThread = flowThreadContainingBlock(); | 1743 RenderFlowThread* flowThread = flowThreadContainingBlock(); |
1744 bool isInsideMulticolFlowThread = flowThread; | 1744 bool isInsideMulticolFlowThread = flowThread; |
1745 bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()
->isPaginatingColumns(); | 1745 bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()
->isPaginatingColumns(); |
1746 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. | 1746 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. |
1747 bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAft
er() == PBALWAYS) | 1747 bool checkAfterAlways = (checkColumnBreaks && child.style()->columnBreakAfte
r() == PBALWAYS) |
1748 || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS); | 1748 || (checkPageBreaks && child.style()->pageBreakAfter() == PBALWAYS); |
1749 if (checkAfterAlways && inNormalFlow(child)) { | 1749 if (checkAfterAlways && inNormalFlow(&child)) { |
1750 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? Lay
outUnit() : marginInfo.margin(); | 1750 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? Lay
outUnit() : marginInfo.margin(); |
1751 | 1751 |
1752 // So our margin doesn't participate in the next collapsing steps. | 1752 // So our margin doesn't participate in the next collapsing steps. |
1753 marginInfo.clearMargin(); | 1753 marginInfo.clearMargin(); |
1754 | 1754 |
1755 if (checkColumnBreaks) { | 1755 if (checkColumnBreaks) { |
1756 if (isInsideMulticolFlowThread) { | 1756 if (isInsideMulticolFlowThread) { |
1757 LayoutUnit offsetBreakAdjustment = 0; | 1757 LayoutUnit offsetBreakAdjustment = 0; |
1758 if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirst
Page() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment)) | 1758 if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirst
Page() + logicalOffset + marginOffset, &child, false, &offsetBreakAdjustment)) |
1759 return logicalOffset + marginOffset + offsetBreakAdjustment; | 1759 return logicalOffset + marginOffset + offsetBreakAdjustment; |
1760 } else { | 1760 } else { |
1761 view()->layoutState()->addForcedColumnBreak(*child, logicalOffse
t); | 1761 view()->layoutState()->addForcedColumnBreak(child, logicalOffset
); |
1762 } | 1762 } |
1763 } | 1763 } |
1764 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); | 1764 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); |
1765 } | 1765 } |
1766 return logicalOffset; | 1766 return logicalOffset; |
1767 } | 1767 } |
1768 | 1768 |
1769 void RenderBlockFlow::addOverflowFromFloats() | 1769 void RenderBlockFlow::addOverflowFromFloats() |
1770 { | 1770 { |
1771 if (!m_floatingObjects) | 1771 if (!m_floatingObjects) |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1880 case CBOTH: | 1880 case CBOTH: |
1881 logicalBottom = lowestFloatLogicalBottom(); | 1881 logicalBottom = lowestFloatLogicalBottom(); |
1882 break; | 1882 break; |
1883 } | 1883 } |
1884 | 1884 |
1885 // We also clear floats if we are too big to sit on the same line as a float
(and wish to avoid floats by default). | 1885 // We also clear floats if we are too big to sit on the same line as a float
(and wish to avoid floats by default). |
1886 LayoutUnit result = clearSet ? std::max<LayoutUnit>(0, logicalBottom - logic
alTop) : LayoutUnit(); | 1886 LayoutUnit result = clearSet ? std::max<LayoutUnit>(0, logicalBottom - logic
alTop) : LayoutUnit(); |
1887 if (!result && child->avoidsFloats()) { | 1887 if (!result && child->avoidsFloats()) { |
1888 LayoutUnit newLogicalTop = logicalTop; | 1888 LayoutUnit newLogicalTop = logicalTop; |
1889 while (true) { | 1889 while (true) { |
1890 LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = availableLog
icalWidthForLine(newLogicalTop, false, logicalHeightForChild(child)); | 1890 LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = availableLog
icalWidthForLine(newLogicalTop, false, logicalHeightForChild(*child)); |
1891 if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWi
dthForContent()) | 1891 if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWi
dthForContent()) |
1892 return newLogicalTop - logicalTop; | 1892 return newLogicalTop - logicalTop; |
1893 | 1893 |
1894 LayoutRect borderBox = child->borderBoxRect(); | 1894 LayoutRect borderBox = child->borderBoxRect(); |
1895 LayoutUnit childLogicalWidthAtOldLogicalTopOffset = isHorizontalWrit
ingMode() ? borderBox.width() : borderBox.height(); | 1895 LayoutUnit childLogicalWidthAtOldLogicalTopOffset = isHorizontalWrit
ingMode() ? borderBox.width() : borderBox.height(); |
1896 | 1896 |
1897 borderBox = child->borderBoxAfterUpdatingLogicalWidth(newLogicalTop)
; | 1897 borderBox = child->borderBoxAfterUpdatingLogicalWidth(newLogicalTop)
; |
1898 LayoutUnit childLogicalWidthAtNewLogicalTopOffset = isHorizontalWrit
ingMode() ? borderBox.width() : borderBox.height(); | 1898 LayoutUnit childLogicalWidthAtNewLogicalTopOffset = isHorizontalWrit
ingMode() ? borderBox.width() : borderBox.height(); |
1899 | 1899 |
1900 if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthA
tNewLogicalTopOffset) { | 1900 if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthA
tNewLogicalTopOffset) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 } | 1963 } |
1964 | 1964 |
1965 parentBlockFlow->markAllDescendantsWithFloatsForLayout(); | 1965 parentBlockFlow->markAllDescendantsWithFloatsForLayout(); |
1966 parentBlockFlow->markSiblingsWithFloatsForLayout(); | 1966 parentBlockFlow->markSiblingsWithFloatsForLayout(); |
1967 } | 1967 } |
1968 | 1968 |
1969 if (diff.needsFullLayout() || !oldStyle) | 1969 if (diff.needsFullLayout() || !oldStyle) |
1970 createOrDestroyMultiColumnFlowThreadIfNeeded(oldStyle); | 1970 createOrDestroyMultiColumnFlowThreadIfNeeded(oldStyle); |
1971 } | 1971 } |
1972 | 1972 |
1973 void RenderBlockFlow::updateStaticInlinePositionForChild(RenderBox* child, Layou
tUnit logicalTop) | 1973 void RenderBlockFlow::updateStaticInlinePositionForChild(RenderBox& child, Layou
tUnit logicalTop) |
1974 { | 1974 { |
1975 if (child->style()->isOriginalDisplayInlineType()) | 1975 if (child.style()->isOriginalDisplayInlineType()) |
1976 setStaticInlinePositionForChild(child, startAlignedOffsetForLine(logical
Top, false)); | 1976 setStaticInlinePositionForChild(child, startAlignedOffsetForLine(logical
Top, false)); |
1977 else | 1977 else |
1978 setStaticInlinePositionForChild(child, startOffsetForContent()); | 1978 setStaticInlinePositionForChild(child, startOffsetForContent()); |
1979 } | 1979 } |
1980 | 1980 |
1981 void RenderBlockFlow::setStaticInlinePositionForChild(RenderBox* child, LayoutUn
it inlinePosition) | 1981 void RenderBlockFlow::setStaticInlinePositionForChild(RenderBox& child, LayoutUn
it inlinePosition) |
1982 { | 1982 { |
1983 child->layer()->setStaticInlinePosition(inlinePosition); | 1983 child.layer()->setStaticInlinePosition(inlinePosition); |
1984 } | 1984 } |
1985 | 1985 |
1986 void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild
) | 1986 void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild
) |
1987 { | 1987 { |
1988 if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 1988 if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
1989 if (beforeChild == flowThread) | 1989 if (beforeChild == flowThread) |
1990 beforeChild = flowThread->firstChild(); | 1990 beforeChild = flowThread->firstChild(); |
1991 ASSERT(!beforeChild || beforeChild->isDescendantOf(flowThread)); | 1991 ASSERT(!beforeChild || beforeChild->isDescendantOf(flowThread)); |
1992 flowThread->addChild(newChild, beforeChild); | 1992 flowThread->addChild(newChild, beforeChild); |
1993 return; | 1993 return; |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2263 } | 2263 } |
2264 // Use the original width of the float here, since the local variable | 2264 // Use the original width of the float here, since the local variable |
2265 // |floatLogicalWidth| was capped to the available line width. See | 2265 // |floatLogicalWidth| was capped to the available line width. See |
2266 // fast/block/float/clamped-right-float.html. | 2266 // fast/block/float/clamped-right-float.html. |
2267 floatLogicalLeft -= logicalWidthForFloat(floatingObject); | 2267 floatLogicalLeft -= logicalWidthForFloat(floatingObject); |
2268 } | 2268 } |
2269 | 2269 |
2270 return LayoutPoint(floatLogicalLeft, logicalTopOffset); | 2270 return LayoutPoint(floatLogicalLeft, logicalTopOffset); |
2271 } | 2271 } |
2272 | 2272 |
2273 FloatingObject* RenderBlockFlow::insertFloatingObject(RenderBox* floatBox) | 2273 FloatingObject* RenderBlockFlow::insertFloatingObject(RenderBox& floatBox) |
2274 { | 2274 { |
2275 ASSERT(floatBox->isFloating()); | 2275 ASSERT(floatBox.isFloating()); |
2276 | 2276 |
2277 // Create the list of special objects if we don't aleady have one | 2277 // Create the list of special objects if we don't aleady have one |
2278 if (!m_floatingObjects) { | 2278 if (!m_floatingObjects) { |
2279 createFloatingObjects(); | 2279 createFloatingObjects(); |
2280 } else { | 2280 } else { |
2281 // Don't insert the object again if it's already in the list | 2281 // Don't insert the object again if it's already in the list |
2282 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 2282 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
2283 FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHash
Translator>(floatBox); | 2283 FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHash
Translator>(&floatBox); |
2284 if (it != floatingObjectSet.end()) | 2284 if (it != floatingObjectSet.end()) |
2285 return it->get(); | 2285 return it->get(); |
2286 } | 2286 } |
2287 | 2287 |
2288 // Create the special object entry & append it to the list | 2288 // Create the special object entry & append it to the list |
2289 | 2289 |
2290 OwnPtr<FloatingObject> newObj = FloatingObject::create(floatBox); | 2290 OwnPtr<FloatingObject> newObj = FloatingObject::create(&floatBox); |
2291 | 2291 |
2292 // Our location is irrelevant if we're unsplittable or no pagination is in e
ffect. | 2292 // Our location is irrelevant if we're unsplittable or no pagination is in e
ffect. |
2293 // Just go ahead and lay out the float. | 2293 // Just go ahead and lay out the float. |
2294 bool isChildRenderBlock = floatBox->isRenderBlock(); | 2294 bool isChildRenderBlock = floatBox.isRenderBlock(); |
2295 if (isChildRenderBlock && !floatBox->needsLayout() && view()->layoutState()-
>pageLogicalHeightChanged()) | 2295 if (isChildRenderBlock && !floatBox.needsLayout() && view()->layoutState()->
pageLogicalHeightChanged()) |
2296 floatBox->setChildNeedsLayout(MarkOnlyThis); | 2296 floatBox.setChildNeedsLayout(MarkOnlyThis); |
2297 | 2297 |
2298 bool needsBlockDirectionLocationSetBeforeLayout = isChildRenderBlock && view
()->layoutState()->needsBlockDirectionLocationSetBeforeLayout(); | 2298 bool needsBlockDirectionLocationSetBeforeLayout = isChildRenderBlock && view
()->layoutState()->needsBlockDirectionLocationSetBeforeLayout(); |
2299 if (!needsBlockDirectionLocationSetBeforeLayout || isWritingModeRoot()) { //
We are unsplittable if we're a block flow root. | 2299 if (!needsBlockDirectionLocationSetBeforeLayout || isWritingModeRoot()) { //
We are unsplittable if we're a block flow root. |
2300 floatBox->layoutIfNeeded(); | 2300 floatBox.layoutIfNeeded(); |
2301 } else { | 2301 } else { |
2302 floatBox->updateLogicalWidth(); | 2302 floatBox.updateLogicalWidth(); |
2303 floatBox->computeAndSetBlockDirectionMargins(this); | 2303 floatBox.computeAndSetBlockDirectionMargins(this); |
2304 } | 2304 } |
2305 | 2305 |
2306 setLogicalWidthForFloat(newObj.get(), logicalWidthForChild(floatBox) + margi
nStartForChild(floatBox) + marginEndForChild(floatBox)); | 2306 setLogicalWidthForFloat(newObj.get(), logicalWidthForChild(floatBox) + margi
nStartForChild(floatBox) + marginEndForChild(floatBox)); |
2307 | 2307 |
2308 return m_floatingObjects->add(newObj.release()); | 2308 return m_floatingObjects->add(newObj.release()); |
2309 } | 2309 } |
2310 | 2310 |
2311 void RenderBlockFlow::removeFloatingObject(RenderBox* floatBox) | 2311 void RenderBlockFlow::removeFloatingObject(RenderBox* floatBox) |
2312 { | 2312 { |
2313 if (m_floatingObjects) { | 2313 if (m_floatingObjects) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2401 // The containing block is responsible for positioning floats, so if we
have floats in our | 2401 // The containing block is responsible for positioning floats, so if we
have floats in our |
2402 // list that come from somewhere else, do not attempt to position them. | 2402 // list that come from somewhere else, do not attempt to position them. |
2403 if (floatingObject->renderer()->containingBlock() != this) | 2403 if (floatingObject->renderer()->containingBlock() != this) |
2404 continue; | 2404 continue; |
2405 | 2405 |
2406 RenderBox* childBox = floatingObject->renderer(); | 2406 RenderBox* childBox = floatingObject->renderer(); |
2407 | 2407 |
2408 // FIXME Investigate if this can be removed. crbug.com/370006 | 2408 // FIXME Investigate if this can be removed. crbug.com/370006 |
2409 childBox->setMayNeedPaintInvalidation(true); | 2409 childBox->setMayNeedPaintInvalidation(true); |
2410 | 2410 |
2411 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ?
marginStartForChild(childBox) : marginEndForChild(childBox); | 2411 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ?
marginStartForChild(*childBox) : marginEndForChild(*childBox); |
2412 if (childBox->style()->clear() & CLEFT) | 2412 if (childBox->style()->clear() & CLEFT) |
2413 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Left), logicalTop); | 2413 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Left), logicalTop); |
2414 if (childBox->style()->clear() & CRIGHT) | 2414 if (childBox->style()->clear() & CRIGHT) |
2415 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Right), logicalTop); | 2415 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Right), logicalTop); |
2416 | 2416 |
2417 LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floati
ngObject, logicalTop); | 2417 LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floati
ngObject, logicalTop); |
2418 | 2418 |
2419 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); | 2419 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); |
2420 | 2420 |
2421 setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogical
LeftMargin); | 2421 setLogicalLeftForChild(*childBox, floatLogicalLocation.x() + childLogica
lLeftMargin); |
2422 setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeF
orChild(childBox)); | 2422 setLogicalTopForChild(*childBox, floatLogicalLocation.y() + marginBefore
ForChild(*childBox)); |
2423 | 2423 |
2424 SubtreeLayoutScope layoutScope(*childBox); | 2424 SubtreeLayoutScope layoutScope(*childBox); |
2425 LayoutState* layoutState = view()->layoutState(); | 2425 LayoutState* layoutState = view()->layoutState(); |
2426 bool isPaginated = layoutState->isPaginated(); | 2426 bool isPaginated = layoutState->isPaginated(); |
2427 if (isPaginated && !childBox->needsLayout()) | 2427 if (isPaginated && !childBox->needsLayout()) |
2428 childBox->markForPaginationRelayoutIfNeeded(layoutScope); | 2428 childBox->markForPaginationRelayoutIfNeeded(layoutScope); |
2429 | 2429 |
2430 childBox->layoutIfNeeded(); | 2430 childBox->layoutIfNeeded(); |
2431 | 2431 |
2432 if (isPaginated) { | 2432 if (isPaginated) { |
2433 // If we are unsplittable and don't fit, then we need to move down. | 2433 // If we are unsplittable and don't fit, then we need to move down. |
2434 // We include our margins as part of the unsplittable area. | 2434 // We include our margins as part of the unsplittable area. |
2435 LayoutUnit newLogicalTop = adjustForUnsplittableChild(childBox, floa
tLogicalLocation.y(), true); | 2435 LayoutUnit newLogicalTop = adjustForUnsplittableChild(*childBox, flo
atLogicalLocation.y(), true); |
2436 | 2436 |
2437 // See if we have a pagination strut that is making us move down fur
ther. | 2437 // See if we have a pagination strut that is making us move down fur
ther. |
2438 // Note that an unsplittable child can't also have a pagination stru
t, so this is | 2438 // Note that an unsplittable child can't also have a pagination stru
t, so this is |
2439 // exclusive with the case above. | 2439 // exclusive with the case above. |
2440 RenderBlockFlow* childBlockFlow = childBox->isRenderBlockFlow() ? to
RenderBlockFlow(childBox) : 0; | 2440 RenderBlockFlow* childBlockFlow = childBox->isRenderBlockFlow() ? to
RenderBlockFlow(childBox) : 0; |
2441 if (childBlockFlow && childBlockFlow->paginationStrut()) { | 2441 if (childBlockFlow && childBlockFlow->paginationStrut()) { |
2442 newLogicalTop += childBlockFlow->paginationStrut(); | 2442 newLogicalTop += childBlockFlow->paginationStrut(); |
2443 childBlockFlow->setPaginationStrut(0); | 2443 childBlockFlow->setPaginationStrut(0); |
2444 } | 2444 } |
2445 | 2445 |
2446 if (newLogicalTop != floatLogicalLocation.y()) { | 2446 if (newLogicalTop != floatLogicalLocation.y()) { |
2447 floatingObject->setPaginationStrut(newLogicalTop - floatLogicalL
ocation.y()); | 2447 floatingObject->setPaginationStrut(newLogicalTop - floatLogicalL
ocation.y()); |
2448 | 2448 |
2449 floatLogicalLocation = computeLogicalLocationForFloat(floatingOb
ject, newLogicalTop); | 2449 floatLogicalLocation = computeLogicalLocationForFloat(floatingOb
ject, newLogicalTop); |
2450 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x())
; | 2450 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x())
; |
2451 | 2451 |
2452 setLogicalLeftForChild(childBox, floatLogicalLocation.x() + chil
dLogicalLeftMargin); | 2452 setLogicalLeftForChild(*childBox, floatLogicalLocation.x() + chi
ldLogicalLeftMargin); |
2453 setLogicalTopForChild(childBox, floatLogicalLocation.y() + margi
nBeforeForChild(childBox)); | 2453 setLogicalTopForChild(*childBox, floatLogicalLocation.y() + marg
inBeforeForChild(*childBox)); |
2454 | 2454 |
2455 if (childBox->isRenderBlock()) | 2455 if (childBox->isRenderBlock()) |
2456 childBox->setChildNeedsLayout(MarkOnlyThis); | 2456 childBox->setChildNeedsLayout(MarkOnlyThis); |
2457 childBox->layoutIfNeeded(); | 2457 childBox->layoutIfNeeded(); |
2458 } | 2458 } |
2459 } | 2459 } |
2460 | 2460 |
2461 setLogicalTopForFloat(floatingObject, floatLogicalLocation.y()); | 2461 setLogicalTopForFloat(floatingObject, floatLogicalLocation.y()); |
2462 | 2462 |
2463 setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox)
+ marginBeforeForChild(childBox) + marginAfterForChild(childBox)); | 2463 setLogicalHeightForFloat(floatingObject, logicalHeightForChild(*childBox
) + marginBeforeForChild(*childBox) + marginAfterForChild(*childBox)); |
2464 | 2464 |
2465 m_floatingObjects->addPlacedObject(floatingObject); | 2465 m_floatingObjects->addPlacedObject(floatingObject); |
2466 | 2466 |
2467 if (ShapeOutsideInfo* shapeOutside = childBox->shapeOutsideInfo()) | 2467 if (ShapeOutsideInfo* shapeOutside = childBox->shapeOutsideInfo()) |
2468 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(childBo
x)); | 2468 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(*childB
ox)); |
2469 } | 2469 } |
2470 return true; | 2470 return true; |
2471 } | 2471 } |
2472 | 2472 |
2473 bool RenderBlockFlow::hasOverhangingFloat(RenderBox* renderer) | 2473 bool RenderBlockFlow::hasOverhangingFloat(RenderBox* renderer) |
2474 { | 2474 { |
2475 if (!m_floatingObjects || hasColumns() || !parent()) | 2475 if (!m_floatingObjects || hasColumns() || !parent()) |
2476 return false; | 2476 return false; |
2477 | 2477 |
2478 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 2478 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2592 return logicalHeight; | 2592 return logicalHeight; |
2593 | 2593 |
2594 LayoutUnit logicalBottom; | 2594 LayoutUnit logicalBottom; |
2595 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 2595 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
2596 FloatingObjectSetIterator end = floatingObjectSet.end(); | 2596 FloatingObjectSetIterator end = floatingObjectSet.end(); |
2597 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { | 2597 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { |
2598 FloatingObject* floatingObject = it->get(); | 2598 FloatingObject* floatingObject = it->get(); |
2599 LayoutUnit floatLogicalBottom = logicalBottomForFloat(floatingObject); | 2599 LayoutUnit floatLogicalBottom = logicalBottomForFloat(floatingObject); |
2600 ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOutsid
eInfo(); | 2600 ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOutsid
eInfo(); |
2601 if (shapeOutside && (offsetMode == ShapeOutsideFloatShapeOffset)) { | 2601 if (shapeOutside && (offsetMode == ShapeOutsideFloatShapeOffset)) { |
2602 LayoutUnit shapeLogicalBottom = logicalTopForFloat(floatingObject) +
marginBeforeForChild(floatingObject->renderer()) + shapeOutside->shapeLogicalBo
ttom(); | 2602 LayoutUnit shapeLogicalBottom = logicalTopForFloat(floatingObject) +
marginBeforeForChild(*(floatingObject->renderer())) + shapeOutside->shapeLogica
lBottom(); |
2603 // Use the shapeLogicalBottom unless it extends outside of the margi
n box, in which case it is clipped. | 2603 // Use the shapeLogicalBottom unless it extends outside of the margi
n box, in which case it is clipped. |
2604 if (shapeLogicalBottom < floatLogicalBottom) | 2604 if (shapeLogicalBottom < floatLogicalBottom) |
2605 floatLogicalBottom = shapeLogicalBottom; | 2605 floatLogicalBottom = shapeLogicalBottom; |
2606 } | 2606 } |
2607 if (floatLogicalBottom > logicalHeight) | 2607 if (floatLogicalBottom > logicalHeight) |
2608 logicalBottom = logicalBottom ? std::min(floatLogicalBottom, logical
Bottom) : floatLogicalBottom; | 2608 logicalBottom = logicalBottom ? std::min(floatLogicalBottom, logical
Bottom) : floatLogicalBottom; |
2609 } | 2609 } |
2610 | 2610 |
2611 return logicalBottom; | 2611 return logicalBottom; |
2612 } | 2612 } |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3091 FrameView* frameView = document().view(); | 3091 FrameView* frameView = document().view(); |
3092 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); | 3092 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); |
3093 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); | 3093 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); |
3094 if (height() < visibleHeight) | 3094 if (height() < visibleHeight) |
3095 top += (visibleHeight - height()) / 2; | 3095 top += (visibleHeight - height()) / 2; |
3096 setY(top); | 3096 setY(top); |
3097 dialog->setCentered(top); | 3097 dialog->setCentered(top); |
3098 } | 3098 } |
3099 | 3099 |
3100 } // namespace blink | 3100 } // namespace blink |
OLD | NEW |