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

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

Issue 147233002: Remove internal recursion for RenderBlockFlow and RenderMultiColumnBlock layout (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 11 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
« no previous file with comments | « Source/core/rendering/RenderBlockFlow.h ('k') | Source/core/rendering/RenderMultiColumnBlock.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 20 matching lines...) Expand all
31 #include "config.h" 31 #include "config.h"
32 #include "core/rendering/RenderBlockFlow.h" 32 #include "core/rendering/RenderBlockFlow.h"
33 33
34 #include "core/accessibility/AXObjectCache.h" 34 #include "core/accessibility/AXObjectCache.h"
35 #include "core/frame/FrameView.h" 35 #include "core/frame/FrameView.h"
36 #include "core/rendering/FastTextAutosizer.h" 36 #include "core/rendering/FastTextAutosizer.h"
37 #include "core/rendering/HitTestLocation.h" 37 #include "core/rendering/HitTestLocation.h"
38 #include "core/rendering/LayoutRectRecorder.h" 38 #include "core/rendering/LayoutRectRecorder.h"
39 #include "core/rendering/LayoutRepainter.h" 39 #include "core/rendering/LayoutRepainter.h"
40 #include "core/rendering/RenderLayer.h" 40 #include "core/rendering/RenderLayer.h"
41 #include "core/rendering/RenderMultiColumnBlock.h"
41 #include "core/rendering/RenderNamedFlowFragment.h" 42 #include "core/rendering/RenderNamedFlowFragment.h"
42 #include "core/rendering/RenderNamedFlowThread.h" 43 #include "core/rendering/RenderNamedFlowThread.h"
43 #include "core/rendering/RenderText.h" 44 #include "core/rendering/RenderText.h"
44 #include "core/rendering/RenderView.h" 45 #include "core/rendering/RenderView.h"
45 #include "core/rendering/line/LineWidth.h" 46 #include "core/rendering/line/LineWidth.h"
46 #include "core/rendering/svg/SVGTextRunRenderingContext.h" 47 #include "core/rendering/svg/SVGTextRunRenderingContext.h"
47 #include "platform/text/BidiTextRun.h" 48 #include "platform/text/BidiTextRun.h"
48 49
49 using namespace std; 50 using namespace std;
50 51
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 { 181 {
181 if (lineGridBox()) 182 if (lineGridBox())
182 lineGridBox()->destroy(); 183 lineGridBox()->destroy();
183 184
184 if (renderNamedFlowFragment()) 185 if (renderNamedFlowFragment())
185 setRenderNamedFlowFragment(0); 186 setRenderNamedFlowFragment(0);
186 187
187 RenderBlock::willBeDestroyed(); 188 RenderBlock::willBeDestroyed();
188 } 189 }
189 190
190 bool RenderBlockFlow::relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer& statePusher) 191 bool RenderBlockFlow::shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom)
esprehn 2014/01/24 22:19:17 Add const? should methods usually don't have side
191 { 192 {
192 if (!hasColumns())
193 return false;
194
195 OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
196 if (childrenInline())
197 addOverflowFromInlineChildren();
198 else
199 addOverflowFromBlockChildren();
200 LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layout OverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingB efore();
201
202 // FIXME: We don't balance properly at all in the presence of forced page br eaks. We need to understand what 193 // FIXME: We don't balance properly at all in the presence of forced page br eaks. We need to understand what
203 // the distance between forced page breaks is so that we can avoid making th e minimum column height too tall. 194 // the distance between forced page breaks is so that we can avoid making th e minimum column height too tall.
204 ColumnInfo* colInfo = columnInfo(); 195 ColumnInfo* colInfo = columnInfo();
205 if (!hasSpecifiedPageLogicalHeight) { 196 LayoutUnit columnHeight = pageLogicalHeight;
206 LayoutUnit columnHeight = pageLogicalHeight; 197 const int minColumnCount = colInfo->forcedBreaks() + 1;
207 int minColumnCount = colInfo->forcedBreaks() + 1; 198 const int desiredColumnCount = colInfo->desiredColumnCount();
208 int desiredColumnCount = colInfo->desiredColumnCount(); 199 if (minColumnCount >= desiredColumnCount) {
209 if (minColumnCount >= desiredColumnCount) { 200 // The forced page breaks are in control of the balancing. Just set the column height to the
210 // The forced page breaks are in control of the balancing. Just set the column height to the 201 // maximum page break distance.
211 // maximum page break distance. 202 if (!pageLogicalHeight) {
212 if (!pageLogicalHeight) { 203 LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maximumD istanceBetweenForcedBreaks(),
213 LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maxi mumDistanceBetweenForcedBreaks(), 204 view()->layoutState()->pageLogicalOffset(this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
214 view()->layoutState()->pageLogicalOffset(this, borderBefore( ) + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset( )); 205 columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBr eaks);
215 columnHeight = max(colInfo->minimumColumnHeight(), distanceBetwe enBreaks);
216 }
217 } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeig ht, desiredColumnCount)) {
218 // Now that we know the intrinsic height of the columns, we have to rebalance them.
219 columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf ((float)layoutOverflowLogicalBottom / desiredColumnCount));
220 } 206 }
221 207 } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
222 if (columnHeight && columnHeight != pageLogicalHeight) { 208 // Now that we know the intrinsic height of the columns, we have to reba lance them.
223 statePusher.pop(); 209 columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf((fl oat)layoutOverflowLogicalBottom / desiredColumnCount));
224 setEverHadLayout(true);
225 layoutBlockFlow(false, columnHeight);
226 return true;
227 }
228 } 210 }
229 211
230 if (pageLogicalHeight) 212 if (columnHeight && columnHeight != pageLogicalHeight) {
231 colInfo->setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBotto m / pageLogicalHeight), pageLogicalHeight); 213 pageLogicalHeight = columnHeight;
232 214 return true;
233 if (columnCount(colInfo)) {
234 setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeigh t() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
235 m_overflow.clear();
236 } else {
237 m_overflow = savedOverflow.release();
238 } 215 }
239 216
240 return false; 217 return false;
241 } 218 }
242 219
220 void RenderBlockFlow::setColumnCountAndHeight(unsigned count, LayoutUnit pageLog icalHeight)
221 {
222 ColumnInfo* colInfo = columnInfo();
223 if (pageLogicalHeight)
224 colInfo->setColumnCountAndHeight(count, pageLogicalHeight);
225
226 if (columnCount(colInfo)) {
227 setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeigh t() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
228 m_overflow.clear();
229 }
230 }
231
243 bool RenderBlockFlow::isSelfCollapsingBlock() const 232 bool RenderBlockFlow::isSelfCollapsingBlock() const
244 { 233 {
245 m_hasOnlySelfCollapsingChildren = RenderBlock::isSelfCollapsingBlock(); 234 m_hasOnlySelfCollapsingChildren = RenderBlock::isSelfCollapsingBlock();
246 return m_hasOnlySelfCollapsingChildren; 235 return m_hasOnlySelfCollapsingChildren;
247 } 236 }
248 237
249 void RenderBlockFlow::layoutBlock(bool relayoutChildren) 238 void RenderBlockFlow::layoutBlock(bool relayoutChildren)
250 { 239 {
251 layoutBlockFlow(relayoutChildren);
252 }
253
254 inline void RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit p ageLogicalHeight)
255 {
256 ASSERT(needsLayout()); 240 ASSERT(needsLayout());
257 ASSERT(isInlineBlockOrInlineTable() || !isInline()); 241 ASSERT(isInlineBlockOrInlineTable() || !isInline());
258 242
259 // If we are self-collapsing with self-collapsing descendants this will get set to save us burrowing through our 243 // If we are self-collapsing with self-collapsing descendants this will get set to save us burrowing through our
260 // descendants every time in |isSelfCollapsingBlock|. We reset it here so th at |isSelfCollapsingBlock| attempts to burrow 244 // descendants every time in |isSelfCollapsingBlock|. We reset it here so th at |isSelfCollapsingBlock| attempts to burrow
261 // at least once and so that it always gives a reliable result reflecting th e latest layout. 245 // at least once and so that it always gives a reliable result reflecting th e latest layout.
262 m_hasOnlySelfCollapsingChildren = false; 246 m_hasOnlySelfCollapsingChildren = false;
263 247
264 if (!relayoutChildren && simplifiedLayout()) 248 if (!relayoutChildren && simplifiedLayout())
265 return; 249 return;
266 250
251 SubtreeLayoutScope layoutScope(this);
252
253 bool success = false;
254 LayoutUnit pageLogicalHeight = 0;
255 while (!success)
256 success = tryLayoutBlockFlow(relayoutChildren, pageLogicalHeight, layout Scope);
esprehn 2014/01/24 22:19:17 Woah, this is really scary, why are you calling it
257 }
258
259 inline bool RenderBlockFlow::tryLayoutBlockFlow(bool relayoutChildren, LayoutUni t &pageLogicalHeight, SubtreeLayoutScope& layoutScope)
260 {
267 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); 261 LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
268 262
269 if (updateLogicalWidthAndColumnWidth()) 263 if (updateLogicalWidthAndColumnWidth())
270 relayoutChildren = true; 264 relayoutChildren = true;
271 265
272 rebuildFloatsFromIntruding(); 266 rebuildFloatsFromIntruding();
273 267
274 bool pageLogicalHeightChanged = false; 268 bool pageLogicalHeightChanged = false;
275 bool hasSpecifiedPageLogicalHeight = false; 269 bool hasSpecifiedPageLogicalHeight = false;
276 checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightCh anged, hasSpecifiedPageLogicalHeight); 270 checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightCh anged, hasSpecifiedPageLogicalHeight);
(...skipping 20 matching lines...) Expand all
297 // 291 //
298 // Start out by setting our margin values to our current margins. Table cell s have 292 // Start out by setting our margin values to our current margins. Table cell s have
299 // no margins, so we don't fill in the values for table cells. 293 // no margins, so we don't fill in the values for table cells.
300 if (!isTableCell()) { 294 if (!isTableCell()) {
301 initMaxMarginValues(); 295 initMaxMarginValues();
302 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); 296 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk());
303 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); 297 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk());
304 setPaginationStrut(0); 298 setPaginationStrut(0);
305 } 299 }
306 300
307 SubtreeLayoutScope layoutScope(this);
308
309 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); 301 LayoutUnit beforeEdge = borderBefore() + paddingBefore();
310 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig ht(); 302 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig ht();
311 LayoutUnit previousHeight = logicalHeight(); 303 LayoutUnit previousHeight = logicalHeight();
312 setLogicalHeight(beforeEdge); 304 setLogicalHeight(beforeEdge);
313 305
314 m_repaintLogicalTop = 0; 306 m_repaintLogicalTop = 0;
315 m_repaintLogicalBottom = 0; 307 m_repaintLogicalBottom = 0;
316 LayoutUnit maxFloatLogicalBottom = 0; 308 LayoutUnit maxFloatLogicalBottom = 0;
317 if (!firstChild() && !isAnonymousBlock()) 309 if (!firstChild() && !isAnonymousBlock())
318 setChildrenInline(true); 310 setChildrenInline(true);
319 311
320 FastTextAutosizer* textAutosizer = document().fastTextAutosizer(); 312 FastTextAutosizer* textAutosizer = document().fastTextAutosizer();
321 if (textAutosizer) 313 if (textAutosizer)
322 textAutosizer->beginLayout(this); 314 textAutosizer->beginLayout(this);
323 315
324 if (childrenInline()) 316 if (childrenInline())
325 layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLog icalBottom, afterEdge); 317 layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLog icalBottom, afterEdge);
326 else 318 else
327 layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom, layoutScope , beforeEdge, afterEdge); 319 layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom, layoutScope , beforeEdge, afterEdge);
328 320
329 if (textAutosizer) 321 if (textAutosizer)
330 textAutosizer->endLayout(this); 322 textAutosizer->endLayout(this);
331 323
332 if (frameView()->partialLayout().isStopping()) { 324 if (frameView()->partialLayout().isStopping()) {
333 statePusher.pop(); 325 statePusher.pop();
334 return; 326 return true;
335 } 327 }
336 328
337 // Expand our intrinsic height to encompass floats. 329 // Expand our intrinsic height to encompass floats.
338 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && expandsToE ncloseOverhangingFloats()) 330 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && expandsToE ncloseOverhangingFloats())
339 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); 331 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge);
340 332
341 if (relayoutForPagination(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher) || relayoutToAvoidWidows(statePusher)) { 333 if (isRenderMultiColumnBlock()) {
342 ASSERT(!shouldBreakAtLineToAvoidWidow()); 334 if (toRenderMultiColumnBlock(this)->shouldRelayoutMultiColumnBlock()) {
343 return; 335 statePusher.pop();
336 return false;
337 }
338 } else if (hasColumns()) {
339 OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
340 if (childrenInline())
341 addOverflowFromInlineChildren();
342 else
343 addOverflowFromBlockChildren();
344 LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? la youtOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - padd ingBefore();
345 m_overflow = savedOverflow.release();
346
347 if (!hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(pageLo gicalHeight, layoutOverflowLogicalBottom)) {
348 statePusher.pop();
349 setEverHadLayout(true);
350 return false;
351 }
352
353 setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageL ogicalHeight), pageLogicalHeight);
354 }
355
356 if (shouldBreakAtLineToAvoidWidow()) {
357 statePusher.pop();
358 setEverHadLayout(true);
359 return false;
344 } 360 }
345 361
346 // Calculate our new height. 362 // Calculate our new height.
347 LayoutUnit oldHeight = logicalHeight(); 363 LayoutUnit oldHeight = logicalHeight();
348 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); 364 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
349 365
350 // Before updating the final size of the flow thread make sure a forced brea k is applied after the content. 366 // Before updating the final size of the flow thread make sure a forced brea k is applied after the content.
351 // This ensures the size information is correctly computed for the last auto -height region receiving content. 367 // This ensures the size information is correctly computed for the last auto -height region receiving content.
352 if (isRenderFlowThread()) 368 if (isRenderFlowThread())
353 toRenderFlowThread(this)->applyBreakAfterContent(oldClientAfterEdge); 369 toRenderFlowThread(this)->applyBreakAfterContent(oldClientAfterEdge);
(...skipping 22 matching lines...) Expand all
376 updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged); 392 updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged);
377 393
378 // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway). 394 // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
379 computeOverflow(oldClientAfterEdge); 395 computeOverflow(oldClientAfterEdge);
380 396
381 statePusher.pop(); 397 statePusher.pop();
382 398
383 fitBorderToLinesIfNeeded(); 399 fitBorderToLinesIfNeeded();
384 400
385 if (frameView()->partialLayout().isStopping()) 401 if (frameView()->partialLayout().isStopping())
386 return; 402 return true;
387 403
388 if (renderView->layoutState()->m_pageLogicalHeight) 404 if (renderView->layoutState()->m_pageLogicalHeight)
389 setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop())); 405 setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop()));
390 406
391 updateLayerTransform(); 407 updateLayerTransform();
392 408
393 // Update our scroll information if we're overflow:auto/scroll/hidden now th at we know if 409 // Update our scroll information if we're overflow:auto/scroll/hidden now th at we know if
394 // we overflow or not. 410 // we overflow or not.
395 updateScrollInfoAfterLayout(); 411 updateScrollInfoAfterLayout();
396 412
397 // Repaint with our new bounds if they are different from our old bounds. 413 // Repaint with our new bounds if they are different from our old bounds.
398 bool didFullRepaint = repainter.repaintAfterLayout(); 414 bool didFullRepaint = repainter.repaintAfterLayout();
399 if (!didFullRepaint && m_repaintLogicalTop != m_repaintLogicalBottom && (sty le()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) { 415 if (!didFullRepaint && m_repaintLogicalTop != m_repaintLogicalBottom && (sty le()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
400 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) 416 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
401 setShouldRepaintOverflowIfNeeded(true); 417 setShouldRepaintOverflowIfNeeded(true);
402 else 418 else
403 repaintOverflow(); 419 repaintOverflow();
404 } 420 }
405 421
406 clearNeedsLayout(); 422 clearNeedsLayout();
423 return true;
407 } 424 }
408 425
409 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom) 426 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
410 { 427 {
411 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); 428 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
412 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); 429 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
413 430
414 // The child is a normal flow object. Compute the margins we will use for co llapsing now. 431 // The child is a normal flow object. Compute the margins we will use for co llapsing now.
415 child->computeAndSetBlockDirectionMargins(this); 432 child->computeAndSetBlockDirectionMargins(this);
416 433
(...skipping 2408 matching lines...) Expand 10 before | Expand all | Expand 10 after
2825 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() 2842 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData()
2826 { 2843 {
2827 if (m_rareData) 2844 if (m_rareData)
2828 return *m_rareData; 2845 return *m_rareData;
2829 2846
2830 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); 2847 m_rareData = adoptPtr(new RenderBlockFlowRareData(this));
2831 return *m_rareData; 2848 return *m_rareData;
2832 } 2849 }
2833 2850
2834 } // namespace WebCore 2851 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderBlockFlow.h ('k') | Source/core/rendering/RenderMultiColumnBlock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698