OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 namespace WebCore { | 35 namespace WebCore { |
36 | 36 |
37 RenderMultiColumnBlock::RenderMultiColumnBlock(Element* element) | 37 RenderMultiColumnBlock::RenderMultiColumnBlock(Element* element) |
38 : RenderBlockFlow(element) | 38 : RenderBlockFlow(element) |
39 , m_flowThread(0) | 39 , m_flowThread(0) |
40 , m_columnCount(1) | 40 , m_columnCount(1) |
41 , m_columnWidth(0) | 41 , m_columnWidth(0) |
42 , m_columnHeightAvailable(0) | 42 , m_columnHeightAvailable(0) |
43 , m_inBalancingPass(false) | 43 , m_inBalancingPass(false) |
| 44 , m_needsRebalancing(false) |
44 { | 45 { |
45 } | 46 } |
46 | 47 |
47 void RenderMultiColumnBlock::styleDidChange(StyleDifference diff, const RenderSt
yle* oldStyle) | 48 void RenderMultiColumnBlock::styleDidChange(StyleDifference diff, const RenderSt
yle* oldStyle) |
48 { | 49 { |
49 RenderBlock::styleDidChange(diff, oldStyle); | 50 RenderBlock::styleDidChange(diff, oldStyle); |
50 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) | 51 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) |
51 child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BL
OCK)); | 52 child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BL
OCK)); |
52 } | 53 } |
53 | 54 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 } | 89 } |
89 | 90 |
90 void RenderMultiColumnBlock::checkForPaginationLogicalHeightChange(LayoutUnit& /
*pageLogicalHeight*/, bool& /*pageLogicalHeightChanged*/, bool& /*hasSpecifiedPa
geLogicalHeight*/) | 91 void RenderMultiColumnBlock::checkForPaginationLogicalHeightChange(LayoutUnit& /
*pageLogicalHeight*/, bool& /*pageLogicalHeightChanged*/, bool& /*hasSpecifiedPa
geLogicalHeight*/) |
91 { | 92 { |
92 // We don't actually update any of the variables. We just subclassed to adju
st our column height. | 93 // We don't actually update any of the variables. We just subclassed to adju
st our column height. |
93 updateLogicalHeight(); | 94 updateLogicalHeight(); |
94 m_columnHeightAvailable = max<LayoutUnit>(contentLogicalHeight(), 0); | 95 m_columnHeightAvailable = max<LayoutUnit>(contentLogicalHeight(), 0); |
95 setLogicalHeight(0); | 96 setLogicalHeight(0); |
96 } | 97 } |
97 | 98 |
98 bool RenderMultiColumnBlock::shouldRelayoutMultiColumnBlock() const | 99 bool RenderMultiColumnBlock::shouldRelayoutMultiColumnBlock() |
99 { | 100 { |
100 if (!requiresBalancing()) | 101 if (!m_needsRebalancing) |
101 return false; | 102 return false; |
102 | 103 |
103 // Column heights may change here because of balancing. We may have to do mu
ltiple layout | 104 // Column heights may change here because of balancing. We may have to do mu
ltiple layout |
104 // passes, depending on how the contents is fitted to the changed column hei
ghts. In most | 105 // passes, depending on how the contents is fitted to the changed column hei
ghts. In most |
105 // cases, laying out again twice or even just once will suffice. Sometimes w
e need more | 106 // cases, laying out again twice or even just once will suffice. Sometimes w
e need more |
106 // passes than that, though, but the number of retries should not exceed the
number of | 107 // passes than that, though, but the number of retries should not exceed the
number of |
107 // columns, unless we have a bug. | 108 // columns, unless we have a bug. |
108 bool needsRelayout = false; | 109 bool needsRelayout = false; |
109 for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->n
extSiblingBox()) { | 110 for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->n
extSiblingBox()) { |
110 if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) { | 111 if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) { |
111 RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox)
; | 112 RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox)
; |
112 if (multicolSet->calculateBalancedHeight(!m_inBalancingPass)) { | 113 if (multicolSet->recalculateBalancedHeight(!m_inBalancingPass)) { |
113 multicolSet->setChildNeedsLayout(MarkOnlyThis); | 114 multicolSet->setChildNeedsLayout(MarkOnlyThis); |
114 needsRelayout = true; | 115 needsRelayout = true; |
115 } | 116 } |
116 } | 117 } |
117 } | 118 } |
118 | 119 |
119 if (needsRelayout) | 120 if (needsRelayout) |
120 m_flowThread->setChildNeedsLayout(MarkOnlyThis); | 121 m_flowThread->setChildNeedsLayout(MarkOnlyThis); |
121 | 122 |
122 | |
123 m_inBalancingPass = needsRelayout; | 123 m_inBalancingPass = needsRelayout; |
124 return needsRelayout; | 124 return needsRelayout; |
125 } | 125 } |
126 | 126 |
127 void RenderMultiColumnBlock::addChild(RenderObject* newChild, RenderObject* befo
reChild) | 127 void RenderMultiColumnBlock::addChild(RenderObject* newChild, RenderObject* befo
reChild) |
128 { | 128 { |
129 if (!m_flowThread) { | 129 if (!m_flowThread) { |
130 m_flowThread = RenderMultiColumnFlowThread::createAnonymous(&document())
; | 130 m_flowThread = RenderMultiColumnFlowThread::createAnonymous(&document())
; |
131 m_flowThread->setStyle(RenderStyle::createAnonymousStyleWithDisplay(styl
e(), BLOCK)); | 131 m_flowThread->setStyle(RenderStyle::createAnonymousStyleWithDisplay(styl
e(), BLOCK)); |
132 RenderBlock::addChild(m_flowThread); | 132 RenderBlock::addChild(m_flowThread); |
(...skipping 20 matching lines...) Expand all Loading... |
153 shouldInvalidateRegions = true; | 153 shouldInvalidateRegions = true; |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 if (shouldInvalidateRegions) | 157 if (shouldInvalidateRegions) |
158 m_flowThread->invalidateRegions(); | 158 m_flowThread->invalidateRegions(); |
159 | 159 |
160 if (relayoutChildren) | 160 if (relayoutChildren) |
161 layoutScope.setChildNeedsLayout(m_flowThread); | 161 layoutScope.setChildNeedsLayout(m_flowThread); |
162 | 162 |
| 163 if (requiresBalancing()) { |
| 164 // At the end of multicol layout, relayoutForPagination() is called unco
nditionally, but if |
| 165 // no children are to be laid out (e.g. fixed width with layout already
being up-to-date), |
| 166 // we want to prevent it from doing any work, so that the column balanci
ng machinery doesn't |
| 167 // kick in and trigger additional unnecessary layout passes. Actually, i
t's not just a good |
| 168 // idea in general to not waste time on balancing content that hasn't be
en re-laid out; we |
| 169 // are actually required to guarantee this. The calculation of implicit
breaks needs to be |
| 170 // preceded by a proper layout pass, since it's layout that sets up cont
ent runs, and the |
| 171 // runs get deleted right after every pass. |
| 172 m_needsRebalancing = shouldInvalidateRegions || m_flowThread->needsLayou
t(); |
| 173 } |
| 174 |
163 setLogicalTopForChild(m_flowThread, borderBefore() + paddingBefore()); | 175 setLogicalTopForChild(m_flowThread, borderBefore() + paddingBefore()); |
164 m_flowThread->layoutIfNeeded(); | 176 m_flowThread->layoutIfNeeded(); |
165 determineLogicalLeftPositionForChild(m_flowThread); | 177 determineLogicalLeftPositionForChild(m_flowThread); |
166 | 178 |
167 return m_flowThread; | 179 return m_flowThread; |
168 } | 180 } |
169 | 181 |
170 const char* RenderMultiColumnBlock::renderName() const | 182 const char* RenderMultiColumnBlock::renderName() const |
171 { | 183 { |
172 if (isFloating()) | 184 if (isFloating()) |
173 return "RenderMultiColumnBlock (floating)"; | 185 return "RenderMultiColumnBlock (floating)"; |
174 if (isOutOfFlowPositioned()) | 186 if (isOutOfFlowPositioned()) |
175 return "RenderMultiColumnBlock (positioned)"; | 187 return "RenderMultiColumnBlock (positioned)"; |
176 if (isAnonymousBlock()) | 188 if (isAnonymousBlock()) |
177 return "RenderMultiColumnBlock (anonymous)"; | 189 return "RenderMultiColumnBlock (anonymous)"; |
178 // FIXME: Temporary hack while the new generated content system is being imp
lemented. | 190 // FIXME: Temporary hack while the new generated content system is being imp
lemented. |
179 if (isPseudoElement()) | 191 if (isPseudoElement()) |
180 return "RenderMultiColumnBlock (generated)"; | 192 return "RenderMultiColumnBlock (generated)"; |
181 if (isAnonymous()) | 193 if (isAnonymous()) |
182 return "RenderMultiColumnBlock (generated)"; | 194 return "RenderMultiColumnBlock (generated)"; |
183 if (isRelPositioned()) | 195 if (isRelPositioned()) |
184 return "RenderMultiColumnBlock (relative positioned)"; | 196 return "RenderMultiColumnBlock (relative positioned)"; |
185 return "RenderMultiColumnBlock"; | 197 return "RenderMultiColumnBlock"; |
186 } | 198 } |
187 | 199 |
188 } | 200 } |
OLD | NEW |