Chromium Code Reviews| 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 // If we are self-collapsing with self-collapsing descendants this will get set to save us burrowing through our | 275 // If we are self-collapsing with self-collapsing descendants this will get set to save us burrowing through our |
| 276 // descendants every time in |isSelfCollapsingBlock|. We reset it here so th at |isSelfCollapsingBlock| attempts to burrow | 276 // descendants every time in |isSelfCollapsingBlock|. We reset it here so th at |isSelfCollapsingBlock| attempts to burrow |
| 277 // at least once and so that it always gives a reliable result reflecting th e latest layout. | 277 // at least once and so that it always gives a reliable result reflecting th e latest layout. |
| 278 m_hasOnlySelfCollapsingChildren = false; | 278 m_hasOnlySelfCollapsingChildren = false; |
| 279 | 279 |
| 280 if (!relayoutChildren && simplifiedLayout()) | 280 if (!relayoutChildren && simplifiedLayout()) |
| 281 return; | 281 return; |
| 282 | 282 |
| 283 SubtreeLayoutScope layoutScope(this); | 283 SubtreeLayoutScope layoutScope(this); |
| 284 | 284 |
| 285 m_layoutScope = &layoutScope; | |
| 286 m_pageLogicalHeight = 0; | |
| 287 | |
| 288 preLayoutBlock(relayoutChildren, true); | |
| 289 | |
| 285 // Multiple passes might be required for column and pagination based layout | 290 // Multiple passes might be required for column and pagination based layout |
| 286 // In the case of the old column code the number of passes will only be two | 291 // In the case of the old column code the number of passes will only be two |
| 287 // however, in the newer column code the number of passes could equal the | 292 // however, in the newer column code the number of passes could equal the |
| 288 // number of columns. | 293 // number of columns. |
| 289 bool done = false; | 294 bool done = postLayoutBlock(); |
| 290 LayoutUnit pageLogicalHeight = 0; | 295 while (!done) { |
| 291 while (!done) | 296 preLayoutBlock(relayoutChildren, true); |
| 292 done = layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope) ; | 297 done = postLayoutBlock(); |
| 298 } | |
| 299 m_layoutScope = 0; | |
| 293 } | 300 } |
| 294 | 301 |
| 295 inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & pageLogicalHeight, SubtreeLayoutScope& layoutScope) | 302 void RenderBlockFlow::preLayoutBlock(bool relayoutChildren, bool traverseChildre n) |
| 296 { | 303 { |
| 297 LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); | 304 m_relayoutChildren = relayoutChildren; |
| 305 preLayoutBlockFlow(traverseChildren); | |
| 306 } | |
| 307 | |
| 308 bool RenderBlockFlow::postLayoutBlock() | |
| 309 { | |
| 310 return postLayoutBlockFlow(); | |
| 311 } | |
| 312 | |
| 313 void RenderBlockFlow::preLayoutBlockFlow(bool traverseChildren) | |
| 314 { | |
| 315 m_checkForRepaint = checkForRepaintDuringLayout(); | |
| 316 m_oldBounds = LayoutRect(); | |
| 317 m_oldOutlineBox = LayoutRect(); | |
| 318 if (m_checkForRepaint) { | |
| 319 m_oldBounds = clippedOverflowRectForRepaint(containerForRepaint()); | |
| 320 m_oldOutlineBox = outlineBoundsForRepaint(containerForRepaint(), 0); | |
| 321 } | |
| 298 | 322 |
| 299 if (updateLogicalWidthAndColumnWidth()) | 323 if (updateLogicalWidthAndColumnWidth()) |
| 300 relayoutChildren = true; | 324 m_relayoutChildren = true; |
| 301 | 325 |
| 302 rebuildFloatsFromIntruding(); | 326 rebuildFloatsFromIntruding(); |
| 303 | 327 |
| 304 bool pageLogicalHeightChanged = false; | 328 bool pageLogicalHeightChanged = false; |
| 305 bool hasSpecifiedPageLogicalHeight = false; | 329 m_hasSpecifiedPageLogicalHeight = false; |
| 306 checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightCh anged, hasSpecifiedPageLogicalHeight); | 330 checkForPaginationLogicalHeightChange(m_pageLogicalHeight, pageLogicalHeight Changed, m_hasSpecifiedPageLogicalHeight); |
| 307 | 331 |
| 308 RenderView* renderView = view(); | 332 RenderView* renderView = view(); |
| 309 LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasCol umns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMo de(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo()); | 333 m_statePusher = new LayoutStateMaintainer(renderView, this, locationOffset() , hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksW ritingMode(), m_pageLogicalHeight, pageLogicalHeightChanged, columnInfo()); |
| 310 | 334 |
| 311 // Regions changing widths can force us to relayout our children. | 335 // Regions changing widths can force us to relayout our children. |
| 312 RenderFlowThread* flowThread = flowThreadContainingBlock(); | 336 RenderFlowThread* flowThread = flowThreadContainingBlock(); |
| 313 if (logicalWidthChangedInRegions(flowThread)) | 337 if (logicalWidthChangedInRegions(flowThread)) |
| 314 relayoutChildren = true; | 338 m_relayoutChildren = true; |
| 315 if (updateRegionsAndShapesLogicalSize(flowThread)) | 339 if (updateRegionsAndShapesLogicalSize(flowThread)) |
| 316 relayoutChildren = true; | 340 m_relayoutChildren = true; |
| 317 if (!relayoutChildren && isRenderNamedFlowFragmentContainer()) | 341 if (!m_relayoutChildren && isRenderNamedFlowFragmentContainer()) |
| 318 relayoutChildren = true; | 342 m_relayoutChildren = true; |
| 319 | 343 |
| 320 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track | 344 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track |
| 321 // our current maximal positive and negative margins. These values are used when we | 345 // our current maximal positive and negative margins. These values are used when we |
| 322 // are collapsed with adjacent blocks, so for example, if you have block A a nd B | 346 // are collapsed with adjacent blocks, so for example, if you have block A a nd B |
| 323 // collapsing together, then you'd take the maximal positive margin from bot h A and B | 347 // collapsing together, then you'd take the maximal positive margin from bot h A and B |
| 324 // and subtract it from the maximal negative margin from both A and B to get the | 348 // and subtract it from the maximal negative margin from both A and B to get the |
| 325 // true collapsed margin. This algorithm is recursive, so when we finish lay out() | 349 // true collapsed margin. This algorithm is recursive, so when we finish lay out() |
| 326 // our block knows its current maximal positive/negative values. | 350 // our block knows its current maximal positive/negative values. |
| 327 // | 351 // |
| 328 // Start out by setting our margin values to our current margins. Table cell s have | 352 // Start out by setting our margin values to our current margins. Table cell s have |
| 329 // no margins, so we don't fill in the values for table cells. | 353 // no margins, so we don't fill in the values for table cells. |
| 330 if (!isTableCell()) { | 354 if (!isTableCell()) { |
| 331 initMaxMarginValues(); | 355 initMaxMarginValues(); |
| 332 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); | 356 setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk()); |
| 333 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); | 357 setHasMarginAfterQuirk(style()->hasMarginAfterQuirk()); |
| 334 setPaginationStrut(0); | 358 setPaginationStrut(0); |
| 335 } | 359 } |
| 336 | 360 |
| 337 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | 361 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); |
| 338 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig ht(); | 362 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig ht(); |
| 339 LayoutUnit previousHeight = logicalHeight(); | 363 m_heightBeforeLayout = logicalHeight(); |
| 340 setLogicalHeight(beforeEdge); | 364 setLogicalHeight(beforeEdge); |
| 341 | 365 |
| 342 m_repaintLogicalTop = 0; | 366 m_repaintLogicalTop = 0; |
| 343 m_repaintLogicalBottom = 0; | 367 m_repaintLogicalBottom = 0; |
| 344 LayoutUnit maxFloatLogicalBottom = 0; | 368 m_maxFloatLogicalBottom = 0; |
| 345 if (!firstChild() && !isAnonymousBlock()) | 369 if (!firstChild() && !isAnonymousBlock()) |
| 346 setChildrenInline(true); | 370 setChildrenInline(true); |
| 347 | 371 |
| 348 FastTextAutosizer* textAutosizer = document().fastTextAutosizer(); | 372 FastTextAutosizer* textAutosizer = document().fastTextAutosizer(); |
| 349 if (textAutosizer) | 373 if (textAutosizer) |
| 350 textAutosizer->beginLayout(this); | 374 textAutosizer->beginLayout(this); |
| 351 | 375 |
| 352 if (childrenInline()) | 376 if (childrenInline()) |
| 353 layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLog icalBottom, afterEdge); | 377 layoutInlineChildren(m_relayoutChildren, m_repaintLogicalTop, m_repaintL ogicalBottom, afterEdge); |
| 354 else | 378 else { |
| 355 layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom, layoutScope , beforeEdge, afterEdge); | 379 dirtyForLayoutFromPercentageHeightDescendants(*m_layoutScope); |
| 380 | |
| 381 // Lay out our hypothetical grid line as though it occurs at the top of the block. | |
| 382 if (view()->layoutState()->lineGrid() == this) | |
| 383 layoutLineGridBox(); | |
| 384 | |
| 385 layoutBlockChildren(beforeEdge, afterEdge, traverseChildren); | |
| 386 } | |
| 387 } | |
| 388 | |
| 389 bool RenderBlockFlow::postLayoutBlockFlow() | |
| 390 { | |
| 391 if (!m_statePusher) // simple layout | |
| 392 return true; | |
| 356 | 393 |
| 357 if (frameView()->partialLayout().isStopping()) { | 394 if (frameView()->partialLayout().isStopping()) { |
| 358 statePusher.pop(); | 395 m_statePusher->pop(); |
| 396 delete m_statePusher; | |
| 397 m_statePusher = 0; | |
| 359 return true; | 398 return true; |
| 360 } | 399 } |
| 361 | 400 |
| 401 LayoutRepainter repainter(*this, m_checkForRepaint, m_oldBounds, m_oldOutlin eBox); | |
| 402 LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | |
| 403 LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeig ht(); | |
| 404 | |
| 405 if (!childrenInline()) { | |
| 406 // Now do the handling of the bottom of the block, adding in our bottom border/padding and | |
| 407 // determining the correct collapsed bottom margin information. | |
| 408 handleAfterSideOfBlock(m_lastNormalFlowChild, beforeEdge, afterEdge, *m_ marginInfo); | |
| 409 delete m_marginInfo; | |
| 410 m_marginInfo = 0; | |
| 411 } | |
| 412 | |
| 362 // Expand our intrinsic height to encompass floats. | 413 // Expand our intrinsic height to encompass floats. |
| 363 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlo ckFormattingContext()) | 414 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlo ckFormattingContext()) |
| 364 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); | 415 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); |
| 365 | 416 |
| 366 if (isRenderMultiColumnBlock()) { | 417 if (isRenderMultiColumnBlock()) { |
| 367 if (toRenderMultiColumnBlock(this)->shouldRelayoutMultiColumnBlock()) { | 418 if (toRenderMultiColumnBlock(this)->shouldRelayoutMultiColumnBlock()) { |
| 368 setChildNeedsLayout(MarkOnlyThis); | 419 setChildNeedsLayout(MarkOnlyThis); |
| 369 statePusher.pop(); | 420 m_statePusher->pop(); |
| 421 delete m_statePusher; | |
| 422 m_statePusher = 0; | |
| 370 return false; | 423 return false; |
| 371 } | 424 } |
| 372 } else if (hasColumns()) { | 425 } else if (hasColumns()) { |
| 373 OwnPtr<RenderOverflow> savedOverflow = m_overflow.release(); | 426 OwnPtr<RenderOverflow> savedOverflow = m_overflow.release(); |
| 374 if (childrenInline()) | 427 if (childrenInline()) |
| 375 addOverflowFromInlineChildren(); | 428 addOverflowFromInlineChildren(); |
| 376 else | 429 else |
| 377 addOverflowFromBlockChildren(); | 430 addOverflowFromBlockChildren(); |
| 378 LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? la youtOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - padd ingBefore(); | 431 LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? la youtOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - padd ingBefore(); |
| 379 m_overflow = savedOverflow.release(); | 432 m_overflow = savedOverflow.release(); |
| 380 | 433 |
| 381 if (!hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(pageLo gicalHeight, layoutOverflowLogicalBottom)) { | 434 if (!m_hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(m_pa geLogicalHeight, layoutOverflowLogicalBottom)) { |
| 382 statePusher.pop(); | 435 m_statePusher->pop(); |
| 436 delete m_statePusher; | |
| 437 m_statePusher = 0; | |
| 383 setEverHadLayout(true); | 438 setEverHadLayout(true); |
| 384 return false; | 439 return false; |
| 385 } | 440 } |
| 386 | 441 |
| 387 setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageL ogicalHeight), pageLogicalHeight); | 442 setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / m_pag eLogicalHeight), m_pageLogicalHeight); |
| 388 } | 443 } |
| 389 | 444 |
| 390 if (shouldBreakAtLineToAvoidWidow()) { | 445 if (shouldBreakAtLineToAvoidWidow()) { |
| 391 statePusher.pop(); | 446 m_statePusher->pop(); |
| 447 delete m_statePusher; | |
| 448 m_statePusher = 0; | |
| 392 setEverHadLayout(true); | 449 setEverHadLayout(true); |
| 393 return false; | 450 return false; |
| 394 } | 451 } |
| 395 | 452 |
| 396 // Calculate our new height. | 453 // Calculate our new height. |
| 397 LayoutUnit oldHeight = logicalHeight(); | 454 LayoutUnit oldHeight = logicalHeight(); |
| 398 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); | 455 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); |
| 399 | 456 |
| 400 // Before updating the final size of the flow thread make sure a forced brea k is applied after the content. | 457 // Before updating the final size of the flow thread make sure a forced brea k is applied after the content. |
| 401 // This ensures the size information is correctly computed for the last auto -height region receiving content. | 458 // This ensures the size information is correctly computed for the last auto -height region receiving content. |
| 402 if (isRenderFlowThread()) | 459 if (isRenderFlowThread()) |
| 403 toRenderFlowThread(this)->applyBreakAfterContent(oldClientAfterEdge); | 460 toRenderFlowThread(this)->applyBreakAfterContent(oldClientAfterEdge); |
| 404 | 461 |
| 405 updateLogicalHeight(); | 462 updateLogicalHeight(); |
| 406 LayoutUnit newHeight = logicalHeight(); | 463 LayoutUnit newHeight = logicalHeight(); |
| 407 if (oldHeight != newHeight) { | 464 if (oldHeight != newHeight) { |
| 408 if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !child renInline()) { | 465 if (oldHeight > newHeight && m_maxFloatLogicalBottom > newHeight && !chi ldrenInline()) { |
| 409 // One of our children's floats may have become an overhanging float for us. We need to look for it. | 466 // One of our children's floats may have become an overhanging float for us. We need to look for it. |
| 410 for (RenderObject* child = firstChild(); child; child = child->nextS ibling()) { | 467 for (RenderObject* child = firstChild(); child; child = child->nextS ibling()) { |
| 411 if (child->isRenderBlockFlow() && !child->isFloatingOrOutOfFlowP ositioned()) { | 468 if (child->isRenderBlockFlow() && !child->isFloatingOrOutOfFlowP ositioned()) { |
| 412 RenderBlockFlow* block = toRenderBlockFlow(child); | 469 RenderBlockFlow* block = toRenderBlockFlow(child); |
| 413 if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight) | 470 if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight) |
| 414 addOverhangingFloats(block, false); | 471 addOverhangingFloats(block, false); |
| 415 } | 472 } |
| 416 } | 473 } |
| 417 } | 474 } |
| 418 } | 475 } |
| 419 | 476 |
| 420 bool heightChanged = (previousHeight != newHeight); | 477 bool heightChanged = (m_heightBeforeLayout != newHeight); |
| 421 if (heightChanged) | 478 if (heightChanged) |
| 422 relayoutChildren = true; | 479 m_relayoutChildren = true; |
| 423 | 480 |
| 424 layoutPositionedObjects(relayoutChildren || isRoot()); | 481 layoutPositionedObjects(m_relayoutChildren || isRoot()); |
| 425 | 482 |
| 426 updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged); | 483 updateRegionsAndShapesAfterChildLayout(flowThreadContainingBlock(), heightCh anged); |
| 427 | 484 |
| 428 // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway). | 485 // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway). |
| 429 computeOverflow(oldClientAfterEdge); | 486 computeOverflow(oldClientAfterEdge); |
| 430 | 487 |
| 431 statePusher.pop(); | 488 m_statePusher->pop(); |
| 432 | 489 |
| 433 fitBorderToLinesIfNeeded(); | 490 fitBorderToLinesIfNeeded(); |
| 434 | 491 |
| 435 if (frameView()->partialLayout().isStopping()) | 492 if (frameView()->partialLayout().isStopping()) { |
| 493 delete m_statePusher; | |
| 494 m_statePusher = 0; | |
| 436 return true; | 495 return true; |
| 496 } | |
| 437 | 497 |
| 438 if (renderView->layoutState()->m_pageLogicalHeight) | 498 if (view()->layoutState()->m_pageLogicalHeight) |
| 439 setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop())); | 499 setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logi calTop())); |
| 440 | 500 |
| 441 updateLayerTransform(); | 501 updateLayerTransform(); |
| 442 | 502 |
| 443 // Update our scroll information if we're overflow:auto/scroll/hidden now th at we know if | 503 // Update our scroll information if we're overflow:auto/scroll/hidden now th at we know if |
| 444 // we overflow or not. | 504 // we overflow or not. |
| 445 updateScrollInfoAfterLayout(); | 505 updateScrollInfoAfterLayout(); |
| 446 | 506 |
| 447 // Repaint with our new bounds if they are different from our old bounds. | 507 // Repaint with our new bounds if they are different from our old bounds. |
| 448 bool didFullRepaint = repainter.repaintAfterLayout(); | 508 bool didFullRepaint = repainter.repaintAfterLayout(); |
| 449 if (!didFullRepaint && m_repaintLogicalTop != m_repaintLogicalBottom && (sty le()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) { | 509 if (!didFullRepaint && m_repaintLogicalTop != m_repaintLogicalBottom && (sty le()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) { |
| 450 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) | 510 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) |
| 451 setShouldRepaintOverflowIfNeeded(true); | 511 setShouldRepaintOverflowIfNeeded(true); |
| 452 else | 512 else |
| 453 repaintOverflow(); | 513 repaintOverflow(); |
| 454 } | 514 } |
| 455 | 515 |
| 516 FastTextAutosizer* textAutosizer = document().fastTextAutosizer(); | |
| 456 if (textAutosizer) | 517 if (textAutosizer) |
| 457 textAutosizer->endLayout(this); | 518 textAutosizer->endLayout(this); |
| 458 | 519 |
| 459 clearNeedsLayout(); | 520 clearNeedsLayout(); |
| 521 delete m_statePusher; | |
| 522 m_statePusher = 0; | |
|
esprehn
2014/02/15 00:35:43
This should be an OwnPtr you just clear.
| |
| 460 return true; | 523 return true; |
| 461 } | 524 } |
| 462 | 525 |
| 463 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom) | 526 bool RenderBlockFlow::preLayoutBlockChild(RenderBox* child, bool& skipChildren) |
| 464 { | 527 { |
| 465 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); | 528 updateBlockChildDirtyBitsBeforeLayout(m_relayoutChildren, child); |
| 466 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); | 529 |
| 530 if (child->isOutOfFlowPositioned()) { | |
| 531 child->containingBlock()->insertPositionedObject(child); | |
| 532 adjustPositionedBlock(child, *m_marginInfo); | |
| 533 skipChildren = true; | |
| 534 return false; | |
| 535 } | |
| 536 | |
| 537 if (child->isFloating()) { | |
| 538 insertFloatingObject(child); | |
| 539 adjustFloatingBlock(*m_marginInfo); | |
| 540 skipChildren = true; | |
| 541 return false; | |
| 542 } | |
| 543 | |
| 544 m_oldPosMarginBefore = maxPositiveMarginBefore(); | |
| 545 m_oldNegMarginBefore = maxNegativeMarginBefore(); | |
| 467 | 546 |
| 468 // The child is a normal flow object. Compute the margins we will use for co llapsing now. | 547 // The child is a normal flow object. Compute the margins we will use for co llapsing now. |
| 469 child->computeAndSetBlockDirectionMargins(this); | 548 child->computeAndSetBlockDirectionMargins(this); |
| 470 | 549 |
| 471 // Try to guess our correct logical top position. In most cases this guess w ill | 550 // Try to guess our correct logical top position. In most cases this guess w ill |
| 472 // be correct. Only if we're wrong (when we compute the real logical top pos ition) | 551 // be correct. Only if we're wrong (when we compute the real logical top pos ition) |
| 473 // will we have to potentially relayout. | 552 // will we have to potentially relayout. |
| 474 LayoutUnit estimateWithoutPagination; | 553 m_estimateWithoutPagination = 0; |
| 475 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo , estimateWithoutPagination); | 554 m_logicalTopEstimate = estimateLogicalTopPosition(child, *m_marginInfo, m_es timateWithoutPagination); |
| 476 | 555 |
| 477 // Cache our old rect so that we can dirty the proper repaint rects if the c hild moves. | 556 // Cache our old rect so that we can dirty the proper repaint rects if the c hild moves. |
| 478 LayoutRect oldRect = child->frameRect(); | 557 m_oldRect = child->frameRect(); |
| 479 LayoutUnit oldLogicalTop = logicalTopForChild(child); | 558 LayoutUnit oldLogicalTop = logicalTopForChild(child); |
| 480 | 559 |
| 481 #if !ASSERT_DISABLED | 560 #if !ASSERT_DISABLED |
| 482 LayoutSize oldLayoutDelta = RuntimeEnabledFeatures::repaintAfterLayoutEnable d() ? LayoutSize() : view()->layoutDelta(); | 561 m_oldLayoutDelta = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? Lay outSize() : view()->layoutDelta(); |
| 483 #endif | 562 #endif |
| 484 // Go ahead and position the child as though it didn't collapse with the top . | 563 // Go ahead and position the child as though it didn't collapse with the top . |
| 485 setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta); | 564 setLogicalTopForChild(child, m_logicalTopEstimate, ApplyLayoutDelta); |
| 486 | 565 |
| 487 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child ) : 0; | 566 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child ) : 0; |
| 488 RenderBlockFlow* childRenderBlockFlow = (childRenderBlock && child->isRender BlockFlow()) ? toRenderBlockFlow(child) : 0; | 567 RenderBlockFlow* childRenderBlockFlow = (childRenderBlock && child->isRender BlockFlow()) ? toRenderBlockFlow(child) : 0; |
| 489 bool markDescendantsWithFloats = false; | 568 bool markDescendantsWithFloats = false; |
| 490 if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRe nderBlock && childRenderBlock->containsFloats()) { | 569 if (m_logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && child RenderBlock && childRenderBlock->containsFloats()) { |
| 491 markDescendantsWithFloats = true; | 570 markDescendantsWithFloats = true; |
| 492 } else if (UNLIKELY(logicalTopEstimate.mightBeSaturated())) { | 571 } else if (UNLIKELY(m_logicalTopEstimate.mightBeSaturated())) { |
| 493 // logicalTopEstimate, returned by estimateLogicalTopPosition, might be saturated for | 572 // logicalTopEstimate, returned by estimateLogicalTopPosition, might be saturated for |
| 494 // very large elements. If it does the comparison with oldLogicalTop mig ht yield a | 573 // very large elements. If it does the comparison with oldLogicalTop mig ht yield a |
| 495 // false negative as adding and removing margins, borders etc from a sat urated number | 574 // false negative as adding and removing margins, borders etc from a sat urated number |
| 496 // might yield incorrect results. If this is the case always mark for la yout. | 575 // might yield incorrect results. If this is the case always mark for la yout. |
| 497 markDescendantsWithFloats = true; | 576 markDescendantsWithFloats = true; |
| 498 } else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { | 577 } else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { |
| 499 // If an element might be affected by the presence of floats, then alway s mark it for | 578 // If an element might be affected by the presence of floats, then alway s mark it for |
| 500 // layout. | 579 // layout. |
| 501 LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom ()); | 580 LayoutUnit fb = max(m_previousFloatLogicalBottom, lowestFloatLogicalBott om()); |
| 502 if (fb > logicalTopEstimate) | 581 if (fb > m_logicalTopEstimate) |
| 503 markDescendantsWithFloats = true; | 582 markDescendantsWithFloats = true; |
| 504 } | 583 } |
| 505 | 584 |
| 506 if (childRenderBlockFlow) { | 585 if (childRenderBlockFlow) { |
| 507 if (markDescendantsWithFloats) | 586 if (markDescendantsWithFloats) |
| 508 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); | 587 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); |
| 509 if (!child->isWritingModeRoot()) | 588 if (!child->isWritingModeRoot()) |
| 510 previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogi calTop + childRenderBlockFlow->lowestFloatLogicalBottom()); | 589 m_previousFloatLogicalBottom = max(m_previousFloatLogicalBottom, old LogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom()); |
| 511 } | 590 } |
| 512 | 591 |
| 513 SubtreeLayoutScope layoutScope(child); | 592 m_childLayoutScope = new SubtreeLayoutScope(child); |
| 514 if (!child->needsLayout()) | 593 if (!child->needsLayout()) |
| 515 child->markForPaginationRelayoutIfNeeded(layoutScope); | 594 child->markForPaginationRelayoutIfNeeded(*m_childLayoutScope); |
| 516 | 595 |
| 517 bool childHadLayout = child->everHadLayout(); | 596 m_childHadLayout = child->everHadLayout(); |
| 518 bool childNeededLayout = child->needsLayout(); | 597 m_childNeededLayout = child->needsLayout(); |
|
esprehn
2014/02/15 00:35:43
This doesn't feel right. Storing so much state in
atreat
2014/02/18 16:03:57
Right, see the comment in the header file. We'll
| |
| 519 if (childNeededLayout) | 598 skipChildren |= !m_childNeededLayout; |
| 520 child->layout(); | 599 if (m_childNeededLayout) { |
| 600 if (child->isNonRecursiveLayout()) | |
| 601 child->preLayout(); | |
| 602 else | |
| 603 child->layout(); | |
| 604 } | |
| 605 return true; | |
| 606 } | |
| 521 | 607 |
| 522 if (frameView()->partialLayout().isStopping()) | 608 void RenderBlockFlow::postLayoutBlockChild(RenderBox* child) |
| 609 { | |
| 610 if (child->isOutOfFlowPositioned() || child->isFloating()) | |
| 523 return; | 611 return; |
| 524 | 612 |
| 613 if (m_childNeededLayout && child->isNonRecursiveLayout()) | |
| 614 child->postLayout(); | |
| 615 | |
| 525 // Cache if we are at the top of the block right now. | 616 // Cache if we are at the top of the block right now. |
| 526 bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); | 617 bool atBeforeSideOfBlock = m_marginInfo->atBeforeSideOfBlock(); |
| 527 | 618 |
| 528 // Now determine the correct ypos based off examination of collapsing margin | 619 // Now determine the correct ypos based off examination of collapsing margin |
| 529 // values. | 620 // values. |
| 530 LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo); | 621 LayoutUnit logicalTopBeforeClear = collapseMargins(child, *m_marginInfo); |
| 531 | 622 |
| 532 // Now check for clear. | 623 // Now check for clear. |
| 533 LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, old PosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear); | 624 LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, *m_marginInfo, m_oldPosMarginBefore, m_oldNegMarginBefore, logicalTopBeforeClear); |
| 534 | 625 |
| 535 bool paginated = view()->layoutState()->isPaginated(); | 626 bool paginated = view()->layoutState()->isPaginated(); |
| 536 if (paginated) { | 627 if (paginated) { |
| 537 logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClea r, estimateWithoutPagination, child, | 628 logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClea r, m_estimateWithoutPagination, child, |
| 538 atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear ); | 629 atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear ); |
| 539 } | 630 } |
| 540 | 631 |
| 541 setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta); | 632 setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta); |
| 542 | 633 |
| 634 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child ) : 0; | |
| 635 RenderBlockFlow* childRenderBlockFlow = (childRenderBlock && child->isRender BlockFlow()) ? toRenderBlockFlow(child) : 0; | |
| 636 | |
| 543 // Now we have a final top position. See if it really does end up being diff erent from our estimate. | 637 // Now we have a final top position. See if it really does end up being diff erent from our estimate. |
| 544 // clearFloatsIfNeeded can also mark the child as needing a layout even thou gh we didn't move. This happens | 638 // clearFloatsIfNeeded can also mark the child as needing a layout even thou gh we didn't move. This happens |
| 545 // when collapseMargins dynamically adds overhanging floats because of a chi ld with negative margins. | 639 // when collapseMargins dynamically adds overhanging floats because of a chi ld with negative margins. |
| 546 if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout() || (p aginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWidow( ))) { | 640 if (logicalTopAfterClear != m_logicalTopEstimate || child->needsLayout() || (paginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWido w())) { |
| 547 SubtreeLayoutScope layoutScope(child); | 641 SubtreeLayoutScope layoutScope(child); |
| 548 if (child->shrinkToAvoidFloats()) { | 642 if (child->shrinkToAvoidFloats()) { |
| 549 // The child's width depends on the line width. | 643 // The child's width depends on the line width. |
| 550 // When the child shifts to clear an item, its width can | 644 // When the child shifts to clear an item, its width can |
| 551 // change (because it has more available line width). | 645 // change (because it has more available line width). |
| 552 // So go ahead and mark the item as dirty. | 646 // So go ahead and mark the item as dirty. |
| 553 layoutScope.setChildNeedsLayout(child); | 647 layoutScope.setChildNeedsLayout(child); |
| 554 } | 648 } |
| 555 | 649 |
| 556 if (childRenderBlock) { | 650 if (childRenderBlock) { |
| 557 if (!child->avoidsFloats() && childRenderBlock->containsFloats()) | 651 if (!child->avoidsFloats() && childRenderBlock->containsFloats()) |
| 558 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); | 652 childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); |
| 559 if (!child->needsLayout()) | 653 if (!child->needsLayout()) |
| 560 child->markForPaginationRelayoutIfNeeded(layoutScope); | 654 child->markForPaginationRelayoutIfNeeded(layoutScope); |
| 561 } | 655 } |
| 562 | 656 |
| 563 // Our guess was wrong. Make the child lay itself out again. | 657 // Our guess was wrong. Make the child lay itself out again. |
| 564 child->layoutIfNeeded(); | 658 child->layoutIfNeeded(); |
| 565 } | 659 } |
| 566 | 660 |
| 567 // If we previously encountered a self-collapsing sibling of this child that had clearance then | 661 // If we previously encountered a self-collapsing sibling of this child that had clearance then |
| 568 // we set this bit to ensure we would not collapse the child's margins, and those of any subsequent | 662 // we set this bit to ensure we would not collapse the child's margins, and those of any subsequent |
| 569 // self-collapsing siblings, with our parent. If this child is not self-coll apsing then it can | 663 // self-collapsing siblings, with our parent. If this child is not self-coll apsing then it can |
| 570 // collapse its margins with the parent so reset the bit. | 664 // collapse its margins with the parent so reset the bit. |
| 571 if (!marginInfo.canCollapseMarginAfterWithLastChild() && !child->isSelfColla psingBlock()) | 665 if (!m_marginInfo->canCollapseMarginAfterWithLastChild() && !child->isSelfCo llapsingBlock()) |
| 572 marginInfo.setCanCollapseMarginAfterWithLastChild(true); | 666 m_marginInfo->setCanCollapseMarginAfterWithLastChild(true); |
| 573 | 667 |
| 574 // We are no longer at the top of the block if we encounter a non-empty chil d. | 668 // We are no longer at the top of the block if we encounter a non-empty chil d. |
| 575 // This has to be done after checking for clear, so that margins can be rese t if a clear occurred. | 669 // This has to be done after checking for clear, so that margins can be rese t if a clear occurred. |
| 576 if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock()) | 670 if (m_marginInfo->atBeforeSideOfBlock() && !child->isSelfCollapsingBlock()) |
| 577 marginInfo.setAtBeforeSideOfBlock(false); | 671 m_marginInfo->setAtBeforeSideOfBlock(false); |
| 578 | 672 |
| 579 // Now place the child in the correct left position | 673 // Now place the child in the correct left position |
| 580 determineLogicalLeftPositionForChild(child, ApplyLayoutDelta); | 674 determineLogicalLeftPositionForChild(child, ApplyLayoutDelta); |
| 581 | 675 |
| 582 LayoutSize childOffset = child->location() - oldRect.location(); | 676 LayoutSize childOffset = child->location() - m_oldRect.location(); |
| 583 relayoutShapeDescendantIfMoved(childRenderBlock, childOffset); | 677 relayoutShapeDescendantIfMoved(childRenderBlock, childOffset); |
| 584 | 678 |
| 585 // Update our height now that the child has been placed in the correct posit ion. | 679 // Update our height now that the child has been placed in the correct posit ion. |
| 586 setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); | 680 setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); |
| 587 if (mustSeparateMarginAfterForChild(child)) { | 681 if (mustSeparateMarginAfterForChild(child)) { |
| 588 setLogicalHeight(logicalHeight() + marginAfterForChild(child)); | 682 setLogicalHeight(logicalHeight() + marginAfterForChild(child)); |
| 589 marginInfo.clearMargin(); | 683 m_marginInfo->clearMargin(); |
| 590 } | 684 } |
| 591 // If the child has overhanging floats that intrude into following siblings (or possibly out | 685 // If the child has overhanging floats that intrude into following siblings (or possibly out |
| 592 // of this block), then the parent gets notified of the floats now. | 686 // of this block), then the parent gets notified of the floats now. |
| 593 if (childRenderBlockFlow && childRenderBlockFlow->containsFloats()) | 687 if (childRenderBlockFlow && childRenderBlockFlow->containsFloats()) |
| 594 maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats( childRenderBlockFlow, !childNeededLayout)); | 688 m_maxFloatLogicalBottom = max(m_maxFloatLogicalBottom, addOverhangingFlo ats(childRenderBlockFlow, !m_childNeededLayout)); |
| 595 | 689 |
| 596 if (childOffset.width() || childOffset.height()) { | 690 if (childOffset.width() || childOffset.height()) { |
| 597 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) | 691 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) |
| 598 view()->addLayoutDelta(childOffset); | 692 view()->addLayoutDelta(childOffset); |
| 599 | 693 |
| 600 // If the child moved, we have to repaint it as well as any floating/pos itioned | 694 // If the child moved, we have to repaint it as well as any floating/pos itioned |
| 601 // descendants. An exception is if we need a layout. In this case, we kn ow we're going to | 695 // descendants. An exception is if we need a layout. In this case, we kn ow we're going to |
| 602 // repaint ourselves (and the child) anyway. | 696 // repaint ourselves (and the child) anyway. |
| 603 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && childHadLayou t && !selfNeedsLayout()) | 697 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && m_childHadLay out && !selfNeedsLayout()) |
| 604 child->repaintOverhangingFloats(true); | 698 child->repaintOverhangingFloats(true); |
| 605 else if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintD uringLayout()) | 699 else if (m_childHadLayout && !selfNeedsLayout() && child->checkForRepain tDuringLayout()) |
| 606 child->repaintDuringLayoutIfMoved(oldRect); | 700 child->repaintDuringLayoutIfMoved(m_oldRect); |
| 607 } | 701 } |
| 608 | 702 |
| 609 if (!childHadLayout && child->checkForRepaint()) { | 703 if (!m_childHadLayout && child->checkForRepaint()) { |
| 610 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) | 704 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) |
| 611 child->repaint(); | 705 child->repaint(); |
| 612 child->repaintOverhangingFloats(true); | 706 child->repaintOverhangingFloats(true); |
| 613 } | 707 } |
| 614 | 708 |
| 615 if (paginated) { | 709 if (paginated) { |
| 616 // Check for an after page/column break. | 710 // Check for an after page/column break. |
| 617 LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInf o); | 711 LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), *m_margin Info); |
| 618 if (newHeight != height()) | 712 if (newHeight != height()) |
| 619 setLogicalHeight(newHeight); | 713 setLogicalHeight(newHeight); |
| 620 } | 714 } |
| 621 | 715 |
| 622 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { | 716 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { |
| 623 ASSERT(view()->layoutDeltaMatches(oldLayoutDelta)); | 717 ASSERT(view()->layoutDeltaMatches(m_oldLayoutDelta)); |
| 624 } | 718 } |
| 719 | |
| 720 m_lastNormalFlowChild = child; | |
| 721 delete m_childLayoutScope; | |
| 722 m_childLayoutScope = 0; | |
| 625 } | 723 } |
| 626 | 724 |
| 627 LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA fterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBefore SideOfBlock) | 725 LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA fterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBefore SideOfBlock) |
| 628 { | 726 { |
| 629 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child ) : 0; | 727 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child ) : 0; |
| 630 | 728 |
| 631 if (estimateWithoutPagination != logicalTopAfterClear) { | 729 if (estimateWithoutPagination != logicalTopAfterClear) { |
| 632 // Our guess prior to pagination movement was wrong. Before we attempt t o paginate, let's try again at the new | 730 // Our guess prior to pagination movement was wrong. Before we attempt t o paginate, let's try again at the new |
| 633 // position. | 731 // position. |
| 634 setLogicalHeight(logicalTopAfterClear); | 732 setLogicalHeight(logicalTopAfterClear); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 841 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set( ); | 939 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set( ); |
| 842 FloatingObjectSetIterator end = floatingObjectSet.end(); | 940 FloatingObjectSetIterator end = floatingObjectSet.end(); |
| 843 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end && !oldIntrudingFloatSet.isEmpty(); ++it) | 941 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end && !oldIntrudingFloatSet.isEmpty(); ++it) |
| 844 oldIntrudingFloatSet.remove((*it)->renderer()); | 942 oldIntrudingFloatSet.remove((*it)->renderer()); |
| 845 if (!oldIntrudingFloatSet.isEmpty()) | 943 if (!oldIntrudingFloatSet.isEmpty()) |
| 846 markAllDescendantsWithFloatsForLayout(); | 944 markAllDescendantsWithFloatsForLayout(); |
| 847 } | 945 } |
| 848 } | 946 } |
| 849 } | 947 } |
| 850 | 948 |
| 851 void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& max FloatLogicalBottom, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, Layo utUnit afterEdge) | 949 void RenderBlockFlow::layoutBlockChildren(LayoutUnit beforeEdge, LayoutUnit afte rEdge, bool traverseChildren) |
| 852 { | 950 { |
| 853 dirtyForLayoutFromPercentageHeightDescendants(layoutScope); | |
| 854 | |
| 855 // Lay out our hypothetical grid line as though it occurs at the top of the block. | |
| 856 if (view()->layoutState()->lineGrid() == this) | |
| 857 layoutLineGridBox(); | |
| 858 | |
| 859 // The margin struct caches all our current margin collapsing state. The com pact struct caches state when we encounter compacts, | 951 // The margin struct caches all our current margin collapsing state. The com pact struct caches state when we encounter compacts, |
| 860 MarginInfo marginInfo(this, beforeEdge, afterEdge); | 952 m_marginInfo = new MarginInfo(this, beforeEdge, afterEdge); |
|
esprehn
2014/02/15 00:35:43
Adding more mallocs doesn't seem like the right wa
| |
| 861 | 953 |
| 862 // Fieldsets need to find their legend and position it inside the border of the object. | 954 // Fieldsets need to find their legend and position it inside the border of the object. |
| 863 // The legend then gets skipped during normal layout. The same is true for r uby text. | 955 // The legend then gets skipped during normal layout. The same is true for r uby text. |
| 864 // It doesn't get included in the normal layout process but is instead skipp ed. | 956 // It doesn't get included in the normal layout process but is instead skipp ed. |
| 865 RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren, layoutScope); | 957 m_childToExclude = layoutSpecialExcludedChild(m_relayoutChildren, *m_layoutS cope); |
| 958 m_previousFloatLogicalBottom = 0; | |
| 959 m_maxFloatLogicalBottom = 0; | |
| 960 m_lastNormalFlowChild = 0; | |
| 866 | 961 |
| 867 LayoutUnit previousFloatLogicalBottom = 0; | 962 if (!traverseChildren) |
| 868 maxFloatLogicalBottom = 0; | 963 return; |
| 869 | 964 |
| 870 RenderBox* next = firstChildBox(); | 965 bool skippingChildren = false; |
| 871 RenderBox* lastNormalFlowChild = 0; | 966 #if NON_RECURSIVE |
| 967 Order order = Pre; | |
| 968 RenderObject* childObject = nextForLayout(order, this, skippingChildren); | |
| 969 for (; childObject && childObject != this; childObject = childObject->nextFo rLayout(order, this, skippingChildren)) { | |
| 970 if (!childObject->isBox()) | |
| 971 continue; | |
| 972 RenderBox *child = toRenderBox(childObject); | |
| 973 skippingChildren = child->childrenInline(); | |
| 974 #else | |
| 975 (void)skippingChildren; | |
| 976 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) { | |
| 977 #endif | |
| 872 | 978 |
| 873 while (next) { | 979 ASSERT(child->parent()->isRenderBlockFlow()); |
| 874 RenderBox* child = next; | 980 RenderBlockFlow* directParent = toRenderBlockFlow(child->parent()); |
| 875 next = child->nextSiblingBox(); | |
| 876 | 981 |
| 877 LayoutRectRecorder recorder(*child); | 982 LayoutRectRecorder recorder(*child); |
| 878 | 983 if (directParent->m_childToExclude == child) { |
| 879 if (childToExclude == child) | 984 skippingChildren = true; |
| 880 continue; // Skip this child, since it will be positioned by the spe cialized subclass (fieldsets and ruby runs). | 985 continue; // Skip this child, since it will be positioned by the spe cialized subclass (fieldsets and ruby runs). |
| 881 | |
| 882 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child); | |
| 883 | |
| 884 if (child->isOutOfFlowPositioned()) { | |
| 885 child->containingBlock()->insertPositionedObject(child); | |
| 886 adjustPositionedBlock(child, marginInfo); | |
| 887 continue; | |
| 888 } | |
| 889 if (child->isFloating()) { | |
| 890 insertFloatingObject(child); | |
| 891 adjustFloatingBlock(marginInfo); | |
| 892 continue; | |
| 893 } | 986 } |
| 894 | 987 |
| 988 #if NON_RECURSIVE | |
| 989 if (order == Pre) { | |
| 990 #endif | |
| 991 | |
| 895 // Lay out the child. | 992 // Lay out the child. |
| 896 layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloat LogicalBottom); | 993 if (!directParent->preLayoutBlockChild(child, skippingChildren)) |
| 897 lastNormalFlowChild = child; | 994 continue; |
| 995 | |
| 996 #if NON_RECURSIVE | |
| 997 } else { | |
| 998 #endif | |
| 999 | |
| 1000 directParent->postLayoutBlockChild(child); | |
| 1001 | |
| 1002 #if NON_RECURSIVE | |
| 1003 } | |
| 1004 #endif | |
| 898 | 1005 |
| 899 // If doing a partial layout and the child was the target renderer, earl y exit here. | 1006 // If doing a partial layout and the child was the target renderer, earl y exit here. |
| 900 if (frameView()->partialLayout().checkPartialLayoutComplete(child)) | 1007 if (frameView()->partialLayout().checkPartialLayoutComplete(child)) |
| 901 return; | 1008 return; |
| 902 | |
| 903 } | 1009 } |
| 904 | |
| 905 // Now do the handling of the bottom of the block, adding in our bottom bord er/padding and | |
| 906 // determining the correct collapsed bottom margin information. | |
| 907 handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, marginInf o); | |
| 908 } | 1010 } |
| 909 | 1011 |
| 910 // Our MarginInfo state used when laying out block children. | 1012 // Our MarginInfo state used when laying out block children. |
| 911 MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin g, LayoutUnit afterBorderPadding) | 1013 MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin g, LayoutUnit afterBorderPadding) |
| 912 : m_canCollapseMarginAfterWithLastChild(true) | 1014 : m_canCollapseMarginAfterWithLastChild(true) |
| 913 , m_atBeforeSideOfBlock(true) | 1015 , m_atBeforeSideOfBlock(true) |
| 914 , m_atAfterSideOfBlock(false) | 1016 , m_atAfterSideOfBlock(false) |
| 915 , m_hasMarginBeforeQuirk(false) | 1017 , m_hasMarginBeforeQuirk(false) |
| 916 , m_hasMarginAfterQuirk(false) | 1018 , m_hasMarginAfterQuirk(false) |
| 917 , m_determinedMarginBeforeQuirk(false) | 1019 , m_determinedMarginBeforeQuirk(false) |
| (...skipping 1958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2876 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() | 2978 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() |
| 2877 { | 2979 { |
| 2878 if (m_rareData) | 2980 if (m_rareData) |
| 2879 return *m_rareData; | 2981 return *m_rareData; |
| 2880 | 2982 |
| 2881 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); | 2983 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); |
| 2882 return *m_rareData; | 2984 return *m_rareData; |
| 2883 } | 2985 } |
| 2884 | 2986 |
| 2885 } // namespace WebCore | 2987 } // namespace WebCore |
| OLD | NEW |