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 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 if (child.isLayoutMultiColumnSpannerPlaceholder()) { | 678 if (child.isLayoutMultiColumnSpannerPlaceholder()) { |
679 // The actual column-span:all element is positioned by this placeholder
child. | 679 // The actual column-span:all element is positioned by this placeholder
child. |
680 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child)); | 680 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child)); |
681 } | 681 } |
682 } | 682 } |
683 | 683 |
684 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
LayoutBox& child, bool atBeforeSideOfBlock) | 684 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
LayoutBox& child, bool atBeforeSideOfBlock) |
685 { | 685 { |
686 LayoutBlockFlow* childBlockFlow = child.isLayoutBlockFlow() ? toLayoutBlockF
low(&child) : 0; | 686 LayoutBlockFlow* childBlockFlow = child.isLayoutBlockFlow() ? toLayoutBlockF
low(&child) : 0; |
687 | 687 |
| 688 // Calculate the pagination strut for this child. A strut may come from thre
e sources: |
| 689 // 1. The first piece of content inside the child doesn't fit in the current
page or column |
| 690 // 2. A forced break before the child |
| 691 // 3. The child itself is unsplittable and doesn't fit in the current page o
r column. |
| 692 // |
| 693 // No matter which source, if we need to insert a strut, it should always ta
ke us to the exact |
| 694 // top of the next page or column, or be zero. |
| 695 |
| 696 // We're now going to calculate the child's final pagination strut. We may e
nd up propagating |
| 697 // it to its containing block (|this|), so reset it first. |
| 698 child.resetPaginationStrut(); |
| 699 |
| 700 // The first piece of content inside the child may have set a strut during l
ayout. Currently, |
| 701 // only block flows support strut propagation, but this may (and should) cha
nge in the future. |
| 702 // See crbug.com/539873 |
| 703 LayoutUnit strutFromContent = childBlockFlow ? childBlockFlow->paginationStr
utPropagatedFromChild() : LayoutUnit(); |
| 704 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent; |
| 705 |
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. | 706 // 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 newLogicalTop = applyBeforeBreak(child, logicalTop); | 707 LayoutUnit logicalTopAfterForcedBreak = applyBeforeBreak(child, logicalTop); |
690 | 708 |
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. | 709 // 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; | 710 LayoutUnit logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, l
ogicalTop); |
693 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil
d(child, newLogicalTop); | 711 LayoutUnit childLogicalHeight = child.logicalHeight(); |
| 712 bool neededBreakForUnsplittable = logicalTopAfterUnsplittable != logicalTop; |
| 713 if (neededBreakForUnsplittable) |
| 714 setPageBreak(logicalTop, childLogicalHeight - (logicalTopAfterUnsplittab
le - logicalTop)); |
694 | 715 |
695 LayoutUnit paginationStrut = 0; | 716 // Some sanity checks: No matter what the reason is for pushing the child to
the next page or |
696 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme
nt - logicalTopBeforeUnsplittableAdjustment; | 717 // column, the amount should be the same. |
697 LayoutUnit childLogicalHeight = child.logicalHeight(); | 718 ASSERT(!strutFromContent || logicalTopAfterForcedBreak == logicalTop || logi
calTopAfterForcedBreak == logicalTopWithContentStrut); |
698 if (unsplittableAdjustmentDelta) { | 719 ASSERT(!strutFromContent || logicalTopAfterUnsplittable == logicalTop || log
icalTopAfterUnsplittable == logicalTopWithContentStrut); |
699 setPageBreak(newLogicalTop, childLogicalHeight - unsplittableAdjustmentD
elta); | 720 ASSERT(logicalTopAfterUnsplittable == logicalTop || logicalTopAfterForcedBre
ak == logicalTop || logicalTopAfterUnsplittable == logicalTopAfterForcedBreak); |
700 paginationStrut = unsplittableAdjustmentDelta; | |
701 } else if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromCh
ild()) { | |
702 paginationStrut = childBlockFlow->paginationStrutPropagatedFromChild(); | |
703 } | |
704 | 721 |
705 if (paginationStrut) { | 722 LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut,
std::max(logicalTopAfterForcedBreak, logicalTopAfterUnsplittable)); |
| 723 LayoutUnit newLogicalTop = logicalTop; |
| 724 if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) { |
| 725 ASSERT(paginationStrut > 0); |
706 // We are willing to propagate out to our parent block as long as we wer
e at the top of the block prior | 726 // 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. | 727 // 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()) { | 728 if (atBeforeSideOfBlock && logicalTopAfterForcedBreak == logicalTop && a
llowsPaginationStrut()) { |
709 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't | 729 // 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 | 730 // 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
. | 731 // and pushes to the next page anyway, so not too concerned about it
. |
712 paginationStrut += logicalTop; | 732 paginationStrut += logicalTop; |
713 if (isFloating()) | 733 if (isFloating()) |
714 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. | 734 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. |
715 setPaginationStrutPropagatedFromChild(paginationStrut); | 735 setPaginationStrutPropagatedFromChild(paginationStrut); |
716 if (childBlockFlow) | 736 if (childBlockFlow) |
717 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit
()); | 737 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit
()); |
718 } else { | 738 } else { |
| 739 child.setPaginationStrut(paginationStrut); |
719 newLogicalTop += paginationStrut; | 740 newLogicalTop += paginationStrut; |
720 } | 741 } |
721 } | 742 } |
722 | 743 |
723 if (!unsplittableAdjustmentDelta) { | 744 if (!neededBreakForUnsplittable) { |
724 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical
Top)) { | 745 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical
Top)) { |
725 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(newLogicalTop, AssociateWithLatterPage); | 746 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(newLogicalTop, AssociateWithLatterPage); |
726 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; | 747 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; |
727 if (spaceShortage > 0) { | 748 if (spaceShortage > 0) { |
728 // If the child crosses a column boundary, report a break, in ca
se nothing inside it | 749 // If the child crosses a column boundary, report a break, in ca
se nothing inside it |
729 // has already done so. The column balancer needs to know how mu
ch it has to stretch | 750 // has already done so. The column balancer needs to know how mu
ch it has to stretch |
730 // the columns to make more content fit. If no breaks are report
ed (but do occur), | 751 // the columns to make more content fit. If no breaks are report
ed (but do occur), |
731 // the balancer will have no clue. Only measure the space after
the last column | 752 // the balancer will have no clue. Only measure the space after
the last column |
732 // boundary, in case it crosses more than one. | 753 // boundary, in case it crosses more than one. |
733 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag
eLogicalHeight); | 754 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag
eLogicalHeight); |
(...skipping 1668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2402 | 2423 |
2403 SubtreeLayoutScope layoutScope(*childBox); | 2424 SubtreeLayoutScope layoutScope(*childBox); |
2404 LayoutState* layoutState = view()->layoutState(); | 2425 LayoutState* layoutState = view()->layoutState(); |
2405 bool isPaginated = layoutState->isPaginated(); | 2426 bool isPaginated = layoutState->isPaginated(); |
2406 if (isPaginated && !childBox->needsLayout()) | 2427 if (isPaginated && !childBox->needsLayout()) |
2407 childBox->markForPaginationRelayoutIfNeeded(layoutScope); | 2428 childBox->markForPaginationRelayoutIfNeeded(layoutScope); |
2408 | 2429 |
2409 childBox->layoutIfNeeded(); | 2430 childBox->layoutIfNeeded(); |
2410 | 2431 |
2411 if (isPaginated) { | 2432 if (isPaginated) { |
2412 LayoutUnit newLogicalTop = floatLogicalLocation.y(); | 2433 LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? to
LayoutBlockFlow(childBox) : nullptr; |
2413 | 2434 // The first piece of content inside the child may have set a strut
during layout. |
2414 LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? to
LayoutBlockFlow(childBox) : 0; | 2435 LayoutUnit strut = childBlockFlow ? childBlockFlow->paginationStrutP
ropagatedFromChild() : LayoutUnit(); |
2415 if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromC
hild()) { | 2436 if (!strut) { |
2416 // Some content inside this float has determined that we need to
move to the next | 2437 // Otherwise, if we are unsplittable and don't fit, move to the
next page or column |
2417 // page or column. | 2438 // if that helps the situation. |
2418 newLogicalTop += childBlockFlow->paginationStrutPropagatedFromCh
ild(); | 2439 strut = adjustForUnsplittableChild(*childBox, floatLogicalLocati
on.y()) - floatLogicalLocation.y(); |
2419 } else { | |
2420 // Now that we know the final height, check if we are unsplittab
le, and if we don't | |
2421 // fit at the current position, but would fit at the top of the
next page or | |
2422 // column, move there. | |
2423 newLogicalTop = adjustForUnsplittableChild(*childBox, newLogical
Top); | |
2424 } | 2440 } |
2425 | 2441 |
2426 if (newLogicalTop != floatLogicalLocation.y()) { | 2442 floatingObject.setPaginationStrut(strut); |
2427 floatingObject.setPaginationStrut(newLogicalTop - floatLogicalLo
cation.y()); | 2443 childBox->setPaginationStrut(strut); |
2428 | 2444 if (strut) { |
2429 floatLogicalLocation = computeLogicalLocationForFloat(floatingOb
ject, newLogicalTop); | 2445 floatLogicalLocation = computeLogicalLocationForFloat(floatingOb
ject, floatLogicalLocation.y() + strut); |
2430 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x())
; | 2446 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x())
; |
2431 | 2447 |
2432 setLogicalLeftForChild(*childBox, floatLogicalLocation.x() + chi
ldLogicalLeftMargin); | 2448 setLogicalLeftForChild(*childBox, floatLogicalLocation.x() + chi
ldLogicalLeftMargin); |
2433 setLogicalTopForChild(*childBox, floatLogicalLocation.y() + marg
inBeforeForChild(*childBox)); | 2449 setLogicalTopForChild(*childBox, floatLogicalLocation.y() + marg
inBeforeForChild(*childBox)); |
2434 | 2450 |
2435 if (childBox->isLayoutBlock()) | 2451 if (childBox->isLayoutBlock()) |
2436 childBox->setChildNeedsLayout(MarkOnlyThis); | 2452 childBox->setChildNeedsLayout(MarkOnlyThis); |
2437 childBox->layoutIfNeeded(); | 2453 childBox->layoutIfNeeded(); |
2438 } | 2454 } |
2439 } | 2455 } |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3086 FrameView* frameView = document().view(); | 3102 FrameView* frameView = document().view(); |
3087 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); | 3103 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); |
3088 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); | 3104 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); |
3089 if (size().height() < visibleHeight) | 3105 if (size().height() < visibleHeight) |
3090 top += (visibleHeight - size().height()) / 2; | 3106 top += (visibleHeight - size().height()) / 2; |
3091 setY(top); | 3107 setY(top); |
3092 dialog->setCentered(top); | 3108 dialog->setCentered(top); |
3093 } | 3109 } |
3094 | 3110 |
3095 } // namespace blink | 3111 } // namespace blink |
OLD | NEW |