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

Side by Side Diff: Source/core/rendering/RenderMultiColumnFlowThread.cpp

Issue 288263002: [New Multicolumn] Rebalance properly when child content changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: More cleanup; avoid bool arguments. Get rid of layout() override. Created 6 years, 7 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) 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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698