| 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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 // and subtract it from the maximal negative margin from both A and B to get
the | 359 // and subtract it from the maximal negative margin from both A and B to get
the |
| 360 // true collapsed margin. This algorithm is recursive, so when we finish lay
out() | 360 // true collapsed margin. This algorithm is recursive, so when we finish lay
out() |
| 361 // our block knows its current maximal positive/negative values. | 361 // our block knows its current maximal positive/negative values. |
| 362 // | 362 // |
| 363 // Start out by setting our margin values to our current margins. Table cell
s have | 363 // Start out by setting our margin values to our current margins. Table cell
s have |
| 364 // no margins, so we don't fill in the values for table cells. | 364 // no margins, so we don't fill in the values for table cells. |
| 365 if (!isTableCell()) { | 365 if (!isTableCell()) { |
| 366 initMaxMarginValues(); | 366 initMaxMarginValues(); |
| 367 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); | 367 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); |
| 368 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); | 368 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); |
| 369 setPaginationStrut(0); | 369 setPaginationStrutPropagatedFromChild(LayoutUnit()); |
| 370 } | 370 } |
| 371 | 371 |
| 372 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | 372 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); |
| 373 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig
ht(); | 373 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig
ht(); |
| 374 LayoutUnit previousHeight = logicalHeight(); | 374 LayoutUnit previousHeight = logicalHeight(); |
| 375 setLogicalHeight(beforeEdge); | 375 setLogicalHeight(beforeEdge); |
| 376 | 376 |
| 377 m_paintInvalidationLogicalTop = 0; | 377 m_paintInvalidationLogicalTop = 0; |
| 378 m_paintInvalidationLogicalBottom = 0; | 378 m_paintInvalidationLogicalBottom = 0; |
| 379 if (!firstChild() && !isAnonymousBlock()) | 379 if (!firstChild() && !isAnonymousBlock()) |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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. | 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. |
| 692 LayoutUnit logicalTopBeforeUnsplittableAdjustment = newLogicalTop; | 692 LayoutUnit logicalTopBeforeUnsplittableAdjustment = newLogicalTop; |
| 693 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil
d(child, newLogicalTop); | 693 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil
d(child, newLogicalTop); |
| 694 | 694 |
| 695 LayoutUnit paginationStrut = 0; | 695 LayoutUnit paginationStrut = 0; |
| 696 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme
nt - logicalTopBeforeUnsplittableAdjustment; | 696 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme
nt - logicalTopBeforeUnsplittableAdjustment; |
| 697 LayoutUnit childLogicalHeight = child.logicalHeight(); | 697 LayoutUnit childLogicalHeight = child.logicalHeight(); |
| 698 if (unsplittableAdjustmentDelta) { | 698 if (unsplittableAdjustmentDelta) { |
| 699 setPageBreak(newLogicalTop, childLogicalHeight - unsplittableAdjustmentD
elta); | 699 setPageBreak(newLogicalTop, childLogicalHeight - unsplittableAdjustmentD
elta); |
| 700 paginationStrut = unsplittableAdjustmentDelta; | 700 paginationStrut = unsplittableAdjustmentDelta; |
| 701 } else if (childBlockFlow && childBlockFlow->paginationStrut()) { | 701 } else if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromCh
ild()) { |
| 702 paginationStrut = childBlockFlow->paginationStrut(); | 702 paginationStrut = childBlockFlow->paginationStrutPropagatedFromChild(); |
| 703 } | 703 } |
| 704 | 704 |
| 705 if (paginationStrut) { | 705 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 | 706 // 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. | 707 // to collapsing our margins, and as long as we didn't clear or move as
a result of other pagination. |
| 708 if (atBeforeSideOfBlock && logicalTop == newLogicalTop && allowsPaginati
onStrut()) { | 708 if (atBeforeSideOfBlock && logicalTop == newLogicalTop && allowsPaginati
onStrut()) { |
| 709 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't | 709 // 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 | 710 // 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
. | 711 // and pushes to the next page anyway, so not too concerned about it
. |
| 712 paginationStrut += logicalTop; | 712 paginationStrut += logicalTop; |
| 713 if (isFloating()) | 713 if (isFloating()) |
| 714 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. | 714 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. |
| 715 setPaginationStrut(paginationStrut); | 715 setPaginationStrutPropagatedFromChild(paginationStrut); |
| 716 if (childBlockFlow) | 716 if (childBlockFlow) |
| 717 childBlockFlow->setPaginationStrut(0); | 717 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit
()); |
| 718 } else { | 718 } else { |
| 719 newLogicalTop += paginationStrut; | 719 newLogicalTop += paginationStrut; |
| 720 } | 720 } |
| 721 } | 721 } |
| 722 | 722 |
| 723 if (!unsplittableAdjustmentDelta) { | 723 if (!unsplittableAdjustmentDelta) { |
| 724 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical
Top)) { | 724 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical
Top)) { |
| 725 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(newLogicalTop, AssociateWithLatterPage); | 725 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(newLogicalTop, AssociateWithLatterPage); |
| 726 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; | 726 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; |
| 727 if (spaceShortage > 0) { | 727 if (spaceShortage > 0) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight); | 825 setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight); |
| 826 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, rema
iningLogicalHeight)) { | 826 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, rema
iningLogicalHeight)) { |
| 827 // Note that when setting the strut on a block, it may be propagated
to parent blocks | 827 // Note that when setting the strut on a block, it may be propagated
to parent blocks |
| 828 // later on, if a block's logical top is flush with that of its pare
nt. We don't want | 828 // later on, if a block's logical top is flush with that of its pare
nt. We don't want |
| 829 // content-less portions (struts) at the beginning of a block before
a break, if it can | 829 // content-less portions (struts) at the beginning of a block before
a break, if it can |
| 830 // be avoided. After all, that's the reason for setting struts on bl
ocks and not lines | 830 // be avoided. After all, that's the reason for setting struts on bl
ocks and not lines |
| 831 // in the first place. | 831 // in the first place. |
| 832 LayoutUnit paginationStrut = remainingLogicalHeight + std::max<Layou
tUnit>(0, logicalOffset); | 832 LayoutUnit paginationStrut = remainingLogicalHeight + std::max<Layou
tUnit>(0, logicalOffset); |
| 833 if (isFloating()) | 833 if (isFloating()) |
| 834 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. | 834 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. |
| 835 setPaginationStrut(paginationStrut); | 835 setPaginationStrutPropagatedFromChild(paginationStrut); |
| 836 } else { | 836 } else { |
| 837 delta += remainingLogicalHeight; | 837 delta += remainingLogicalHeight; |
| 838 lineBox.setPaginationStrut(remainingLogicalHeight); | 838 lineBox.setPaginationStrut(remainingLogicalHeight); |
| 839 lineBox.setIsFirstAfterPageBreak(true); | 839 lineBox.setIsFirstAfterPageBreak(true); |
| 840 } | 840 } |
| 841 } else if (remainingLogicalHeight == pageLogicalHeight) { | 841 } else if (remainingLogicalHeight == pageLogicalHeight) { |
| 842 // We're at the very top of a page or column. | 842 // We're at the very top of a page or column. |
| 843 if (lineBox != firstRootBox()) | 843 if (lineBox != firstRootBox()) |
| 844 lineBox.setIsFirstAfterPageBreak(true); | 844 lineBox.setIsFirstAfterPageBreak(true); |
| 845 if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage()) | 845 if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage()) |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1517 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); | 1517 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); |
| 1518 | 1518 |
| 1519 estimateWithoutPagination = logicalTopEstimate; | 1519 estimateWithoutPagination = logicalTopEstimate; |
| 1520 | 1520 |
| 1521 if (layoutState->isPaginated()) { | 1521 if (layoutState->isPaginated()) { |
| 1522 // If the object has a page or column break value of "before", then we s
hould shift to the top of the next page. | 1522 // If the object has a page or column break value of "before", then we s
hould shift to the top of the next page. |
| 1523 logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate); | 1523 logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate); |
| 1524 | 1524 |
| 1525 // For replaced elements and scrolled elements, we want to shift them to
the next page if they don't fit on the current one. | 1525 // For replaced elements and scrolled elements, we want to shift them to
the next page if they don't fit on the current one. |
| 1526 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimat
e); | 1526 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimat
e); |
| 1527 | |
| 1528 if (!child.selfNeedsLayout() && child.isLayoutBlockFlow()) | |
| 1529 logicalTopEstimate += toLayoutBlockFlow(&child)->paginationStrut(); | |
| 1530 } | 1527 } |
| 1531 | 1528 |
| 1532 return logicalTopEstimate; | 1529 return logicalTopEstimate; |
| 1533 } | 1530 } |
| 1534 | 1531 |
| 1535 void LayoutBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) | 1532 void LayoutBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) |
| 1536 { | 1533 { |
| 1537 // The float should be positioned taking into account the bottom margin | 1534 // The float should be positioned taking into account the bottom margin |
| 1538 // of the previous flow. We add that margin into the height, get the | 1535 // of the previous flow. We add that margin into the height, get the |
| 1539 // float positioned properly, and then subtract the margin out of the | 1536 // float positioned properly, and then subtract the margin out of the |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 bool isPaginated = layoutState->isPaginated(); | 2405 bool isPaginated = layoutState->isPaginated(); |
| 2409 if (isPaginated && !childBox->needsLayout()) | 2406 if (isPaginated && !childBox->needsLayout()) |
| 2410 childBox->markForPaginationRelayoutIfNeeded(layoutScope); | 2407 childBox->markForPaginationRelayoutIfNeeded(layoutScope); |
| 2411 | 2408 |
| 2412 childBox->layoutIfNeeded(); | 2409 childBox->layoutIfNeeded(); |
| 2413 | 2410 |
| 2414 if (isPaginated) { | 2411 if (isPaginated) { |
| 2415 LayoutUnit newLogicalTop = floatLogicalLocation.y(); | 2412 LayoutUnit newLogicalTop = floatLogicalLocation.y(); |
| 2416 | 2413 |
| 2417 LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? to
LayoutBlockFlow(childBox) : 0; | 2414 LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? to
LayoutBlockFlow(childBox) : 0; |
| 2418 if (childBlockFlow && childBlockFlow->paginationStrut()) { | 2415 if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromC
hild()) { |
| 2419 // Some content inside this float has determined that we need to
move to the next | 2416 // Some content inside this float has determined that we need to
move to the next |
| 2420 // page or column. | 2417 // page or column. |
| 2421 newLogicalTop += childBlockFlow->paginationStrut(); | 2418 newLogicalTop += childBlockFlow->paginationStrutPropagatedFromCh
ild(); |
| 2422 childBlockFlow->setPaginationStrut(LayoutUnit()); | |
| 2423 } else { | 2419 } else { |
| 2424 // Now that we know the final height, check if we are unsplittab
le, and if we don't | 2420 // Now that we know the final height, check if we are unsplittab
le, and if we don't |
| 2425 // fit at the current position, but would fit at the top of the
next page or | 2421 // fit at the current position, but would fit at the top of the
next page or |
| 2426 // column, move there. | 2422 // column, move there. |
| 2427 newLogicalTop = adjustForUnsplittableChild(*childBox, newLogical
Top); | 2423 newLogicalTop = adjustForUnsplittableChild(*childBox, newLogical
Top); |
| 2428 } | 2424 } |
| 2429 | 2425 |
| 2430 if (newLogicalTop != floatLogicalLocation.y()) { | 2426 if (newLogicalTop != floatLogicalLocation.y()) { |
| 2431 floatingObject.setPaginationStrut(newLogicalTop - floatLogicalLo
cation.y()); | 2427 floatingObject.setPaginationStrut(newLogicalTop - floatLogicalLo
cation.y()); |
| 2432 | 2428 |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2908 // up the struts and handle them. We handle floats and regular in-flow child
ren, and that's | 2904 // up the struts and handle them. We handle floats and regular in-flow child
ren, and that's |
| 2909 // all. We could handle this in other layout modes as well (and even for out
-of-flow children), | 2905 // all. We could handle this in other layout modes as well (and even for out
-of-flow children), |
| 2910 // but currently we don't. | 2906 // but currently we don't. |
| 2911 // TODO(mstensho): But we *should*. | 2907 // TODO(mstensho): But we *should*. |
| 2912 if (isOutOfFlowPositioned()) | 2908 if (isOutOfFlowPositioned()) |
| 2913 return false; | 2909 return false; |
| 2914 LayoutBlock* containingBlock = this->containingBlock(); | 2910 LayoutBlock* containingBlock = this->containingBlock(); |
| 2915 return containingBlock && containingBlock->isLayoutBlockFlow(); | 2911 return containingBlock && containingBlock->isLayoutBlockFlow(); |
| 2916 } | 2912 } |
| 2917 | 2913 |
| 2918 void LayoutBlockFlow::setPaginationStrut(LayoutUnit strut) | 2914 void LayoutBlockFlow::setPaginationStrutPropagatedFromChild(LayoutUnit strut) |
| 2919 { | 2915 { |
| 2920 if (!m_rareData) { | 2916 if (!m_rareData) { |
| 2921 if (!strut) | 2917 if (!strut) |
| 2922 return; | 2918 return; |
| 2923 m_rareData = adoptPtr(new LayoutBlockFlowRareData(this)); | 2919 m_rareData = adoptPtr(new LayoutBlockFlowRareData(this)); |
| 2924 } | 2920 } |
| 2925 m_rareData->m_paginationStrut = strut; | 2921 m_rareData->m_paginationStrutPropagatedFromChild = strut; |
| 2926 } | 2922 } |
| 2927 | 2923 |
| 2928 void LayoutBlockFlow::positionSpannerDescendant(LayoutMultiColumnSpannerPlacehol
der& child) | 2924 void LayoutBlockFlow::positionSpannerDescendant(LayoutMultiColumnSpannerPlacehol
der& child) |
| 2929 { | 2925 { |
| 2930 LayoutBox& spanner = *child.layoutObjectInFlowThread(); | 2926 LayoutBox& spanner = *child.layoutObjectInFlowThread(); |
| 2931 // FIXME: |spanner| is a descendant, but never a direct child, so the names
here are bad, if | 2927 // FIXME: |spanner| is a descendant, but never a direct child, so the names
here are bad, if |
| 2932 // nothing else. | 2928 // nothing else. |
| 2933 setLogicalTopForChild(spanner, child.logicalTop()); | 2929 setLogicalTopForChild(spanner, child.logicalTop()); |
| 2934 determineLogicalLeftPositionForChild(spanner); | 2930 determineLogicalLeftPositionForChild(spanner); |
| 2935 } | 2931 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3090 FrameView* frameView = document().view(); | 3086 FrameView* frameView = document().view(); |
| 3091 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); | 3087 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); |
| 3092 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); | 3088 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); |
| 3093 if (size().height() < visibleHeight) | 3089 if (size().height() < visibleHeight) |
| 3094 top += (visibleHeight - size().height()) / 2; | 3090 top += (visibleHeight - size().height()) / 2; |
| 3095 setY(top); | 3091 setY(top); |
| 3096 dialog->setCentered(top); | 3092 dialog->setCentered(top); |
| 3097 } | 3093 } |
| 3098 | 3094 |
| 3099 } // namespace blink | 3095 } // namespace blink |
| OLD | NEW |