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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 // Some features, such as floats, margin collapsing and fragmentation, require s
ome knowledge about | 159 // Some features, such as floats, margin collapsing and fragmentation, require s
ome knowledge about |
160 // things that happened when laying out previous block child siblings. Only look
ing at the object | 160 // things that happened when laying out previous block child siblings. Only look
ing at the object |
161 // currently being laid out isn't always enough. | 161 // currently being laid out isn't always enough. |
162 class BlockChildrenLayoutInfo { | 162 class BlockChildrenLayoutInfo { |
163 public: | 163 public: |
164 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow, LayoutUnit beforeEdge, L
ayoutUnit afterEdge) | 164 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow, LayoutUnit beforeEdge, L
ayoutUnit afterEdge) |
165 : m_marginInfo(blockFlow, beforeEdge, afterEdge) | 165 : m_marginInfo(blockFlow, beforeEdge, afterEdge) |
166 , m_previousBreakAfterValue(BreakAuto) | 166 , m_previousBreakAfterValue(BreakAuto) |
167 , m_isAtFirstInFlowChild(true) { } | 167 , m_isAtFirstInFlowChild(true) { } |
168 | 168 |
| 169 // Store multicol layout state before first layout of a block child. The chi
ld may contain a |
| 170 // column spanner. If we need to re-lay out the block child because our init
ial logical top |
| 171 // estimate was wrong, we need to roll back to how things were before laying
out the child. |
| 172 void storeMultiColumnLayoutState(const LayoutFlowThread& flowThread) |
| 173 { |
| 174 m_multiColumnLayoutState = flowThread.multiColumnLayoutState(); |
| 175 } |
| 176 void rollBackToInitialMultiColumnLayoutState(LayoutFlowThread& flowThread) |
| 177 { |
| 178 flowThread.restoreMultiColumnLayoutState(m_multiColumnLayoutState); |
| 179 } |
| 180 |
169 const MarginInfo& marginInfo() const { return m_marginInfo; } | 181 const MarginInfo& marginInfo() const { return m_marginInfo; } |
170 MarginInfo& marginInfo() { return m_marginInfo; } | 182 MarginInfo& marginInfo() { return m_marginInfo; } |
171 LayoutUnit& previousFloatLogicalBottom() { return m_previousFloatLogicalBott
om; } | 183 LayoutUnit& previousFloatLogicalBottom() { return m_previousFloatLogicalBott
om; } |
172 | 184 |
173 EBreak previousBreakAfterValue() const { return m_previousBreakAfterValue; } | 185 EBreak previousBreakAfterValue() const { return m_previousBreakAfterValue; } |
174 void setPreviousBreakAfterValue(EBreak value) { m_previousBreakAfterValue =
value; } | 186 void setPreviousBreakAfterValue(EBreak value) { m_previousBreakAfterValue =
value; } |
175 | 187 |
176 bool isAtFirstInFlowChild() const { return m_isAtFirstInFlowChild; } | 188 bool isAtFirstInFlowChild() const { return m_isAtFirstInFlowChild; } |
177 void clearIsAtFirstInFlowChild() { m_isAtFirstInFlowChild = false; } | 189 void clearIsAtFirstInFlowChild() { m_isAtFirstInFlowChild = false; } |
178 | 190 |
179 private: | 191 private: |
| 192 MultiColumnLayoutState m_multiColumnLayoutState; |
180 MarginInfo m_marginInfo; | 193 MarginInfo m_marginInfo; |
181 LayoutUnit m_previousFloatLogicalBottom; | 194 LayoutUnit m_previousFloatLogicalBottom; |
182 EBreak m_previousBreakAfterValue; | 195 EBreak m_previousBreakAfterValue; |
183 bool m_isAtFirstInFlowChild; | 196 bool m_isAtFirstInFlowChild; |
184 }; | 197 }; |
185 | 198 |
186 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) | 199 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) |
187 : LayoutBlock(node) | 200 : LayoutBlock(node) |
188 { | 201 { |
189 static_assert(sizeof(MarginInfo) == sizeof(SameSizeAsMarginInfo), "MarginInf
o should stay small"); | 202 static_assert(sizeof(MarginInfo) == sizeof(SameSizeAsMarginInfo), "MarginInf
o should stay small"); |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 if (std::max(previousFloatLogicalBottom, lowestFloatLogicalBottom()) > n
ewLogicalTop) | 629 if (std::max(previousFloatLogicalBottom, lowestFloatLogicalBottom()) > n
ewLogicalTop) |
617 markDescendantsWithFloats = true; | 630 markDescendantsWithFloats = true; |
618 } | 631 } |
619 | 632 |
620 if (markDescendantsWithFloats) | 633 if (markDescendantsWithFloats) |
621 child.markAllDescendantsWithFloatsForLayout(); | 634 child.markAllDescendantsWithFloatsForLayout(); |
622 } | 635 } |
623 | 636 |
624 bool LayoutBlockFlow::positionAndLayoutOnceIfNeeded(LayoutBox& child, LayoutUnit
newLogicalTop, BlockChildrenLayoutInfo& layoutInfo) | 637 bool LayoutBlockFlow::positionAndLayoutOnceIfNeeded(LayoutBox& child, LayoutUnit
newLogicalTop, BlockChildrenLayoutInfo& layoutInfo) |
625 { | 638 { |
| 639 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) |
| 640 layoutInfo.rollBackToInitialMultiColumnLayoutState(*flowThread); |
| 641 |
626 if (child.isLayoutBlockFlow()) { | 642 if (child.isLayoutBlockFlow()) { |
627 LayoutUnit& previousFloatLogicalBottom = layoutInfo.previousFloatLogical
Bottom(); | 643 LayoutUnit& previousFloatLogicalBottom = layoutInfo.previousFloatLogical
Bottom(); |
628 LayoutBlockFlow& childBlockFlow = toLayoutBlockFlow(child); | 644 LayoutBlockFlow& childBlockFlow = toLayoutBlockFlow(child); |
629 if (childBlockFlow.containsFloats() || containsFloats()) | 645 if (childBlockFlow.containsFloats() || containsFloats()) |
630 markDescendantsWithFloatsForLayoutIfNeeded(childBlockFlow, newLogica
lTop, previousFloatLogicalBottom); | 646 markDescendantsWithFloatsForLayoutIfNeeded(childBlockFlow, newLogica
lTop, previousFloatLogicalBottom); |
631 | 647 |
632 // TODO(mstensho): A writing mode root is one thing, but we should be ab
le to skip anything | 648 // TODO(mstensho): A writing mode root is one thing, but we should be ab
le to skip anything |
633 // that establishes a new block formatting context here. Their floats do
n't affect us. | 649 // that establishes a new block formatting context here. Their floats do
n't affect us. |
634 if (!childBlockFlow.isWritingModeRoot()) | 650 if (!childBlockFlow.isWritingModeRoot()) |
635 previousFloatLogicalBottom = std::max(previousFloatLogicalBottom, ch
ildBlockFlow.logicalTop() + childBlockFlow.lowestFloatLogicalBottom()); | 651 previousFloatLogicalBottom = std::max(previousFloatLogicalBottom, ch
ildBlockFlow.logicalTop() + childBlockFlow.lowestFloatLogicalBottom()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 | 707 |
692 // Try to guess our correct logical top position. In most cases this guess w
ill | 708 // Try to guess our correct logical top position. In most cases this guess w
ill |
693 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) | 709 // be correct. Only if we're wrong (when we compute the real logical top pos
ition) |
694 // will we have to potentially relayout. | 710 // will we have to potentially relayout. |
695 LayoutUnit estimateWithoutPagination; | 711 LayoutUnit estimateWithoutPagination; |
696 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, layoutInfo
, estimateWithoutPagination); | 712 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, layoutInfo
, estimateWithoutPagination); |
697 | 713 |
698 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. | 714 // Cache our old rect so that we can dirty the proper paint invalidation rec
ts if the child moves. |
699 LayoutRect oldRect = child.frameRect(); | 715 LayoutRect oldRect = child.frameRect(); |
700 | 716 |
| 717 if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) |
| 718 layoutInfo.storeMultiColumnLayoutState(*flowThread); |
| 719 |
701 // Use the estimated block position and lay out the child if needed. After c
hild layout, when | 720 // Use the estimated block position and lay out the child if needed. After c
hild layout, when |
702 // we have enough information to perform proper margin collapsing, float cle
aring and | 721 // we have enough information to perform proper margin collapsing, float cle
aring and |
703 // pagination, we may have to reposition and lay out again if the estimate w
as wrong. | 722 // pagination, we may have to reposition and lay out again if the estimate w
as wrong. |
704 bool childNeededLayout = positionAndLayoutOnceIfNeeded(child, logicalTopEsti
mate, layoutInfo); | 723 bool childNeededLayout = positionAndLayoutOnceIfNeeded(child, logicalTopEsti
mate, layoutInfo); |
705 | 724 |
706 // Cache if we are at the top of the block right now. | 725 // Cache if we are at the top of the block right now. |
707 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); | 726 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); |
708 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); | 727 bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); |
709 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); | 728 bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); |
710 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); | 729 bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); |
(...skipping 3064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3775 if (!rect.isEmpty()) | 3794 if (!rect.isEmpty()) |
3776 rects.append(rect); | 3795 rects.append(rect); |
3777 } | 3796 } |
3778 } | 3797 } |
3779 | 3798 |
3780 if (inlineElementContinuation) | 3799 if (inlineElementContinuation) |
3781 inlineElementContinuation->addOutlineRects(rects, additionalOffset + (in
lineElementContinuation->containingBlock()->location() - location()), includeBlo
ckOverflows); | 3800 inlineElementContinuation->addOutlineRects(rects, additionalOffset + (in
lineElementContinuation->containingBlock()->location() - location()), includeBlo
ckOverflows); |
3782 } | 3801 } |
3783 | 3802 |
3784 } // namespace blink | 3803 } // namespace blink |
OLD | NEW |