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 20 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |