Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(603)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp

Issue 1399493002: Column balancing refactoring. Don't propagate data during layout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698