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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 flipForWritingMode(flowThreadPoint); | 132 flipForWritingMode(flowThreadPoint); |
133 LayoutUnit blockOffset = isHorizontalWritingMode() ? flowThreadPoint.y() : f lowThreadPoint.x(); | 133 LayoutUnit blockOffset = isHorizontalWritingMode() ? flowThreadPoint.y() : f lowThreadPoint.x(); |
134 RenderRegion* renderRegion = regionAtBlockOffset(blockOffset); | 134 RenderRegion* renderRegion = regionAtBlockOffset(blockOffset); |
135 if (!renderRegion) | 135 if (!renderRegion) |
136 return LayoutSize(0, 0); | 136 return LayoutSize(0, 0); |
137 return toRenderMultiColumnSet(renderRegion)->flowThreadTranslationAtOffset(b lockOffset); | 137 return toRenderMultiColumnSet(renderRegion)->flowThreadTranslationAtOffset(b lockOffset); |
138 } | 138 } |
139 | 139 |
140 void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa youtScope& layoutScope) | 140 void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa youtScope& layoutScope) |
141 { | 141 { |
142 // Update the dimensions of our regions before we lay out the flow thread. | 142 if (relayoutChildren) |
143 // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions | 143 layoutScope.setChildNeedsLayout(this); |
144 // instead of trying to keep them around. | 144 |
145 bool shouldInvalidateRegions = false; | 145 if (!needsLayout()) { |
146 // At the end of multicol container (our parent RenderBlockFlow) layout, it will call | |
147 // recalculateColumnHeights() on us unconditionally, but if we won't lay out (e.g. because | |
148 // we have fixed width with layout already being up-to-date), we want to prevent | |
149 // recalculateColumnHeights() from doing any work, so that the column ba lancing machinery | |
150 // doesn't kick in and trigger additional unnecessary layout passes. Act ually, it's not just | |
151 // a good idea in general to not waste time on balancing content that ha sn't been re-laid | |
Julien - ping for review
2014/05/23 09:07:54
I have a hard time parsing this sentence due to to
mstensho (USE GERRIT)
2014/05/23 11:46:09
Done.
| |
152 // out; we are actually required to guarantee this. The calculation of i mplicit breaks needs | |
153 // to be preceded by a proper layout pass, since it's layout that sets u p content runs, and | |
154 // the runs get deleted right after every pass. | |
155 m_needsColumnHeightsRecalculation = false; | |
156 return; | |
157 } | |
158 | |
146 for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet()) { | 159 for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet()) { |
147 if (relayoutChildren || columnSet->needsLayout()) { | 160 if (!m_inBalancingPass) { |
148 if (!m_inBalancingPass) | 161 // This is the initial layout pass. We need to reset the column heig ht, because contents |
149 columnSet->prepareForLayout(); | 162 // typically have changed. |
150 shouldInvalidateRegions = true; | 163 columnSet->resetColumnHeight(); |
164 | |
165 columnSet->setComputedColumnWidthAndCount(columnWidth(), columnCount ()); | |
151 } | 166 } |
152 } | 167 } |
153 | 168 |
154 if (shouldInvalidateRegions) | 169 invalidateRegions(); |
155 invalidateRegions(); | 170 m_needsColumnHeightsRecalculation = requiresBalancing(); |
156 | 171 layout(); |
157 if (relayoutChildren) | |
158 layoutScope.setChildNeedsLayout(this); | |
159 | |
160 if (requiresBalancing()) { | |
161 // At the end of multicol layout, relayoutForPagination() is called unco nditionally, but if | |
162 // no children are to be laid out (e.g. fixed width with layout already being up-to-date), | |
163 // we want to prevent it from doing any work, so that the column balanci ng machinery doesn't | |
164 // kick in and trigger additional unnecessary layout passes. Actually, i t's not just a good | |
165 // idea in general to not waste time on balancing content that hasn't be en re-laid out; we | |
166 // are actually required to guarantee this. The calculation of implicit breaks needs to be | |
167 // preceded by a proper layout pass, since it's layout that sets up cont ent runs, and the | |
168 // runs get deleted right after every pass. | |
169 m_needsColumnHeightsRecalculation = shouldInvalidateRegions || needsLayo ut(); | |
170 } | |
171 | |
172 layoutIfNeeded(); | |
173 } | 172 } |
174 | 173 |
175 bool RenderMultiColumnFlowThread::computeColumnCountAndWidth() | 174 bool RenderMultiColumnFlowThread::computeColumnCountAndWidth() |
176 { | 175 { |
177 RenderBlock* columnBlock = multiColumnBlockFlow(); | 176 RenderBlock* columnBlock = multiColumnBlockFlow(); |
178 LayoutUnit oldColumnWidth = m_columnWidth; | 177 LayoutUnit oldColumnWidth = m_columnWidth; |
179 | 178 |
180 // Calculate our column width and column count. | 179 // Calculate our column width and column count. |
181 m_columnCount = 1; | 180 m_columnCount = 1; |
182 m_columnWidth = columnBlock->contentLogicalWidth(); | 181 m_columnWidth = columnBlock->contentLogicalWidth(); |
(...skipping 15 matching lines...) Expand all Loading... | |
198 } else { | 197 } else { |
199 m_columnCount = std::max<LayoutUnit>(std::min<LayoutUnit>(colCount, (ava ilWidth + colGap) / (colWidth + colGap)), 1); | 198 m_columnCount = std::max<LayoutUnit>(std::min<LayoutUnit>(colCount, (ava ilWidth + colGap) / (colWidth + colGap)), 1); |
200 m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap; | 199 m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap; |
201 } | 200 } |
202 | 201 |
203 return m_columnWidth != oldColumnWidth; | 202 return m_columnWidth != oldColumnWidth; |
204 } | 203 } |
205 | 204 |
206 bool RenderMultiColumnFlowThread::recalculateColumnHeights() | 205 bool RenderMultiColumnFlowThread::recalculateColumnHeights() |
207 { | 206 { |
207 // All column sets that needed layout have now been laid out, so we can fina lly validate them. | |
208 validateRegions(); | |
209 | |
208 if (!m_needsColumnHeightsRecalculation) | 210 if (!m_needsColumnHeightsRecalculation) |
209 return false; | 211 return false; |
210 | 212 |
211 // Column heights may change here because of balancing. We may have to do mu ltiple layout | 213 // Column heights may change here because of balancing. We may have to do mu ltiple layout |
212 // passes, depending on how the contents is fitted to the changed column hei ghts. In most | 214 // passes, depending on how the contents is fitted to the changed column hei ghts. In most |
213 // cases, laying out again twice or even just once will suffice. Sometimes w e need more | 215 // cases, laying out again twice or even just once will suffice. Sometimes w e need more |
214 // passes than that, though, but the number of retries should not exceed the number of | 216 // passes than that, though, but the number of retries should not exceed the number of |
215 // columns, unless we have a bug. | 217 // columns, unless we have a bug. |
216 bool needsRelayout = false; | 218 bool needsRelayout = false; |
217 for (RenderMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) { | 219 for (RenderMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) { |
218 if (multicolSet->recalculateColumnHeight(!m_inBalancingPass)) { | 220 if (multicolSet->recalculateColumnHeight(m_inBalancingPass ? RenderMulti ColumnSet::StretchBySpaceShortage : RenderMultiColumnSet::GuessFromFlowThreadPor tion)) |
221 needsRelayout = true; | |
Julien - ping for review
2014/05/23 09:07:54
needsRelayout |= multicolSet->recalculateColumnHei
mstensho (USE GERRIT)
2014/05/23 11:46:09
Done.
| |
222 if (needsRelayout) { | |
223 // Once a column set gets a new column height, that column set and a ll successive column | |
224 // sets need to be laid out over again, since their logical top will be affected by | |
225 // this, and therefore their column heights may change as well, at l east if the multicol | |
226 // height is constrained. | |
219 multicolSet->setChildNeedsLayout(MarkOnlyThis); | 227 multicolSet->setChildNeedsLayout(MarkOnlyThis); |
220 needsRelayout = true; | |
221 } | 228 } |
222 } | 229 } |
223 | 230 |
224 if (needsRelayout) | 231 if (needsRelayout) |
225 setChildNeedsLayout(MarkOnlyThis); | 232 setChildNeedsLayout(MarkOnlyThis); |
226 | 233 |
227 m_inBalancingPass = needsRelayout; | 234 m_inBalancingPass = needsRelayout; |
228 return needsRelayout; | 235 return needsRelayout; |
229 } | 236 } |
230 | 237 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 } | 320 } |
314 | 321 |
315 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const | 322 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const |
316 { | 323 { |
317 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet()) | 324 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet()) |
318 return columnSet->computedColumnHeight(); | 325 return columnSet->computedColumnHeight(); |
319 return false; | 326 return false; |
320 } | 327 } |
321 | 328 |
322 } | 329 } |
OLD | NEW |