| 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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 | 499 |
| 500 void LayoutBlockFlow::setLogicalTopForChild(LayoutBox& child, LayoutUnit logical
Top) | 500 void LayoutBlockFlow::setLogicalTopForChild(LayoutBox& child, LayoutUnit logical
Top) |
| 501 { | 501 { |
| 502 if (isHorizontalWritingMode()) { | 502 if (isHorizontalWritingMode()) { |
| 503 child.setY(logicalTop); | 503 child.setY(logicalTop); |
| 504 } else { | 504 } else { |
| 505 child.setX(logicalTop); | 505 child.setX(logicalTop); |
| 506 } | 506 } |
| 507 } | 507 } |
| 508 | 508 |
| 509 void LayoutBlockFlow::markDescendantsWithFloatsForLayoutIfNeeded(LayoutBlockFlow
& child, LayoutUnit newLogicalTop, LayoutUnit previousFloatLogicalBottom) |
| 510 { |
| 511 // TODO(mstensho): rework the code to return early when there is no need for
marking, instead |
| 512 // of this |markDescendantsWithFloats| flag. |
| 513 bool markDescendantsWithFloats = false; |
| 514 if (newLogicalTop != child.logicalTop() && !child.avoidsFloats() && child.co
ntainsFloats()) { |
| 515 markDescendantsWithFloats = true; |
| 516 } else if (UNLIKELY(newLogicalTop.mightBeSaturated())) { |
| 517 // The logical top might be saturated for very large elements. Comparing
with the old |
| 518 // logical top might then yield a false negative, as adding and removing
margins, borders |
| 519 // etc. from a saturated number might yield incorrect results. If this i
s the case, always |
| 520 // mark for layout. |
| 521 markDescendantsWithFloats = true; |
| 522 } else if (!child.avoidsFloats() || child.shrinkToAvoidFloats()) { |
| 523 // If an element might be affected by the presence of floats, then alway
s mark it for |
| 524 // layout. |
| 525 if (std::max(previousFloatLogicalBottom, lowestFloatLogicalBottom()) > n
ewLogicalTop) |
| 526 markDescendantsWithFloats = true; |
| 527 } |
| 528 |
| 529 if (markDescendantsWithFloats) |
| 530 child.markAllDescendantsWithFloatsForLayout(); |
| 531 } |
| 532 |
| 533 bool LayoutBlockFlow::positionAndLayoutOnceIfNeeded(LayoutBox& child, LayoutUnit
newLogicalTop, LayoutUnit& previousFloatLogicalBottom) |
| 534 { |
| 535 if (child.isLayoutBlockFlow()) { |
| 536 LayoutBlockFlow& childBlockFlow = toLayoutBlockFlow(child); |
| 537 if (childBlockFlow.containsFloats() || containsFloats()) |
| 538 markDescendantsWithFloatsForLayoutIfNeeded(childBlockFlow, newLogica
lTop, previousFloatLogicalBottom); |
| 539 |
| 540 // TODO(mstensho): A writing mode root is one thing, but we should be ab
le to skip anything |
| 541 // that establishes a new block formatting context here. Their floats do
n't affect us. |
| 542 if (!childBlockFlow.isWritingModeRoot()) |
| 543 previousFloatLogicalBottom = std::max(previousFloatLogicalBottom, ch
ildBlockFlow.logicalTop() + childBlockFlow.lowestFloatLogicalBottom()); |
| 544 } |
| 545 |
| 546 LayoutUnit oldLogicalTop = logicalTopForChild(child); |
| 547 setLogicalTopForChild(child, newLogicalTop); |
| 548 |
| 549 SubtreeLayoutScope layoutScope(child); |
| 550 if (!child.needsLayout()) { |
| 551 if (newLogicalTop != oldLogicalTop && child.shrinkToAvoidFloats()) { |
| 552 // The child's width is affected by adjacent floats. When the child
shifts to clear an |
| 553 // item, its width can change (because it has more available width). |
| 554 layoutScope.setChildNeedsLayout(&child); |
| 555 } else { |
| 556 child.markForPaginationRelayoutIfNeeded(layoutScope); |
| 557 } |
| 558 } |
| 559 |
| 560 if (!child.needsLayout()) |
| 561 return false; |
| 562 child.layout(); |
| 563 return true; |
| 564 } |
| 565 |
| 509 void LayoutBlockFlow::layoutBlockChild(LayoutBox& child, MarginInfo& marginInfo,
LayoutUnit& previousFloatLogicalBottom) | 566 void LayoutBlockFlow::layoutBlockChild(LayoutBox& child, MarginInfo& marginInfo,
LayoutUnit& previousFloatLogicalBottom) |
| 510 { | 567 { |
| 568 LayoutBlockFlow* childLayoutBlockFlow = child.isLayoutBlockFlow() ? toLayout
BlockFlow(&child) : nullptr; |
| 511 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); | 569 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); |
| 512 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); | 570 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); |
| 513 | 571 |
| 514 // The child is a normal flow object. Compute the margins we will use for co
llapsing now. | 572 // The child is a normal flow object. Compute the margins we will use for co
llapsing now. |
| 515 child.computeAndSetBlockDirectionMargins(this); | 573 child.computeAndSetBlockDirectionMargins(this); |
| 516 | 574 |
| 517 // Try to guess our correct logical top position. In most cases this guess w
ill | 575 // Try to guess our correct logical top position. In most cases this guess w
ill |
| 518 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) | 576 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) |
| 519 // will we have to potentially relayout. | 577 // will we have to potentially relayout. |
| 520 LayoutUnit estimateWithoutPagination; | 578 LayoutUnit estimateWithoutPagination; |
| 521 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo
, estimateWithoutPagination); | 579 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo
, estimateWithoutPagination); |
| 522 | 580 |
| 523 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. | 581 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. |
| 524 LayoutRect oldRect = child.frameRect(); | 582 LayoutRect oldRect = child.frameRect(); |
| 525 LayoutUnit oldLogicalTop = logicalTopForChild(child); | |
| 526 | 583 |
| 527 // Go ahead and position the child as though it didn't collapse with the top
. | 584 // Use the estimated block position and lay out the child if needed. After c
hild layout, when |
| 528 setLogicalTopForChild(child, logicalTopEstimate); | 585 // we have enough information to perform proper margin collapsing, float cle
aring and |
| 529 | 586 // pagination, we may have to reposition and lay out again if the estimate w
as wrong. |
| 530 LayoutBlockFlow* childLayoutBlockFlow = child.isLayoutBlockFlow() ? toLayout
BlockFlow(&child) : 0; | 587 bool childNeededLayout = positionAndLayoutOnceIfNeeded(child, logicalTopEsti
mate, previousFloatLogicalBottom); |
| 531 bool markDescendantsWithFloats = false; | |
| 532 if (logicalTopEstimate != oldLogicalTop && childLayoutBlockFlow && !childLay
outBlockFlow->avoidsFloats() && childLayoutBlockFlow->containsFloats()) { | |
| 533 markDescendantsWithFloats = true; | |
| 534 } else if (UNLIKELY(logicalTopEstimate.mightBeSaturated())) { | |
| 535 // logicalTopEstimate, returned by estimateLogicalTopPosition, might be
saturated for | |
| 536 // very large elements. If it does the comparison with oldLogicalTop mig
ht yield a | |
| 537 // false negative as adding and removing margins, borders etc from a sat
urated number | |
| 538 // might yield incorrect results. If this is the case always mark for la
yout. | |
| 539 markDescendantsWithFloats = true; | |
| 540 } else if (!child.avoidsFloats() || child.shrinkToAvoidFloats()) { | |
| 541 // If an element might be affected by the presence of floats, then alway
s mark it for | |
| 542 // layout. | |
| 543 LayoutUnit fb = std::max(previousFloatLogicalBottom, lowestFloatLogicalB
ottom()); | |
| 544 if (fb > logicalTopEstimate) | |
| 545 markDescendantsWithFloats = true; | |
| 546 } | |
| 547 | |
| 548 if (childLayoutBlockFlow) { | |
| 549 if (markDescendantsWithFloats) | |
| 550 childLayoutBlockFlow->markAllDescendantsWithFloatsForLayout(); | |
| 551 if (!child.isWritingModeRoot()) | |
| 552 previousFloatLogicalBottom = std::max(previousFloatLogicalBottom, ol
dLogicalTop + childLayoutBlockFlow->lowestFloatLogicalBottom()); | |
| 553 } | |
| 554 | |
| 555 SubtreeLayoutScope layoutScope(child); | |
| 556 if (!child.needsLayout()) | |
| 557 child.markForPaginationRelayoutIfNeeded(layoutScope); | |
| 558 | |
| 559 bool childNeededLayout = child.needsLayout(); | |
| 560 if (childNeededLayout) | |
| 561 child.layout(); | |
| 562 | 588 |
| 563 // Cache if we are at the top of the block right now. | 589 // Cache if we are at the top of the block right now. |
| 564 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); | 590 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); |
| 565 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); | 591 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); |
| 566 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); | 592 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); |
| 567 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); | 593 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); |
| 568 | 594 |
| 569 // Now determine the correct ypos based off examination of collapsing margin | 595 // Now determine the correct ypos based off examination of collapsing margin |
| 570 // values. | 596 // values. |
| 571 LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo, childI
sSelfCollapsing, childDiscardMarginBefore, childDiscardMarginAfter); | 597 LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo, childI
sSelfCollapsing, childDiscardMarginBefore, childDiscardMarginAfter); |
| 572 | 598 |
| 573 // Now check for clear. | 599 // Now check for clear. |
| 574 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfte
r; | 600 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfte
r; |
| 575 LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, old
PosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear, childIsSelfCollapsin
g, childDiscardMargin); | 601 LayoutUnit newLogicalTop = clearFloatsIfNeeded(child, marginInfo, oldPosMarg
inBefore, oldNegMarginBefore, logicalTopBeforeClear, childIsSelfCollapsing, chil
dDiscardMargin); |
| 576 | 602 |
| 603 // Now check for pagination. |
| 577 bool paginated = view()->layoutState()->isPaginated(); | 604 bool paginated = view()->layoutState()->isPaginated(); |
| 578 if (paginated) { | 605 if (paginated) { |
| 579 logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClea
r, estimateWithoutPagination, child, | 606 if (estimateWithoutPagination != newLogicalTop) { |
| 580 atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear
); | 607 // We got a new position due to clearance or margin collapsing. Befo
re we attempt to |
| 608 // paginate (which may result in the position changing again), let's
try again at the |
| 609 // new position (since a new position may result in a new logical he
ight). |
| 610 positionAndLayoutOnceIfNeeded(child, newLogicalTop, previousFloatLog
icalBottom); |
| 611 } |
| 612 |
| 613 newLogicalTop = adjustBlockChildForPagination(newLogicalTop, child, atBe
foreSideOfBlock && logicalTopBeforeClear == newLogicalTop); |
| 581 } | 614 } |
| 582 | 615 |
| 583 setLogicalTopForChild(child, logicalTopAfterClear); | 616 // Clearance, margin collapsing or pagination may have given us a new logica
l top, in which |
| 584 | 617 // case we may have to reposition and possibly relayout as well. If we deter
mined during child |
| 585 // Now we have a final top position. See if it really does end up being diff
erent from our estimate. | 618 // layout that we need to insert a break to honor widows, we also need to re
layout. |
| 586 // clearFloatsIfNeeded can also mark the child as needing a layout even thou
gh we didn't move. This happens | 619 if (newLogicalTop != logicalTopEstimate |
| 587 // when collapseMargins dynamically adds overhanging floats because of a chi
ld with negative margins. | 620 || child.needsLayout() |
| 588 if (logicalTopAfterClear != logicalTopEstimate || child.needsLayout() || (pa
ginated && childLayoutBlockFlow && childLayoutBlockFlow->shouldBreakAtLineToAvoi
dWidow())) { | 621 || (paginated && childLayoutBlockFlow && childLayoutBlockFlow->shouldBre
akAtLineToAvoidWidow())) { |
| 589 SubtreeLayoutScope layoutScope(child); | 622 positionAndLayoutOnceIfNeeded(child, newLogicalTop, previousFloatLogical
Bottom); |
| 590 if (child.shrinkToAvoidFloats()) { | |
| 591 // The child's width depends on the line width. | |
| 592 // When the child shifts to clear an item, its width can | |
| 593 // change (because it has more available line width). | |
| 594 // So go ahead and mark the item as dirty. | |
| 595 layoutScope.setChildNeedsLayout(&child); | |
| 596 } | |
| 597 | |
| 598 if (childLayoutBlockFlow && !childLayoutBlockFlow->avoidsFloats() && chi
ldLayoutBlockFlow->containsFloats()) | |
| 599 childLayoutBlockFlow->markAllDescendantsWithFloatsForLayout(); | |
| 600 | |
| 601 if (!child.needsLayout()) | |
| 602 child.markForPaginationRelayoutIfNeeded(layoutScope); | |
| 603 | |
| 604 // Our guess was wrong. Make the child lay itself out again. | |
| 605 child.layoutIfNeeded(); | |
| 606 } | 623 } |
| 607 | 624 |
| 608 // If we previously encountered a self-collapsing sibling of this child that
had clearance then | 625 // If we previously encountered a self-collapsing sibling of this child that
had clearance then |
| 609 // we set this bit to ensure we would not collapse the child's margins, and
those of any subsequent | 626 // we set this bit to ensure we would not collapse the child's margins, and
those of any subsequent |
| 610 // self-collapsing siblings, with our parent. If this child is not self-coll
apsing then it can | 627 // self-collapsing siblings, with our parent. If this child is not self-coll
apsing then it can |
| 611 // collapse its margins with the parent so reset the bit. | 628 // collapse its margins with the parent so reset the bit. |
| 612 if (!marginInfo.canCollapseMarginAfterWithLastChild() && !childIsSelfCollaps
ing) | 629 if (!marginInfo.canCollapseMarginAfterWithLastChild() && !childIsSelfCollaps
ing) |
| 613 marginInfo.setCanCollapseMarginAfterWithLastChild(true); | 630 marginInfo.setCanCollapseMarginAfterWithLastChild(true); |
| 614 | 631 |
| 615 // We are no longer at the top of the block if we encounter a non-empty chil
d. | 632 // We are no longer at the top of the block if we encounter a non-empty chil
d. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 645 if (newHeight != size().height()) | 662 if (newHeight != size().height()) |
| 646 setLogicalHeight(newHeight); | 663 setLogicalHeight(newHeight); |
| 647 } | 664 } |
| 648 | 665 |
| 649 if (child.isLayoutMultiColumnSpannerPlaceholder()) { | 666 if (child.isLayoutMultiColumnSpannerPlaceholder()) { |
| 650 // The actual column-span:all element is positioned by this placeholder
child. | 667 // The actual column-span:all element is positioned by this placeholder
child. |
| 651 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child)); | 668 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child)); |
| 652 } | 669 } |
| 653 } | 670 } |
| 654 | 671 |
| 655 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA
fterClear, LayoutUnit estimateWithoutPagination, LayoutBox& child, bool atBefore
SideOfBlock) | 672 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
LayoutBox& child, bool atBeforeSideOfBlock) |
| 656 { | 673 { |
| 657 LayoutBlockFlow* childBlockFlow = child.isLayoutBlockFlow() ? toLayoutBlockF
low(&child) : 0; | 674 LayoutBlockFlow* childBlockFlow = child.isLayoutBlockFlow() ? toLayoutBlockF
low(&child) : 0; |
| 658 | 675 |
| 659 if (estimateWithoutPagination != logicalTopAfterClear) { | |
| 660 // Our guess prior to pagination movement was wrong. Before we attempt t
o paginate, let's try again at the new | |
| 661 // position. | |
| 662 setLogicalHeight(logicalTopAfterClear); | |
| 663 setLogicalTopForChild(child, logicalTopAfterClear); | |
| 664 | |
| 665 if (child.shrinkToAvoidFloats()) { | |
| 666 // The child's width depends on the line width. | |
| 667 // When the child shifts to clear an item, its width can | |
| 668 // change (because it has more available line width). | |
| 669 // So go ahead and mark the item as dirty. | |
| 670 child.setChildNeedsLayout(MarkOnlyThis); | |
| 671 } | |
| 672 | |
| 673 SubtreeLayoutScope layoutScope(child); | |
| 674 | |
| 675 if (childBlockFlow) { | |
| 676 if (!childBlockFlow->avoidsFloats() && childBlockFlow->containsFloat
s()) | |
| 677 childBlockFlow->markAllDescendantsWithFloatsForLayout(); | |
| 678 if (!child.needsLayout()) | |
| 679 child.markForPaginationRelayoutIfNeeded(layoutScope); | |
| 680 } | |
| 681 | |
| 682 // Our guess was wrong. Make the child lay itself out again. | |
| 683 child.layoutIfNeeded(); | |
| 684 } | |
| 685 | |
| 686 LayoutUnit oldTop = logicalTopAfterClear; | |
| 687 | |
| 688 // If the object has a page or column break value of "before", then we shoul
d shift to the top of the next page. | 676 // If the object has a page or column break value of "before", then we shoul
d shift to the top of the next page. |
| 689 LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear); | 677 LayoutUnit newLogicalTop = applyBeforeBreak(child, logicalTop); |
| 690 | 678 |
| 691 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. | 679 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. |
| 692 LayoutUnit logicalTopBeforeUnsplittableAdjustment = result; | 680 LayoutUnit logicalTopBeforeUnsplittableAdjustment = newLogicalTop; |
| 693 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil
d(child, result); | 681 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil
d(child, newLogicalTop); |
| 694 | 682 |
| 695 LayoutUnit paginationStrut = 0; | 683 LayoutUnit paginationStrut = 0; |
| 696 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme
nt - logicalTopBeforeUnsplittableAdjustment; | 684 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme
nt - logicalTopBeforeUnsplittableAdjustment; |
| 697 LayoutUnit childLogicalHeight = child.logicalHeight(); | 685 LayoutUnit childLogicalHeight = child.logicalHeight(); |
| 698 if (unsplittableAdjustmentDelta) { | 686 if (unsplittableAdjustmentDelta) { |
| 699 setPageBreak(result, childLogicalHeight - unsplittableAdjustmentDelta); | 687 setPageBreak(newLogicalTop, childLogicalHeight - unsplittableAdjustmentD
elta); |
| 700 paginationStrut = unsplittableAdjustmentDelta; | 688 paginationStrut = unsplittableAdjustmentDelta; |
| 701 } else if (childBlockFlow && childBlockFlow->paginationStrut()) { | 689 } else if (childBlockFlow && childBlockFlow->paginationStrut()) { |
| 702 paginationStrut = childBlockFlow->paginationStrut(); | 690 paginationStrut = childBlockFlow->paginationStrut(); |
| 703 } | 691 } |
| 704 | 692 |
| 705 if (paginationStrut) { | 693 if (paginationStrut) { |
| 706 // We are willing to propagate out to our parent block as long as we wer
e at the top of the block prior | 694 // We are willing to propagate out to our parent block as long as we wer
e at the top of the block prior |
| 707 // to collapsing our margins, and as long as we didn't clear or move as
a result of other pagination. | 695 // to collapsing our margins, and as long as we didn't clear or move as
a result of other pagination. |
| 708 if (atBeforeSideOfBlock && oldTop == result && !isOutOfFlowPositioned()
&& !isTableCell()) { | 696 if (atBeforeSideOfBlock && logicalTop == newLogicalTop && !isOutOfFlowPo
sitioned() && !isTableCell()) { |
| 709 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't | 697 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't |
| 710 // have all the information to do so (the strut only has the remaini
ng amount to push). Gecko gets this wrong too | 698 // have all the information to do so (the strut only has the remaini
ng amount to push). Gecko gets this wrong too |
| 711 // and pushes to the next page anyway, so not too concerned about it
. | 699 // and pushes to the next page anyway, so not too concerned about it
. |
| 712 setPaginationStrut(result + paginationStrut); | 700 setPaginationStrut(logicalTop + paginationStrut); |
| 713 if (childBlockFlow) | 701 if (childBlockFlow) |
| 714 childBlockFlow->setPaginationStrut(0); | 702 childBlockFlow->setPaginationStrut(0); |
| 715 } else { | 703 } else { |
| 716 result += paginationStrut; | 704 newLogicalTop += paginationStrut; |
| 717 } | 705 } |
| 718 } | 706 } |
| 719 | 707 |
| 720 if (!unsplittableAdjustmentDelta) { | 708 if (!unsplittableAdjustmentDelta) { |
| 721 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(result)) { | 709 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical
Top)) { |
| 722 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(result, AssociateWithLatterPage); | 710 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(newLogicalTop, AssociateWithLatterPage); |
| 723 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; | 711 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; |
| 724 if (spaceShortage > 0) { | 712 if (spaceShortage > 0) { |
| 725 // If the child crosses a column boundary, report a break, in ca
se nothing inside it | 713 // If the child crosses a column boundary, report a break, in ca
se nothing inside it |
| 726 // has already done so. The column balancer needs to know how mu
ch it has to stretch | 714 // has already done so. The column balancer needs to know how mu
ch it has to stretch |
| 727 // the columns to make more content fit. If no breaks are report
ed (but do occur), | 715 // the columns to make more content fit. If no breaks are report
ed (but do occur), |
| 728 // the balancer will have no clue. Only measure the space after
the last column | 716 // the balancer will have no clue. Only measure the space after
the last column |
| 729 // boundary, in case it crosses more than one. | 717 // boundary, in case it crosses more than one. |
| 730 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag
eLogicalHeight); | 718 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag
eLogicalHeight); |
| 731 setPageBreak(result, spaceShortageInLastColumn ? spaceShortageIn
LastColumn : spaceShortage); | 719 setPageBreak(newLogicalTop, spaceShortageInLastColumn ? spaceSho
rtageInLastColumn : spaceShortage); |
| 732 } else if (remainingLogicalHeight == pageLogicalHeight && offsetFrom
LogicalTopOfFirstPage() + child.logicalTop()) { | 720 } else if (remainingLogicalHeight == pageLogicalHeight && offsetFrom
LogicalTopOfFirstPage() + child.logicalTop()) { |
| 733 // We're at the very top of a page or column, and it's not the f
irst one. This child | 721 // We're at the very top of a page or column, and it's not the f
irst one. This child |
| 734 // may turn out to be the smallest piece of content that causes
a page break, so we | 722 // may turn out to be the smallest piece of content that causes
a page break, so we |
| 735 // need to report it. | 723 // need to report it. |
| 736 setPageBreak(result, childLogicalHeight); | 724 setPageBreak(newLogicalTop, childLogicalHeight); |
| 737 } | 725 } |
| 738 } | 726 } |
| 739 } | 727 } |
| 740 | 728 |
| 741 // Similar to how we apply clearance. Go ahead and boost height() to be the
place where we're going to position the child. | 729 // Similar to how we apply clearance. Go ahead and boost height() to be the
place where we're going to position the child. |
| 742 setLogicalHeight(logicalHeight() + (result - oldTop)); | 730 setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop)); |
| 743 | 731 |
| 744 // Return the final adjusted logical top. | 732 // Return the final adjusted logical top. |
| 745 return result; | 733 return newLogicalTop; |
| 746 } | 734 } |
| 747 | 735 |
| 748 static inline LayoutUnit calculateMinimumPageHeight(const ComputedStyle& style,
const RootInlineBox& lastLine) | 736 static inline LayoutUnit calculateMinimumPageHeight(const ComputedStyle& style,
const RootInlineBox& lastLine) |
| 749 { | 737 { |
| 750 // We may require a certain minimum number of lines per page in order to sat
isfy | 738 // We may require a certain minimum number of lines per page in order to sat
isfy |
| 751 // orphans and widows, and that may affect the minimum page height. | 739 // orphans and widows, and that may affect the minimum page height. |
| 752 unsigned lineCount = std::max<unsigned>(style.hasAutoOrphans() ? 1 : style.o
rphans(), style.widows()); | 740 unsigned lineCount = std::max<unsigned>(style.hasAutoOrphans() ? 1 : style.o
rphans(), style.widows()); |
| 753 const RootInlineBox* firstLine = &lastLine; | 741 const RootInlineBox* firstLine = &lastLine; |
| 754 for (unsigned i = 1; i < lineCount && firstLine->prevRootBox(); i++) | 742 for (unsigned i = 1; i < lineCount && firstLine->prevRootBox(); i++) |
| 755 firstLine = firstLine->prevRootBox(); | 743 firstLine = firstLine->prevRootBox(); |
| (...skipping 2314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3070 FrameView* frameView = document().view(); | 3058 FrameView* frameView = document().view(); |
| 3071 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); | 3059 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); |
| 3072 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); | 3060 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); |
| 3073 if (size().height() < visibleHeight) | 3061 if (size().height() < visibleHeight) |
| 3074 top += (visibleHeight - size().height()) / 2; | 3062 top += (visibleHeight - size().height()) / 2; |
| 3075 setY(top); | 3063 setY(top); |
| 3076 dialog->setCentered(top); | 3064 dialog->setCentered(top); |
| 3077 } | 3065 } |
| 3078 | 3066 |
| 3079 } // namespace blink | 3067 } // namespace blink |
| OLD | NEW |