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

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

Issue 1375673004: Keep block pagination struts after layout, and store them before any type of break. (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 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
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.setPaginationStrut(LayoutUnit());
leviw_travelin_and_unemployed 2015/10/06 13:17:59 We should probably have a resetPaginationStrut() m
mstensho (USE GERRIT) 2015/10/06 14:01:45 Done.
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.
leviw_travelin_and_unemployed 2015/10/06 13:17:59 Seems bug-worthy for more context.
mstensho (USE GERRIT) 2015/10/06 14:01:45 Done.
702 LayoutUnit strutFromContent = childBlockFlow ? childBlockFlow->paginationStr utPropagatedFromChild() : LayoutUnit();
703 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent;
704
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. 705 // 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); 706 LayoutUnit logicalTopAfterForcedBreak = applyBeforeBreak(child, logicalTop);
690 707
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. 708 // 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; 709 LayoutUnit logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, l ogicalTop);
693 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil d(child, newLogicalTop); 710 LayoutUnit childLogicalHeight = child.logicalHeight();
711 bool neededBreakForUnsplittable = logicalTopAfterUnsplittable != logicalTop;
712 if (neededBreakForUnsplittable)
713 setPageBreak(logicalTop, childLogicalHeight - (logicalTopAfterUnsplittab le - logicalTop));
694 714
695 LayoutUnit paginationStrut = 0; 715 // Some sanity checks: No matter what the reason is for pushing the child to the next page or
696 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme nt - logicalTopBeforeUnsplittableAdjustment; 716 // column, the amount should be the same.
697 LayoutUnit childLogicalHeight = child.logicalHeight(); 717 ASSERT(!strutFromContent || logicalTopAfterForcedBreak == logicalTop || logi calTopAfterForcedBreak == logicalTopWithContentStrut);
698 if (unsplittableAdjustmentDelta) { 718 ASSERT(!strutFromContent || logicalTopAfterUnsplittable == logicalTop || log icalTopAfterUnsplittable == logicalTopWithContentStrut);
699 setPageBreak(newLogicalTop, childLogicalHeight - unsplittableAdjustmentD elta); 719 ASSERT(logicalTopAfterUnsplittable == logicalTop || logicalTopAfterForcedBre ak == logicalTop || logicalTopAfterUnsplittable == logicalTopAfterForcedBreak);
700 paginationStrut = unsplittableAdjustmentDelta;
701 } else if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromCh ild()) {
702 paginationStrut = childBlockFlow->paginationStrutPropagatedFromChild();
703 }
704 720
705 if (paginationStrut) { 721 LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut, std::max(logicalTopAfterForcedBreak, logicalTopAfterUnsplittable));
722 LayoutUnit newLogicalTop = logicalTop;
723 if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) {
724 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 725 // 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. 726 // 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()) { 727 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 728 // 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 729 // 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 . 730 // and pushes to the next page anyway, so not too concerned about it .
712 paginationStrut += logicalTop; 731 paginationStrut += logicalTop;
713 if (isFloating()) 732 if (isFloating())
714 paginationStrut += marginBefore(); // Floats' margins do not col lapse with page or column boundaries. 733 paginationStrut += marginBefore(); // Floats' margins do not col lapse with page or column boundaries.
715 setPaginationStrutPropagatedFromChild(paginationStrut); 734 setPaginationStrutPropagatedFromChild(paginationStrut);
716 if (childBlockFlow) 735 if (childBlockFlow)
717 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit ()); 736 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit ());
718 } else { 737 } else {
738 child.setPaginationStrut(paginationStrut);
719 newLogicalTop += paginationStrut; 739 newLogicalTop += paginationStrut;
720 } 740 }
721 } 741 }
722 742
723 if (!unsplittableAdjustmentDelta) { 743 if (!neededBreakForUnsplittable) {
724 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical Top)) { 744 if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(newLogical Top)) {
725 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff set(newLogicalTop, AssociateWithLatterPage); 745 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOff set(newLogicalTop, AssociateWithLatterPage);
726 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig ht; 746 LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeig ht;
727 if (spaceShortage > 0) { 747 if (spaceShortage > 0) {
728 // If the child crosses a column boundary, report a break, in ca se nothing inside it 748 // 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 749 // 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), 750 // 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 751 // the balancer will have no clue. Only measure the space after the last column
732 // boundary, in case it crosses more than one. 752 // boundary, in case it crosses more than one.
733 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag eLogicalHeight); 753 LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pag eLogicalHeight);
(...skipping 1668 matching lines...) Expand 10 before | Expand all | Expand 10 after
2402 2422
2403 SubtreeLayoutScope layoutScope(*childBox); 2423 SubtreeLayoutScope layoutScope(*childBox);
2404 LayoutState* layoutState = view()->layoutState(); 2424 LayoutState* layoutState = view()->layoutState();
2405 bool isPaginated = layoutState->isPaginated(); 2425 bool isPaginated = layoutState->isPaginated();
2406 if (isPaginated && !childBox->needsLayout()) 2426 if (isPaginated && !childBox->needsLayout())
2407 childBox->markForPaginationRelayoutIfNeeded(layoutScope); 2427 childBox->markForPaginationRelayoutIfNeeded(layoutScope);
2408 2428
2409 childBox->layoutIfNeeded(); 2429 childBox->layoutIfNeeded();
2410 2430
2411 if (isPaginated) { 2431 if (isPaginated) {
2412 LayoutUnit newLogicalTop = floatLogicalLocation.y(); 2432 // If we are unsplittable and don't fit, move to the next page or co lumn if that helps
2433 // the situation.
2434 LayoutUnit newLogicalTop = adjustForUnsplittableChild(*childBox, flo atLogicalLocation.y());
2435 LayoutUnit strutFromUnsplittable = newLogicalTop - floatLogicalLocat ion.y();
2436 LayoutUnit finalStrut;
2437 if (strutFromUnsplittable)
leviw_travelin_and_unemployed 2015/10/06 13:17:59 You switched the order of this logic from the old
mstensho (USE GERRIT) 2015/10/06 14:01:45 Seems that I had no good reason for making this ch
2438 finalStrut = strutFromUnsplittable;
2439 else if (LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFl ow() ? toLayoutBlockFlow(childBox) : nullptr)
2440 finalStrut = childBlockFlow->paginationStrutPropagatedFromChild( );
2413 2441
2414 LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? to LayoutBlockFlow(childBox) : 0; 2442 floatingObject.setPaginationStrut(finalStrut);
2415 if (childBlockFlow && childBlockFlow->paginationStrutPropagatedFromC hild()) { 2443 childBox->setPaginationStrut(finalStrut);
2416 // Some content inside this float has determined that we need to move to the next 2444 if (finalStrut) {
2417 // page or column. 2445 floatLogicalLocation = computeLogicalLocationForFloat(floatingOb ject, floatLogicalLocation.y() + finalStrut);
2418 newLogicalTop += childBlockFlow->paginationStrutPropagatedFromCh ild();
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 }
2425
2426 if (newLogicalTop != floatLogicalLocation.y()) {
2427 floatingObject.setPaginationStrut(newLogicalTop - floatLogicalLo cation.y());
2428
2429 floatLogicalLocation = computeLogicalLocationForFloat(floatingOb ject, newLogicalTop);
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/core.gypi ('k') | third_party/WebKit/Source/core/layout/LayoutBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698