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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 bool lastChildIsSelfCollapsingBlockWithClearance() const { return m_lastChil
dIsSelfCollapsingBlockWithClearance; } | 155 bool lastChildIsSelfCollapsingBlockWithClearance() const { return m_lastChil
dIsSelfCollapsingBlockWithClearance; } |
156 }; | 156 }; |
157 | 157 |
158 // Some features, such as floats, margin collapsing and fragmentation, require s
ome knowledge about | 158 // Some features, such as floats, margin collapsing and fragmentation, require s
ome knowledge about |
159 // things that happened when laying out previous block child siblings. Only look
ing at the object | 159 // things that happened when laying out previous block child siblings. Only look
ing at the object |
160 // currently being laid out isn't always enough. | 160 // currently being laid out isn't always enough. |
161 class BlockChildrenLayoutInfo { | 161 class BlockChildrenLayoutInfo { |
162 public: | 162 public: |
163 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow, LayoutUnit beforeEdge, L
ayoutUnit afterEdge) | 163 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow, LayoutUnit beforeEdge, L
ayoutUnit afterEdge) |
164 : m_marginInfo(blockFlow, beforeEdge, afterEdge) | 164 : m_marginInfo(blockFlow, beforeEdge, afterEdge) |
| 165 , m_previousBreakAfterValue(BreakAuto) |
165 , m_isAtFirstInFlowChild(true) { } | 166 , m_isAtFirstInFlowChild(true) { } |
166 | 167 |
167 const MarginInfo& marginInfo() const { return m_marginInfo; } | 168 const MarginInfo& marginInfo() const { return m_marginInfo; } |
168 MarginInfo& marginInfo() { return m_marginInfo; } | 169 MarginInfo& marginInfo() { return m_marginInfo; } |
169 LayoutUnit& previousFloatLogicalBottom() { return m_previousFloatLogicalBott
om; } | 170 LayoutUnit& previousFloatLogicalBottom() { return m_previousFloatLogicalBott
om; } |
170 | 171 |
| 172 EBreak previousBreakAfterValue() const { return m_previousBreakAfterValue; } |
| 173 void setPreviousBreakAfterValue(EBreak value) { m_previousBreakAfterValue =
value; } |
| 174 |
171 bool isAtFirstInFlowChild() const { return m_isAtFirstInFlowChild; } | 175 bool isAtFirstInFlowChild() const { return m_isAtFirstInFlowChild; } |
172 void clearIsAtFirstInFlowChild() { m_isAtFirstInFlowChild = false; } | 176 void clearIsAtFirstInFlowChild() { m_isAtFirstInFlowChild = false; } |
173 | 177 |
174 private: | 178 private: |
175 MarginInfo m_marginInfo; | 179 MarginInfo m_marginInfo; |
176 LayoutUnit m_previousFloatLogicalBottom; | 180 LayoutUnit m_previousFloatLogicalBottom; |
| 181 EBreak m_previousBreakAfterValue; |
177 bool m_isAtFirstInFlowChild; | 182 bool m_isAtFirstInFlowChild; |
178 }; | 183 }; |
179 | 184 |
180 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) | 185 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) |
181 : LayoutBlock(node) | 186 : LayoutBlock(node) |
182 { | 187 { |
183 static_assert(sizeof(MarginInfo) == sizeof(SameSizeAsMarginInfo), "MarginInf
o should stay small"); | 188 static_assert(sizeof(MarginInfo) == sizeof(SameSizeAsMarginInfo), "MarginInf
o should stay small"); |
184 setChildrenInline(true); | 189 setChildrenInline(true); |
185 } | 190 } |
186 | 191 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 // and subtract it from the maximal negative margin from both A and B to get
the | 374 // and subtract it from the maximal negative margin from both A and B to get
the |
370 // true collapsed margin. This algorithm is recursive, so when we finish lay
out() | 375 // true collapsed margin. This algorithm is recursive, so when we finish lay
out() |
371 // our block knows its current maximal positive/negative values. | 376 // our block knows its current maximal positive/negative values. |
372 // | 377 // |
373 // Start out by setting our margin values to our current margins. Table cell
s have | 378 // Start out by setting our margin values to our current margins. Table cell
s have |
374 // no margins, so we don't fill in the values for table cells. | 379 // no margins, so we don't fill in the values for table cells. |
375 if (!isTableCell()) { | 380 if (!isTableCell()) { |
376 initMaxMarginValues(); | 381 initMaxMarginValues(); |
377 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); | 382 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); |
378 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); | 383 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); |
| 384 } |
| 385 |
| 386 if (state.isPaginated()) { |
379 setPaginationStrutPropagatedFromChild(LayoutUnit()); | 387 setPaginationStrutPropagatedFromChild(LayoutUnit()); |
| 388 |
| 389 // Start with any applicable computed break-after and break-before value
s for this |
| 390 // object. During child layout, breakBefore will be joined with the brea
kBefore value of |
| 391 // the first in-flow child, and breakAfter will be joined with the break
After value of the |
| 392 // last in-flow child. This is done in order to honor the requirement th
at a class A break |
| 393 // point [1] may only exists *between* in-flow siblings (i.e. not before
the first child |
| 394 // and not after the last child). |
| 395 // |
| 396 // [1] https://drafts.csswg.org/css-break/#possible-breaks |
| 397 setBreakBefore(LayoutBlock::breakBefore()); |
| 398 setBreakAfter(LayoutBlock::breakAfter()); |
380 } | 399 } |
381 | 400 |
382 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | 401 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); |
383 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig
ht(); | 402 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig
ht(); |
384 LayoutUnit previousHeight = logicalHeight(); | 403 LayoutUnit previousHeight = logicalHeight(); |
385 setLogicalHeight(beforeEdge); | 404 setLogicalHeight(beforeEdge); |
386 | 405 |
387 m_paintInvalidationLogicalTop = LayoutUnit(); | 406 m_paintInvalidationLogicalTop = LayoutUnit(); |
388 m_paintInvalidationLogicalBottom = LayoutUnit(); | 407 m_paintInvalidationLogicalBottom = LayoutUnit(); |
389 if (!firstChild() && !isAnonymousBlock()) | 408 if (!firstChild() && !isAnonymousBlock()) |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 child.markForPaginationRelayoutIfNeeded(layoutScope); | 592 child.markForPaginationRelayoutIfNeeded(layoutScope); |
574 } | 593 } |
575 } | 594 } |
576 | 595 |
577 if (!child.needsLayout()) | 596 if (!child.needsLayout()) |
578 return false; | 597 return false; |
579 child.layout(); | 598 child.layout(); |
580 return true; | 599 return true; |
581 } | 600 } |
582 | 601 |
| 602 bool LayoutBlockFlow::insertForcedBreakBeforeChildIfNeeded(LayoutBox& child, Blo
ckChildrenLayoutInfo& layoutInfo) |
| 603 { |
| 604 if (layoutInfo.isAtFirstInFlowChild()) { |
| 605 // There's no class A break point before the first child (only *between*
siblings), so |
| 606 // steal its break value and join it with what we already have here. |
| 607 setBreakBefore(joinFragmentainerBreakValues(breakBefore(), child.breakBe
fore())); |
| 608 return false; |
| 609 } |
| 610 |
| 611 // Figure out if a forced break should be inserted in front of the child. If
we insert a forced |
| 612 // break, the margins on this child may not collapse with those preceding th
e break. |
| 613 EBreak classABreakPointValue = child.classABreakPointValue(layoutInfo.previo
usBreakAfterValue()); |
| 614 if (isForcedFragmentainerBreakValue(classABreakPointValue)) { |
| 615 layoutInfo.marginInfo().clearMargin(); |
| 616 LayoutUnit oldLogicalTop = logicalHeight(); |
| 617 LayoutUnit newLogicalTop = applyForcedBreak(oldLogicalTop, classABreakPo
intValue); |
| 618 setLogicalHeight(newLogicalTop); |
| 619 LayoutUnit paginationStrut = newLogicalTop - oldLogicalTop; |
| 620 child.setPaginationStrut(paginationStrut); |
| 621 return true; |
| 622 } |
| 623 return false; |
| 624 } |
| 625 |
583 void LayoutBlockFlow::layoutBlockChild(LayoutBox& child, BlockChildrenLayoutInfo
& layoutInfo) | 626 void LayoutBlockFlow::layoutBlockChild(LayoutBox& child, BlockChildrenLayoutInfo
& layoutInfo) |
584 { | 627 { |
585 MarginInfo& marginInfo = layoutInfo.marginInfo(); | 628 MarginInfo& marginInfo = layoutInfo.marginInfo(); |
586 LayoutBlockFlow* childLayoutBlockFlow = child.isLayoutBlockFlow() ? toLayout
BlockFlow(&child) : nullptr; | 629 LayoutBlockFlow* childLayoutBlockFlow = child.isLayoutBlockFlow() ? toLayout
BlockFlow(&child) : nullptr; |
587 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); | 630 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); |
588 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); | 631 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); |
589 | 632 |
590 // The child is a normal flow object. Compute the margins we will use for co
llapsing now. | 633 // The child is a normal flow object. Compute the margins we will use for co
llapsing now. |
591 child.computeAndSetBlockDirectionMargins(this); | 634 child.computeAndSetBlockDirectionMargins(this); |
592 | 635 |
593 // Try to guess our correct logical top position. In most cases this guess w
ill | 636 // Try to guess our correct logical top position. In most cases this guess w
ill |
594 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) | 637 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) |
595 // will we have to potentially relayout. | 638 // will we have to potentially relayout. |
596 LayoutUnit estimateWithoutPagination; | 639 LayoutUnit estimateWithoutPagination; |
597 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo
, estimateWithoutPagination); | 640 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, layoutInfo
, estimateWithoutPagination); |
598 | 641 |
599 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. | 642 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. |
600 LayoutRect oldRect = child.frameRect(); | 643 LayoutRect oldRect = child.frameRect(); |
601 | 644 |
602 // Use the estimated block position and lay out the child if needed. After c
hild layout, when | 645 // Use the estimated block position and lay out the child if needed. After c
hild layout, when |
603 // we have enough information to perform proper margin collapsing, float cle
aring and | 646 // we have enough information to perform proper margin collapsing, float cle
aring and |
604 // pagination, we may have to reposition and lay out again if the estimate w
as wrong. | 647 // pagination, we may have to reposition and lay out again if the estimate w
as wrong. |
605 bool childNeededLayout = positionAndLayoutOnceIfNeeded(child, logicalTopEsti
mate, layoutInfo); | 648 bool childNeededLayout = positionAndLayoutOnceIfNeeded(child, logicalTopEsti
mate, layoutInfo); |
606 | 649 |
607 // Cache if we are at the top of the block right now. | 650 // Cache if we are at the top of the block right now. |
608 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); | 651 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); |
609 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); | 652 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); |
610 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); | 653 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); |
611 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); | 654 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); |
| 655 bool paginated = view()->layoutState()->isPaginated(); |
| 656 |
| 657 // If there should be a forced break before the child, we need to insert it
before attempting |
| 658 // to collapse margins or apply clearance. |
| 659 bool forcedBreakWasInserted = paginated && insertForcedBreakBeforeChildIfNee
ded(child, layoutInfo); |
612 | 660 |
613 // Now determine the correct ypos based off examination of collapsing margin | 661 // Now determine the correct ypos based off examination of collapsing margin |
614 // values. | 662 // values. |
615 LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo, childI
sSelfCollapsing, childDiscardMarginBefore, childDiscardMarginAfter); | 663 LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo, childI
sSelfCollapsing, childDiscardMarginBefore, childDiscardMarginAfter); |
616 | 664 |
617 // Now check for clear. | 665 // Now check for clear. |
618 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfte
r; | 666 bool childDiscardMargin = childDiscardMarginBefore || childDiscardMarginAfte
r; |
619 LayoutUnit newLogicalTop = clearFloatsIfNeeded(child, marginInfo, oldPosMarg
inBefore, oldNegMarginBefore, logicalTopBeforeClear, childIsSelfCollapsing, chil
dDiscardMargin); | 667 LayoutUnit newLogicalTop = clearFloatsIfNeeded(child, marginInfo, oldPosMarg
inBefore, oldNegMarginBefore, logicalTopBeforeClear, childIsSelfCollapsing, chil
dDiscardMargin); |
620 | 668 |
621 // Now check for pagination. | 669 // If there's a forced break in front of this child, its final position has
already been |
622 bool paginated = view()->layoutState()->isPaginated(); | 670 // determined. Otherwise, see if there are other reasons for breaking before
it |
623 if (paginated) { | 671 // (break-inside:avoid, or not enough space for the first piece of child con
tent to fit in the |
| 672 // current fragmentainer), and adjust the position accordingly. |
| 673 if (paginated && !forcedBreakWasInserted) { |
624 if (estimateWithoutPagination != newLogicalTop) { | 674 if (estimateWithoutPagination != newLogicalTop) { |
625 // We got a new position due to clearance or margin collapsing. Befo
re we attempt to | 675 // We got a new position due to clearance or margin collapsing. Befo
re we attempt to |
626 // paginate (which may result in the position changing again), let's
try again at the | 676 // paginate (which may result in the position changing again), let's
try again at the |
627 // new position (since a new position may result in a new logical he
ight). | 677 // new position (since a new position may result in a new logical he
ight). |
628 positionAndLayoutOnceIfNeeded(child, newLogicalTop, layoutInfo); | 678 positionAndLayoutOnceIfNeeded(child, newLogicalTop, layoutInfo); |
629 } | 679 } |
630 | 680 |
631 newLogicalTop = adjustBlockChildForPagination(newLogicalTop, child, layo
utInfo, atBeforeSideOfBlock && logicalTopBeforeClear == newLogicalTop); | 681 newLogicalTop = adjustBlockChildForPagination(newLogicalTop, child, layo
utInfo, atBeforeSideOfBlock && logicalTopBeforeClear == newLogicalTop); |
632 } | 682 } |
633 | 683 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 if (childLayoutBlockFlow) | 718 if (childLayoutBlockFlow) |
669 addOverhangingFloats(childLayoutBlockFlow, !childNeededLayout); | 719 addOverhangingFloats(childLayoutBlockFlow, !childNeededLayout); |
670 | 720 |
671 // If the child moved, we have to invalidate its paint as well as any floati
ng/positioned | 721 // If the child moved, we have to invalidate its paint as well as any floati
ng/positioned |
672 // descendants. An exception is if we need a layout. In this case, we know w
e're going to | 722 // descendants. An exception is if we need a layout. In this case, we know w
e're going to |
673 // invalidate our paint (and the child) anyway. | 723 // invalidate our paint (and the child) anyway. |
674 if (!selfNeedsLayout() && (childOffset.width() || childOffset.height())) | 724 if (!selfNeedsLayout() && (childOffset.width() || childOffset.height())) |
675 child.invalidatePaintForOverhangingFloats(true); | 725 child.invalidatePaintForOverhangingFloats(true); |
676 | 726 |
677 if (paginated) { | 727 if (paginated) { |
678 // Check for an after page/column break. | 728 // Keep track of the break-after value of the child, so that it can be j
oined with the |
679 LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInf
o); | 729 // break-before value of the next in-flow object at the next class A bre
ak point. |
680 if (newHeight != size().height()) | 730 layoutInfo.setPreviousBreakAfterValue(child.breakAfter()); |
681 setLogicalHeight(newHeight); | |
682 } | 731 } |
683 | 732 |
684 if (child.isLayoutMultiColumnSpannerPlaceholder()) { | 733 if (child.isLayoutMultiColumnSpannerPlaceholder()) { |
685 // The actual column-span:all element is positioned by this placeholder
child. | 734 // The actual column-span:all element is positioned by this placeholder
child. |
686 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child)); | 735 positionSpannerDescendant(toLayoutMultiColumnSpannerPlaceholder(child)); |
687 } | 736 } |
688 } | 737 } |
689 | 738 |
690 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
LayoutBox& child, BlockChildrenLayoutInfo& layoutInfo, bool atBeforeSideOfBlock
) | 739 LayoutUnit LayoutBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTop,
LayoutBox& child, BlockChildrenLayoutInfo& layoutInfo, bool atBeforeSideOfBlock
) |
691 { | 740 { |
| 741 // Forced breaks trumps unforced ones, and if we have a forced break, we sho
uldn't even be here. |
| 742 ASSERT(layoutInfo.isAtFirstInFlowChild() || !isForcedFragmentainerBreakValue
(child.classABreakPointValue(layoutInfo.previousBreakAfterValue()))); |
| 743 |
692 LayoutBlockFlow* childBlockFlow = child.isLayoutBlockFlow() ? toLayoutBlockF
low(&child) : 0; | 744 LayoutBlockFlow* childBlockFlow = child.isLayoutBlockFlow() ? toLayoutBlockF
low(&child) : 0; |
693 | 745 |
694 // Calculate the pagination strut for this child. A strut may come from thre
e sources: | 746 // See if we need a soft (unforced) break in front of this child, and set th
e pagination strut |
| 747 // in that case. An unforced break may come from two sources: |
695 // 1. The first piece of content inside the child doesn't fit in the current
page or column | 748 // 1. The first piece of content inside the child doesn't fit in the current
page or column |
696 // 2. A forced break before the child | 749 // 2. The child itself has breaking restrictions (break-inside:avoid, replac
ed content, etc.) |
697 // 3. The child itself is unsplittable and doesn't fit in the current page o
r column. | 750 // and doesn't fully fit in the current page or column. |
698 // | 751 // |
699 // No matter which source, if we need to insert a strut, it should always ta
ke us to the exact | 752 // No matter which source, if we need to insert a strut, it should always ta
ke us to the exact |
700 // top of a page or column further ahead, or be zero. | 753 // top of a page or column further ahead, or be zero. |
701 | 754 |
702 // We're now going to calculate the child's final pagination strut. We may e
nd up propagating | 755 // We're now going to calculate the child's final pagination strut. We may e
nd up propagating |
703 // it to its containing block (|this|), so reset it first. | 756 // it to its containing block (|this|), so reset it first. |
704 child.resetPaginationStrut(); | 757 child.resetPaginationStrut(); |
705 | 758 |
706 // The first piece of content inside the child may have set a strut during l
ayout. Currently, | 759 // The first piece of content inside the child may have set a strut during l
ayout. Currently, |
707 // only block flows support strut propagation, but this may (and should) cha
nge in the future. | 760 // only block flows support strut propagation, but this may (and should) cha
nge in the future. |
708 // See crbug.com/539873 | 761 // See crbug.com/539873 |
709 LayoutUnit strutFromContent = childBlockFlow ? childBlockFlow->paginationStr
utPropagatedFromChild() : LayoutUnit(); | 762 LayoutUnit strutFromContent = childBlockFlow ? childBlockFlow->paginationStr
utPropagatedFromChild() : LayoutUnit(); |
710 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent; | 763 LayoutUnit logicalTopWithContentStrut = logicalTop + strutFromContent; |
711 | 764 |
712 // If the object has a page or column break value of "before", then we shoul
d shift to the top of the next page. | |
713 LayoutUnit logicalTopAfterForcedBreak = applyBeforeBreak(child, logicalTop); | |
714 | |
715 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. | 765 // For replaced elements and scrolled elements, we want to shift them to the
next page if they don't fit on the current one. |
716 LayoutUnit logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, l
ogicalTop); | 766 LayoutUnit logicalTopAfterUnsplittable = adjustForUnsplittableChild(child, l
ogicalTop); |
717 | 767 |
718 // Pick the largest offset. Tall unsplittable content may take us to a page
or column further | 768 // Pick the largest offset. Tall unsplittable content may take us to a page
or column further |
719 // ahead than the next one. | 769 // ahead than the next one. |
720 LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut,
std::max(logicalTopAfterForcedBreak, logicalTopAfterUnsplittable)); | 770 LayoutUnit logicalTopAfterPagination = std::max(logicalTopWithContentStrut,
logicalTopAfterUnsplittable); |
721 LayoutUnit newLogicalTop = logicalTop; | 771 LayoutUnit newLogicalTop = logicalTop; |
722 if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) { | 772 if (LayoutUnit paginationStrut = logicalTopAfterPagination - logicalTop) { |
723 ASSERT(paginationStrut > 0); | 773 ASSERT(paginationStrut > 0); |
724 // If we're not at the first in-flow child, there's a class A break poin
t before the child. If we *are* at the | 774 // If we're not at the first in-flow child, there's a class A break poin
t before the child. If we *are* at the |
725 // first in-flow child, but the child isn't flush with the content edge
of its container, due to e.g. clearance, | 775 // first in-flow child, but the child isn't flush with the content edge
of its container, due to e.g. clearance, |
726 // there's a class C break point before the child. Otherwise we should p
ropagate the strut to our parent block, | 776 // there's a class C break point before the child. Otherwise we should p
ropagate the strut to our parent block, |
727 // and attempt to break there instead. See https://drafts.csswg.org/css-
break/#possible-breaks | 777 // and attempt to break there instead. See https://drafts.csswg.org/css-
break/#possible-breaks |
728 if (layoutInfo.isAtFirstInFlowChild() && atBeforeSideOfBlock && logicalT
opAfterForcedBreak == logicalTop && allowsPaginationStrut()) { | 778 if (layoutInfo.isAtFirstInFlowChild() && atBeforeSideOfBlock && allowsPa
ginationStrut()) { |
729 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't | 779 // FIXME: Should really check if we're exceeding the page height bef
ore propagating the strut, but we don't |
730 // have all the information to do so (the strut only has the remaini
ng amount to push). Gecko gets this wrong too | 780 // have all the information to do so (the strut only has the remaini
ng amount to push). Gecko gets this wrong too |
731 // and pushes to the next page anyway, so not too concerned about it
. | 781 // and pushes to the next page anyway, so not too concerned about it
. |
732 paginationStrut += logicalTop + marginBeforeIfFloating(); | 782 paginationStrut += logicalTop + marginBeforeIfFloating(); |
733 setPaginationStrutPropagatedFromChild(paginationStrut); | 783 setPaginationStrutPropagatedFromChild(paginationStrut); |
734 if (childBlockFlow) | 784 if (childBlockFlow) |
735 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit
()); | 785 childBlockFlow->setPaginationStrutPropagatedFromChild(LayoutUnit
()); |
736 } else { | 786 } else { |
737 child.setPaginationStrut(paginationStrut); | 787 child.setPaginationStrut(paginationStrut); |
738 newLogicalTop += paginationStrut; | 788 newLogicalTop += paginationStrut; |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 | 1092 |
1043 child->setMayNeedPaintInvalidation(); | 1093 child->setMayNeedPaintInvalidation(); |
1044 | 1094 |
1045 if (childToExclude == child) | 1095 if (childToExclude == child) |
1046 continue; // Skip this child, since it will be positioned by the spe
cialized subclass (fieldsets and ruby runs). | 1096 continue; // Skip this child, since it will be positioned by the spe
cialized subclass (fieldsets and ruby runs). |
1047 | 1097 |
1048 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *child); | 1098 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *child); |
1049 | 1099 |
1050 if (child->isOutOfFlowPositioned()) { | 1100 if (child->isOutOfFlowPositioned()) { |
1051 child->containingBlock()->insertPositionedObject(child); | 1101 child->containingBlock()->insertPositionedObject(child); |
1052 adjustPositionedBlock(*child, marginInfo); | 1102 adjustPositionedBlock(*child, layoutInfo); |
1053 continue; | 1103 continue; |
1054 } | 1104 } |
1055 if (child->isFloating()) { | 1105 if (child->isFloating()) { |
1056 insertFloatingObject(*child); | 1106 insertFloatingObject(*child); |
1057 adjustFloatingBlock(marginInfo); | 1107 adjustFloatingBlock(marginInfo); |
1058 continue; | 1108 continue; |
1059 } | 1109 } |
1060 if (child->isColumnSpanAll()) { | 1110 if (child->isColumnSpanAll()) { |
1061 // This is not the containing block of the spanner. The spanner's pl
aceholder will lay | 1111 // This is not the containing block of the spanner. The spanner's pl
aceholder will lay |
1062 // it out in due course. For now we just need to consult our flow th
read, so that the | 1112 // it out in due course. For now we just need to consult our flow th
read, so that the |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 // into the margin area of the self-collapsing block then the float it c
lears is now intruding into |child|. Layout again so that we can look for | 1374 // into the margin area of the self-collapsing block then the float it c
lears is now intruding into |child|. Layout again so that we can look for |
1325 // floats in the parent that overhang |child|'s new logical top. | 1375 // floats in the parent that overhang |child|'s new logical top. |
1326 bool logicalTopIntrudesIntoFloat = logicalTop < beforeCollapseLogicalTop
; | 1376 bool logicalTopIntrudesIntoFloat = logicalTop < beforeCollapseLogicalTop
; |
1327 if (logicalTopIntrudesIntoFloat && containsFloats() && !child.avoidsFloa
ts() && lowestFloatLogicalBottom() > logicalTop) | 1377 if (logicalTopIntrudesIntoFloat && containsFloats() && !child.avoidsFloa
ts() && lowestFloatLogicalBottom() > logicalTop) |
1328 child.setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReaso
n::AncestorMarginCollapsing); | 1378 child.setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReaso
n::AncestorMarginCollapsing); |
1329 } | 1379 } |
1330 | 1380 |
1331 return logicalTop; | 1381 return logicalTop; |
1332 } | 1382 } |
1333 | 1383 |
1334 void LayoutBlockFlow::adjustPositionedBlock(LayoutBox& child, const MarginInfo&
marginInfo) | 1384 void LayoutBlockFlow::adjustPositionedBlock(LayoutBox& child, const BlockChildre
nLayoutInfo& layoutInfo) |
1335 { | 1385 { |
1336 LayoutUnit logicalTop = logicalHeight(); | 1386 LayoutUnit logicalTop = logicalHeight(); |
| 1387 |
| 1388 // Forced breaks are only specified on in-flow objects, but auto-positioned
out-of-flow objects |
| 1389 // may be affected by a break-after value of the previous in-flow object. |
| 1390 if (view()->layoutState()->isPaginated()) |
| 1391 logicalTop = applyForcedBreak(logicalTop, layoutInfo.previousBreakAfterV
alue()); |
| 1392 |
1337 updateStaticInlinePositionForChild(child, logicalTop); | 1393 updateStaticInlinePositionForChild(child, logicalTop); |
1338 | 1394 |
| 1395 const MarginInfo& marginInfo = layoutInfo.marginInfo(); |
1339 if (!marginInfo.canCollapseWithMarginBefore()) { | 1396 if (!marginInfo.canCollapseWithMarginBefore()) { |
1340 // Positioned blocks don't collapse margins, so add the margin provided
by | 1397 // Positioned blocks don't collapse margins, so add the margin provided
by |
1341 // the container now. The child's own margin is added later when calcula
ting its logical top. | 1398 // the container now. The child's own margin is added later when calcula
ting its logical top. |
1342 LayoutUnit collapsedBeforePos = marginInfo.positiveMargin(); | 1399 LayoutUnit collapsedBeforePos = marginInfo.positiveMargin(); |
1343 LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin(); | 1400 LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin(); |
1344 logicalTop += collapsedBeforePos - collapsedBeforeNeg; | 1401 logicalTop += collapsedBeforePos - collapsedBeforeNeg; |
1345 } | 1402 } |
1346 | 1403 |
1347 PaintLayer* childLayer = child.layer(); | 1404 PaintLayer* childLayer = child.layer(); |
1348 if (childLayer->staticBlockPosition() != logicalTop) | 1405 if (childLayer->staticBlockPosition() != logicalTop) |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 // If we have a 'clear' value but also have a margin we may not actually req
uire clearance to move past any floats. | 1543 // If we have a 'clear' value but also have a margin we may not actually req
uire clearance to move past any floats. |
1487 // If that's the case we want to be sure we estimate the correct position in
cluding margins after any floats rather | 1544 // If that's the case we want to be sure we estimate the correct position in
cluding margins after any floats rather |
1488 // than use 'clearance' later which could give us the wrong position. | 1545 // than use 'clearance' later which could give us the wrong position. |
1489 if (grandchildBox->style()->clear() != ClearNone && childBlockFlow->marginBe
foreForChild(*grandchildBox) == 0) | 1546 if (grandchildBox->style()->clear() != ClearNone && childBlockFlow->marginBe
foreForChild(*grandchildBox) == 0) |
1490 return; | 1547 return; |
1491 | 1548 |
1492 // Collapse the margin of the grandchild box with our own to produce an esti
mate. | 1549 // Collapse the margin of the grandchild box with our own to produce an esti
mate. |
1493 childBlockFlow->marginBeforeEstimateForChild(*grandchildBox, positiveMarginB
efore, negativeMarginBefore, discardMarginBefore); | 1550 childBlockFlow->marginBeforeEstimateForChild(*grandchildBox, positiveMarginB
efore, negativeMarginBefore, discardMarginBefore); |
1494 } | 1551 } |
1495 | 1552 |
1496 LayoutUnit LayoutBlockFlow::estimateLogicalTopPosition(LayoutBox& child, const M
arginInfo& marginInfo, LayoutUnit& estimateWithoutPagination) | 1553 LayoutUnit LayoutBlockFlow::estimateLogicalTopPosition(LayoutBox& child, const B
lockChildrenLayoutInfo& layoutInfo, LayoutUnit& estimateWithoutPagination) |
1497 { | 1554 { |
| 1555 const MarginInfo& marginInfo = layoutInfo.marginInfo(); |
1498 // FIXME: We need to eliminate the estimation of vertical position, because
when it's wrong we sometimes trigger a pathological | 1556 // FIXME: We need to eliminate the estimation of vertical position, because
when it's wrong we sometimes trigger a pathological |
1499 // relayout if there are intruding floats. | 1557 // relayout if there are intruding floats. |
1500 LayoutUnit logicalTopEstimate = logicalHeight(); | 1558 LayoutUnit logicalTopEstimate = logicalHeight(); |
| 1559 LayoutUnit positiveMarginBefore; |
| 1560 LayoutUnit negativeMarginBefore; |
| 1561 bool discardMarginBefore = false; |
1501 if (!marginInfo.canCollapseWithMarginBefore()) { | 1562 if (!marginInfo.canCollapseWithMarginBefore()) { |
1502 LayoutUnit positiveMarginBefore; | |
1503 LayoutUnit negativeMarginBefore; | |
1504 bool discardMarginBefore = false; | |
1505 if (child.selfNeedsLayout()) { | 1563 if (child.selfNeedsLayout()) { |
1506 // Try to do a basic estimation of how the collapse is going to go. | 1564 // Try to do a basic estimation of how the collapse is going to go. |
1507 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMa
rginBefore, discardMarginBefore); | 1565 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMa
rginBefore, discardMarginBefore); |
1508 } else { | 1566 } else { |
1509 // Use the cached collapsed margin values from a previous layout. Mo
st of the time they | 1567 // Use the cached collapsed margin values from a previous layout. Mo
st of the time they |
1510 // will be right. | 1568 // will be right. |
1511 LayoutBlockFlow::MarginValues marginValues = marginValuesForChild(ch
ild); | 1569 LayoutBlockFlow::MarginValues marginValues = marginValuesForChild(ch
ild); |
1512 positiveMarginBefore = std::max(positiveMarginBefore, marginValues.p
ositiveMarginBefore()); | 1570 positiveMarginBefore = std::max(positiveMarginBefore, marginValues.p
ositiveMarginBefore()); |
1513 negativeMarginBefore = std::max(negativeMarginBefore, marginValues.n
egativeMarginBefore()); | 1571 negativeMarginBefore = std::max(negativeMarginBefore, marginValues.n
egativeMarginBefore()); |
1514 discardMarginBefore = mustDiscardMarginBeforeForChild(child); | 1572 discardMarginBefore = mustDiscardMarginBeforeForChild(child); |
1515 } | 1573 } |
1516 | 1574 |
1517 // Collapse the result with our current margins. | 1575 // Collapse the result with our current margins. |
1518 if (!discardMarginBefore) | 1576 if (!discardMarginBefore) |
1519 logicalTopEstimate += std::max(marginInfo.positiveMargin(), positive
MarginBefore) - std::max(marginInfo.negativeMargin(), negativeMarginBefore); | 1577 logicalTopEstimate += std::max(marginInfo.positiveMargin(), positive
MarginBefore) - std::max(marginInfo.negativeMargin(), negativeMarginBefore); |
1520 } | 1578 } |
1521 | 1579 |
1522 // Adjust logicalTopEstimate down to the next page if the margins are so lar
ge that we don't fit on the current | 1580 // Adjust logicalTopEstimate down to the next page if the margins are so lar
ge that we don't fit on the current |
1523 // page. | 1581 // page. |
1524 LayoutState* layoutState = view()->layoutState(); | 1582 LayoutState* layoutState = view()->layoutState(); |
1525 if (layoutState->isPaginated() && isPageLogicalHeightKnown(logicalHeight())
&& logicalTopEstimate > logicalHeight()) | 1583 if (layoutState->isPaginated() && isPageLogicalHeightKnown(logicalHeight())
&& logicalTopEstimate > logicalHeight()) |
1526 logicalTopEstimate = std::min(logicalTopEstimate, nextPageLogicalTop(log
icalHeight(), AssociateWithLatterPage)); | 1584 logicalTopEstimate = std::min(logicalTopEstimate, nextPageLogicalTop(log
icalHeight(), AssociateWithLatterPage)); |
1527 | 1585 |
1528 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); | 1586 logicalTopEstimate += getClearDelta(&child, logicalTopEstimate); |
1529 | 1587 |
1530 estimateWithoutPagination = logicalTopEstimate; | 1588 estimateWithoutPagination = logicalTopEstimate; |
1531 | 1589 |
1532 if (layoutState->isPaginated()) { | 1590 if (layoutState->isPaginated()) { |
1533 // If the object has a page or column break value of "before", then we s
hould shift to the top of the next page. | 1591 if (!layoutInfo.isAtFirstInFlowChild()) { |
1534 logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate); | 1592 // Estimate the need for a forced break in front of this child. The
final break policy |
| 1593 // at this class A break point isn't known until we have laid out th
e children of |
| 1594 // |child|. There may be forced break-before values set on first-chi
ldren inside that |
| 1595 // get propagated up to the child. Just make an estimate with what w
e know so far. |
| 1596 EBreak breakValue = child.classABreakPointValue(layoutInfo.previousB
reakAfterValue()); |
| 1597 if (isForcedFragmentainerBreakValue(breakValue)) { |
| 1598 logicalTopEstimate = applyForcedBreak(logicalHeight(), breakValu
e); |
| 1599 // Disregard previous margins, since they will collapse with the
fragmentainer |
| 1600 // boundary, due to the forced break. Only apply margins that ha
ve been specified |
| 1601 // on the child or its descendants. |
| 1602 if (!discardMarginBefore) |
| 1603 logicalTopEstimate += positiveMarginBefore - negativeMarginB
efore; |
| 1604 |
| 1605 // Clearance may already have taken us past the beginning of the
next |
| 1606 // fragmentainer. |
| 1607 return std::max(estimateWithoutPagination, logicalTopEstimate); |
| 1608 } |
| 1609 } |
1535 | 1610 |
1536 // For replaced elements and scrolled elements, we want to shift them to
the next page if they don't fit on the current one. | 1611 // For replaced elements and scrolled elements, we want to shift them to
the next page if they don't fit on the current one. |
1537 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimat
e); | 1612 logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimat
e); |
1538 } | 1613 } |
1539 | 1614 |
1540 return logicalTopEstimate; | 1615 return logicalTopEstimate; |
1541 } | 1616 } |
1542 | 1617 |
1543 void LayoutBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) | 1618 void LayoutBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo) |
1544 { | 1619 { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 | 1658 |
1584 // Now add in our bottom border/padding. | 1659 // Now add in our bottom border/padding. |
1585 setLogicalHeight(logicalHeight() + afterSide); | 1660 setLogicalHeight(logicalHeight() + afterSide); |
1586 | 1661 |
1587 // Negative margins can cause our height to shrink below our minimal height
(border/padding). | 1662 // Negative margins can cause our height to shrink below our minimal height
(border/padding). |
1588 // If this happens, ensure that the computed height is increased to the mini
mal height. | 1663 // If this happens, ensure that the computed height is increased to the mini
mal height. |
1589 setLogicalHeight(std::max(logicalHeight(), beforeSide + afterSide)); | 1664 setLogicalHeight(std::max(logicalHeight(), beforeSide + afterSide)); |
1590 | 1665 |
1591 // Update our bottom collapsed margin info. | 1666 // Update our bottom collapsed margin info. |
1592 setCollapsedBottomMargin(marginInfo); | 1667 setCollapsedBottomMargin(marginInfo); |
| 1668 |
| 1669 // There's no class A break point right after the last child, only *between*
siblings. So |
| 1670 // propagate the break-after value, and keep looking for a class A break poi
nt (at the next |
| 1671 // in-flow block-level object), where we'll join this break-after value with
the break-before |
| 1672 // value there. |
| 1673 if (view()->layoutState()->isPaginated() && lastChild) |
| 1674 setBreakAfter(joinFragmentainerBreakValues(breakAfter(), lastChild->brea
kAfter())); |
1593 } | 1675 } |
1594 | 1676 |
1595 void LayoutBlockFlow::setMustDiscardMarginBefore(bool value) | 1677 void LayoutBlockFlow::setMustDiscardMarginBefore(bool value) |
1596 { | 1678 { |
1597 if (style()->marginBeforeCollapse() == MarginCollapseDiscard) { | 1679 if (style()->marginBeforeCollapse() == MarginCollapseDiscard) { |
1598 ASSERT(value); | 1680 ASSERT(value); |
1599 return; | 1681 return; |
1600 } | 1682 } |
1601 | 1683 |
1602 if (!m_rareData && !value) | 1684 if (!m_rareData && !value) |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 const ComputedStyle& childStyle = child.styleRef(); | 1782 const ComputedStyle& childStyle = child.styleRef(); |
1701 if (!child.isWritingModeRoot()) | 1783 if (!child.isWritingModeRoot()) |
1702 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; | 1784 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; |
1703 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 1785 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
1704 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; | 1786 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; |
1705 | 1787 |
1706 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 1788 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
1707 return false; | 1789 return false; |
1708 } | 1790 } |
1709 | 1791 |
1710 LayoutUnit LayoutBlockFlow::applyBeforeBreak(LayoutBox& child, LayoutUnit logica
lOffset) | 1792 LayoutUnit LayoutBlockFlow::applyForcedBreak(LayoutUnit logicalOffset, EBreak br
eakValue) |
1711 { | 1793 { |
1712 if (child.hasForcedBreakBefore()) | 1794 // TODO(mstensho): honor breakValue. There are different types of forced bre
aks. We currently |
| 1795 // just assume that we want to break to the top of the next fragmentainer of
the fragmentation |
| 1796 // context we're in. However, we may want to find the next left or right pag
e - even if we're |
| 1797 // inside a multicol container when printing. |
| 1798 if (isForcedFragmentainerBreakValue(breakValue)) |
1713 return nextPageLogicalTop(logicalOffset, AssociateWithFormerPage); | 1799 return nextPageLogicalTop(logicalOffset, AssociateWithFormerPage); |
1714 return logicalOffset; | 1800 return logicalOffset; |
1715 } | 1801 } |
1716 | 1802 |
1717 LayoutUnit LayoutBlockFlow::applyAfterBreak(LayoutBox& child, LayoutUnit logical
Offset, MarginInfo& marginInfo) | 1803 void LayoutBlockFlow::setBreakBefore(EBreak breakValue) |
1718 { | 1804 { |
1719 if (child.hasForcedBreakAfter()) { | 1805 if (breakValue != BreakAuto && !isBreakBetweenControllable(breakValue)) |
1720 // So our margin doesn't participate in the next collapsing steps. | 1806 breakValue = BreakAuto; |
1721 marginInfo.clearMargin(); | 1807 if (breakValue == BreakAuto && !m_rareData) |
| 1808 return; |
| 1809 ensureRareData().m_breakBefore = breakValue; |
| 1810 } |
1722 | 1811 |
1723 return nextPageLogicalTop(logicalOffset, AssociateWithFormerPage); | 1812 void LayoutBlockFlow::setBreakAfter(EBreak breakValue) |
1724 } | 1813 { |
1725 return logicalOffset; | 1814 if (breakValue != BreakAuto && !isBreakBetweenControllable(breakValue)) |
| 1815 breakValue = BreakAuto; |
| 1816 if (breakValue == BreakAuto && !m_rareData) |
| 1817 return; |
| 1818 ensureRareData().m_breakAfter = breakValue; |
| 1819 } |
| 1820 |
| 1821 EBreak LayoutBlockFlow::breakBefore() const |
| 1822 { |
| 1823 return m_rareData ? static_cast<EBreak>(m_rareData->m_breakBefore) : BreakAu
to; |
| 1824 } |
| 1825 |
| 1826 EBreak LayoutBlockFlow::breakAfter() const |
| 1827 { |
| 1828 return m_rareData ? static_cast<EBreak>(m_rareData->m_breakAfter) : BreakAut
o; |
1726 } | 1829 } |
1727 | 1830 |
1728 void LayoutBlockFlow::addOverflowFromFloats() | 1831 void LayoutBlockFlow::addOverflowFromFloats() |
1729 { | 1832 { |
1730 if (!m_floatingObjects) | 1833 if (!m_floatingObjects) |
1731 return; | 1834 return; |
1732 | 1835 |
1733 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 1836 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
1734 FloatingObjectSetIterator end = floatingObjectSet.end(); | 1837 FloatingObjectSetIterator end = floatingObjectSet.end(); |
1735 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { | 1838 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2404 | 2507 |
2405 // FIXME Investigate if this can be removed. crbug.com/370006 | 2508 // FIXME Investigate if this can be removed. crbug.com/370006 |
2406 childBox->setMayNeedPaintInvalidation(); | 2509 childBox->setMayNeedPaintInvalidation(); |
2407 | 2510 |
2408 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ?
marginStartForChild(*childBox) : marginEndForChild(*childBox); | 2511 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ?
marginStartForChild(*childBox) : marginEndForChild(*childBox); |
2409 if (childBox->style()->clear() & ClearLeft) | 2512 if (childBox->style()->clear() & ClearLeft) |
2410 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Left), logicalTop); | 2513 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Left), logicalTop); |
2411 if (childBox->style()->clear() & ClearRight) | 2514 if (childBox->style()->clear() & ClearRight) |
2412 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Right), logicalTop); | 2515 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Right), logicalTop); |
2413 | 2516 |
| 2517 bool isPaginated = view()->layoutState()->isPaginated(); |
| 2518 if (isPaginated && !childrenInline()) { |
| 2519 // Forced breaks are inserted at class A break points. Floats may be
affected by a |
| 2520 // break-after value on the previous in-flow sibling. |
| 2521 if (LayoutBox* previousInFlowBox = childBox->previousInFlowSiblingBo
x()) |
| 2522 logicalTop = applyForcedBreak(logicalTop, previousInFlowBox->bre
akAfter()); |
| 2523 } |
| 2524 |
2414 LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floati
ngObject, logicalTop); | 2525 LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floati
ngObject, logicalTop); |
2415 | 2526 |
2416 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); | 2527 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); |
2417 | 2528 |
2418 setLogicalLeftForChild(*childBox, floatLogicalLocation.x() + childLogica
lLeftMargin); | 2529 setLogicalLeftForChild(*childBox, floatLogicalLocation.x() + childLogica
lLeftMargin); |
2419 setLogicalTopForChild(*childBox, floatLogicalLocation.y() + marginBefore
ForChild(*childBox)); | 2530 setLogicalTopForChild(*childBox, floatLogicalLocation.y() + marginBefore
ForChild(*childBox)); |
2420 | 2531 |
2421 SubtreeLayoutScope layoutScope(*childBox); | 2532 SubtreeLayoutScope layoutScope(*childBox); |
2422 LayoutState* layoutState = view()->layoutState(); | |
2423 bool isPaginated = layoutState->isPaginated(); | |
2424 if (isPaginated && !childBox->needsLayout()) | 2533 if (isPaginated && !childBox->needsLayout()) |
2425 childBox->markForPaginationRelayoutIfNeeded(layoutScope); | 2534 childBox->markForPaginationRelayoutIfNeeded(layoutScope); |
2426 | 2535 |
2427 childBox->layoutIfNeeded(); | 2536 childBox->layoutIfNeeded(); |
2428 | 2537 |
2429 if (isPaginated) { | 2538 if (isPaginated) { |
2430 LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? to
LayoutBlockFlow(childBox) : nullptr; | 2539 LayoutBlockFlow* childBlockFlow = childBox->isLayoutBlockFlow() ? to
LayoutBlockFlow(childBox) : nullptr; |
2431 // The first piece of content inside the child may have set a strut
during layout. | 2540 // The first piece of content inside the child may have set a strut
during layout. |
2432 LayoutUnit strut = childBlockFlow ? childBlockFlow->paginationStrutP
ropagatedFromChild() : LayoutUnit(); | 2541 LayoutUnit strut = childBlockFlow ? childBlockFlow->paginationStrutP
ropagatedFromChild() : LayoutUnit(); |
2433 if (!strut) { | 2542 if (!strut) { |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2923 // FIXME: Glyph overflow will get lost in this case, but not really a big de
al. | 3032 // FIXME: Glyph overflow will get lost in this case, but not really a big de
al. |
2924 GlyphOverflowAndFallbackFontsMap textBoxDataMap; | 3033 GlyphOverflowAndFallbackFontsMap textBoxDataMap; |
2925 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it
!= lineBoxes.end(); ++it) { | 3034 for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it
!= lineBoxes.end(); ++it) { |
2926 RootInlineBox* box = *it; | 3035 RootInlineBox* box = *it; |
2927 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); | 3036 box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap); |
2928 } | 3037 } |
2929 return childrenOverflowChanged; | 3038 return childrenOverflowChanged; |
2930 } | 3039 } |
2931 | 3040 |
2932 } // namespace blink | 3041 } // namespace blink |
OLD | NEW |