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

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: code review 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.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
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
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