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 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 // only block flows support strut propagation, but this may (and should) cha
nge in the future. | 688 // only block flows support strut propagation, but this may (and should) cha
nge in the future. |
689 // See crbug.com/539873 | 689 // See crbug.com/539873 |
690 LayoutUnit strutFromContent = childBlockFlow ? childBlockFlow->paginationStr
utPropagatedFromChild() : LayoutUnit(); | 690 LayoutUnit strutFromContent = childBlockFlow ? childBlockFlow->paginationStr
utPropagatedFromChild() : LayoutUnit(); |
691 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent; | 691 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent; |
692 | 692 |
693 // If the object has a page or column break value of "before", then we shoul
d shift to the top of the next page. | 693 // If the object has a page or column break value of "before", then we shoul
d shift to the top of the next page. |
694 LayoutUnit logicalTopAfterForcedBreak = applyBeforeBreak(child, logicalTop); | 694 LayoutUnit logicalTopAfterForcedBreak = applyBeforeBreak(child, logicalTop); |
695 | 695 |
696 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. | 696 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. |
697 LayoutUnit logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, l
ogicalTop); | 697 LayoutUnit logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, l
ogicalTop); |
698 LayoutUnit childLogicalHeight = child.logicalHeight(); | |
699 bool neededBreakForUnsplittable = logicalTopAfterUnsplittable != logicalTop; | |
700 if (neededBreakForUnsplittable) | |
701 setPageBreak(logicalTop, childLogicalHeight - (logicalTopAfterUnsplittab
le - logicalTop)); | |
702 | 698 |
703 // Some sanity checks: No matter what the reason is for pushing the child to
the next page or | 699 // Some sanity checks: No matter what the reason is for pushing the child to
the next page or |
704 // column, the amount should be the same. | 700 // column, the amount should be the same. |
705 ASSERT(!strutFromContent || logicalTopAfterForcedBreak == logicalTop || logi
calTopAfterForcedBreak == logicalTopWithContentStrut); | 701 ASSERT(!strutFromContent || logicalTopAfterForcedBreak == logicalTop || logi
calTopAfterForcedBreak == logicalTopWithContentStrut); |
706 ASSERT(!strutFromContent || logicalTopAfterUnsplittable == logicalTop || log
icalTopAfterUnsplittable == logicalTopWithContentStrut); | 702 ASSERT(!strutFromContent || logicalTopAfterUnsplittable == logicalTop || log
icalTopAfterUnsplittable == logicalTopWithContentStrut); |
707 ASSERT(logicalTopAfterUnsplittable == logicalTop || logicalTopAfterForcedBre
ak == logicalTop || logicalTopAfterUnsplittable == logicalTopAfterForcedBreak); | 703 ASSERT(logicalTopAfterUnsplittable == logicalTop || logicalTopAfterForcedBre
ak == logicalTop || logicalTopAfterUnsplittable == logicalTopAfterForcedBreak); |
708 | 704 |
709 LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut,
std::max(logicalTopAfterForcedBreak, logicalTopAfterUnsplittable)); | 705 LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut,
std::max(logicalTopAfterForcedBreak, logicalTopAfterUnsplittable)); |
710 LayoutUnit newLogicalTop = logicalTop; | 706 LayoutUnit newLogicalTop = logicalTop; |
711 if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) { | 707 if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) { |
712 ASSERT(paginationStrut > 0); | 708 ASSERT(paginationStrut > 0); |
713 // We are willing to propagate out to our parent block as long as we wer
e at the top of the block prior | 709 // We are willing to propagate out to our parent block as long as we wer
e at the top of the block prior |
714 // to collapsing our margins, and as long as we didn't clear or move as
a result of other pagination. | 710 // to collapsing our margins, and as long as we didn't clear or move as
a result of other pagination. |
715 if (atBeforeSideOfBlock && logicalTopAfterForcedBreak == logicalTop && a
llowsPaginationStrut()) { | 711 if (atBeforeSideOfBlock && logicalTopAfterForcedBreak == logicalTop && a
llowsPaginationStrut()) { |
716 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't | 712 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't |
717 // have all the information to do so (the strut only has the remaini
ng amount to push). Gecko gets this wrong too | 713 // have all the information to do so (the strut only has the remaini
ng amount to push). Gecko gets this wrong too |
718 // and pushes to the next page anyway, so not too concerned about it
. | 714 // and pushes to the next page anyway, so not too concerned about it
. |
719 paginationStrut += logicalTop; | 715 paginationStrut += logicalTop; |
720 if (isFloating()) | 716 if (isFloating()) |
721 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. | 717 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. |
722 setPaginationStrutPropagatedFromChild(paginationStrut); | 718 setPaginationStrutPropagatedFromChild(paginationStrut); |
723 if (childBlockFlow) | 719 if (childBlockFlow) |
724 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit
()); | 720 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit
()); |
725 } else { | 721 } else { |
726 child.setPaginationStrut(paginationStrut); | 722 child.setPaginationStrut(paginationStrut); |
727 newLogicalTop += paginationStrut; | 723 newLogicalTop += paginationStrut; |
728 } | 724 } |
729 } | 725 } |
730 | 726 |
731 if (!neededBreakForUnsplittable) { | 727 paginatedContentWasLaidOut(newLogicalTop); |
732 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical
Top)) { | |
733 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff
set(newLogicalTop, AssociateWithLatterPage); | |
734 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig
ht; | |
735 if (spaceShortage > 0) { | |
736 // If the child crosses a column boundary, report a break, in ca
se nothing inside it | |
737 // has already done so. The column balancer needs to know how mu
ch it has to stretch | |
738 // the columns to make more content fit. If no breaks are report
ed (but do occur), | |
739 // the balancer will have no clue. Only measure the space after
the last column | |
740 // boundary, in case it crosses more than one. | |
741 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag
eLogicalHeight); | |
742 setPageBreak(newLogicalTop, spaceShortageInLastColumn ? spaceSho
rtageInLastColumn : spaceShortage); | |
743 } else if (remainingLogicalHeight == pageLogicalHeight && offsetFrom
LogicalTopOfFirstPage() + child.logicalTop()) { | |
744 // We're at the very top of a page or column, and it's not the f
irst one. This child | |
745 // may turn out to be the smallest piece of content that causes
a page break, so we | |
746 // need to report it. | |
747 setPageBreak(newLogicalTop, childLogicalHeight); | |
748 } | |
749 } | |
750 } | |
751 | 728 |
752 // 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. |
753 setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop)); | 730 setLogicalHeight(logicalHeight() + (newLogicalTop - logicalTop)); |
754 | 731 |
755 // Return the final adjusted logical top. | 732 // Return the final adjusted logical top. |
756 return newLogicalTop; | 733 return newLogicalTop; |
757 } | 734 } |
758 | 735 |
759 static inline LayoutUnit calculateMinimumPageHeight(const ComputedStyle& style,
const RootInlineBox& lastLine) | 736 static inline LayoutUnit calculateMinimumPageHeight(const ComputedStyle& style,
const RootInlineBox& lastLine) |
760 { | 737 { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 | 800 |
824 int lineIndex = lineCount(&lineBox); | 801 int lineIndex = lineCount(&lineBox); |
825 if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow()
&& lineBreakToAvoidWidow() == lineIndex)) { | 802 if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow()
&& lineBreakToAvoidWidow() == lineIndex)) { |
826 // We need to insert a break now, either because there's no room for the
line in the | 803 // We need to insert a break now, either because there's no room for the
line in the |
827 // current column / page, or because we have determined that we need a b
reak to satisfy | 804 // current column / page, or because we have determined that we need a b
reak to satisfy |
828 // widow requirements. | 805 // widow requirements. |
829 if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIn
dex) { | 806 if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIn
dex) { |
830 clearShouldBreakAtLineToAvoidWidow(); | 807 clearShouldBreakAtLineToAvoidWidow(); |
831 setDidBreakAtLineToAvoidWidow(); | 808 setDidBreakAtLineToAvoidWidow(); |
832 } | 809 } |
833 setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight); | |
834 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, rema
iningLogicalHeight)) { | 810 if (shouldSetStrutOnBlock(*this, lineBox, logicalOffset, lineIndex, rema
iningLogicalHeight)) { |
835 // Note that when setting the strut on a block, it may be propagated
to parent blocks | 811 // Note that when setting the strut on a block, it may be propagated
to parent blocks |
836 // later on, if a block's logical top is flush with that of its pare
nt. We don't want | 812 // later on, if a block's logical top is flush with that of its pare
nt. We don't want |
837 // content-less portions (struts) at the beginning of a block before
a break, if it can | 813 // content-less portions (struts) at the beginning of a block before
a break, if it can |
838 // be avoided. After all, that's the reason for setting struts on bl
ocks and not lines | 814 // be avoided. After all, that's the reason for setting struts on bl
ocks and not lines |
839 // in the first place. | 815 // in the first place. |
840 LayoutUnit paginationStrut = remainingLogicalHeight + std::max<Layou
tUnit>(0, logicalOffset); | 816 LayoutUnit paginationStrut = remainingLogicalHeight + std::max<Layou
tUnit>(0, logicalOffset); |
841 if (isFloating()) | 817 if (isFloating()) |
842 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. | 818 paginationStrut += marginBefore(); // Floats' margins do not col
lapse with page or column boundaries. |
843 setPaginationStrutPropagatedFromChild(paginationStrut); | 819 setPaginationStrutPropagatedFromChild(paginationStrut); |
844 } else { | 820 } else { |
| 821 logicalOffset += remainingLogicalHeight; |
845 delta += remainingLogicalHeight; | 822 delta += remainingLogicalHeight; |
846 lineBox.setPaginationStrut(remainingLogicalHeight); | 823 lineBox.setPaginationStrut(remainingLogicalHeight); |
847 lineBox.setIsFirstAfterPageBreak(true); | 824 lineBox.setIsFirstAfterPageBreak(true); |
848 } | 825 } |
849 } else if (remainingLogicalHeight == pageLogicalHeight) { | 826 } else if (remainingLogicalHeight == pageLogicalHeight) { |
850 // We're at the very top of a page or column. | 827 // We're at the very top of a page or column. |
851 if (lineBox != firstRootBox()) | 828 if (lineBox != firstRootBox()) |
852 lineBox.setIsFirstAfterPageBreak(true); | 829 lineBox.setIsFirstAfterPageBreak(true); |
853 if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage()) | |
854 setPageBreak(logicalOffset, lineHeight); | |
855 } | 830 } |
| 831 |
| 832 paginatedContentWasLaidOut(logicalOffset); |
856 } | 833 } |
857 | 834 |
858 LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutU
nit logicalOffset) | 835 LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutU
nit logicalOffset) |
859 { | 836 { |
860 bool checkColumnBreaks = flowThreadContainingBlock(); | 837 bool checkColumnBreaks = flowThreadContainingBlock(); |
861 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); | 838 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); |
862 bool isUnsplittable = child.isUnsplittableForPagination() || (checkColumnBre
aks && child.style()->columnBreakInside() == PBAVOID) | 839 bool isUnsplittable = child.isUnsplittableForPagination() || (checkColumnBre
aks && child.style()->columnBreakInside() == PBAVOID) |
863 || (checkPageBreaks && child.style()->pageBreakInside() == PBAVOID); | 840 || (checkPageBreaks && child.style()->pageBreakInside() == PBAVOID); |
864 if (!isUnsplittable) | 841 if (!isUnsplittable) |
865 return logicalOffset; | 842 return logicalOffset; |
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1696 return childStyle.marginAfterCollapse() == MSEPARATE; | 1673 return childStyle.marginAfterCollapse() == MSEPARATE; |
1697 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 1674 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
1698 return childStyle.marginBeforeCollapse() == MSEPARATE; | 1675 return childStyle.marginBeforeCollapse() == MSEPARATE; |
1699 | 1676 |
1700 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 1677 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
1701 return false; | 1678 return false; |
1702 } | 1679 } |
1703 | 1680 |
1704 LayoutUnit LayoutBlockFlow::applyBeforeBreak(LayoutBox& child, LayoutUnit logica
lOffset) | 1681 LayoutUnit LayoutBlockFlow::applyBeforeBreak(LayoutBox& child, LayoutUnit logica
lOffset) |
1705 { | 1682 { |
1706 if (child.hasForcedBreakBefore()) { | 1683 if (child.hasForcedBreakBefore()) |
1707 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) { | |
1708 LayoutUnit offsetBreakAdjustment = 0; | |
1709 if (flowThread->addForcedColumnBreak(offsetFromLogicalTopOfFirstPage
() + logicalOffset, &child, true, &offsetBreakAdjustment)) | |
1710 return logicalOffset + offsetBreakAdjustment; | |
1711 } | |
1712 return nextPageLogicalTop(logicalOffset, AssociateWithFormerPage); | 1684 return nextPageLogicalTop(logicalOffset, AssociateWithFormerPage); |
1713 } | |
1714 return logicalOffset; | 1685 return logicalOffset; |
1715 } | 1686 } |
1716 | 1687 |
1717 LayoutUnit LayoutBlockFlow::applyAfterBreak(LayoutBox& child, LayoutUnit logical
Offset, MarginInfo& marginInfo) | 1688 LayoutUnit LayoutBlockFlow::applyAfterBreak(LayoutBox& child, LayoutUnit logical
Offset, MarginInfo& marginInfo) |
1718 { | 1689 { |
1719 if (child.hasForcedBreakAfter()) { | 1690 if (child.hasForcedBreakAfter()) { |
1720 // So our margin doesn't participate in the next collapsing steps. | 1691 // So our margin doesn't participate in the next collapsing steps. |
1721 marginInfo.clearMargin(); | 1692 marginInfo.clearMargin(); |
1722 | 1693 |
1723 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) { | |
1724 LayoutUnit offsetBreakAdjustment = 0; | |
1725 if (flowThread->addForcedColumnBreak(offsetFromLogicalTopOfFirstPage
() + logicalOffset, &child, false, &offsetBreakAdjustment)) | |
1726 return logicalOffset + offsetBreakAdjustment; | |
1727 } | |
1728 return nextPageLogicalTop(logicalOffset, AssociateWithFormerPage); | 1694 return nextPageLogicalTop(logicalOffset, AssociateWithFormerPage); |
1729 } | 1695 } |
1730 return logicalOffset; | 1696 return logicalOffset; |
1731 } | 1697 } |
1732 | 1698 |
1733 void LayoutBlockFlow::addOverflowFromFloats() | 1699 void LayoutBlockFlow::addOverflowFromFloats() |
1734 { | 1700 { |
1735 if (!m_floatingObjects) | 1701 if (!m_floatingObjects) |
1736 return; | 1702 return; |
1737 | 1703 |
(...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3074 FrameView* frameView = document().view(); | 3040 FrameView* frameView = document().view(); |
3075 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); | 3041 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); |
3076 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); | 3042 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); |
3077 if (size().height() < visibleHeight) | 3043 if (size().height() < visibleHeight) |
3078 top += (visibleHeight - size().height()) / 2; | 3044 top += (visibleHeight - size().height()) / 2; |
3079 setY(top); | 3045 setY(top); |
3080 dialog->setCentered(top); | 3046 dialog->setCentered(top); |
3081 } | 3047 } |
3082 | 3048 |
3083 } // namespace blink | 3049 } // namespace blink |
OLD | NEW |