| 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 |