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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 | 270 |
271 bool LayoutBlockFlow::updateLogicalWidthAndColumnWidth() { | 271 bool LayoutBlockFlow::updateLogicalWidthAndColumnWidth() { |
272 bool relayoutChildren = LayoutBlock::updateLogicalWidthAndColumnWidth(); | 272 bool relayoutChildren = LayoutBlock::updateLogicalWidthAndColumnWidth(); |
273 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 273 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
274 if (flowThread->needsNewWidth()) | 274 if (flowThread->needsNewWidth()) |
275 return true; | 275 return true; |
276 } | 276 } |
277 return relayoutChildren; | 277 return relayoutChildren; |
278 } | 278 } |
279 | 279 |
280 void LayoutBlockFlow::checkForPaginationLogicalHeightChange( | |
281 LayoutUnit& pageLogicalHeight) { | |
282 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | |
283 // Calculate the non-auto content box height, or set it to 0 if it's auto. | |
284 // We need to know this before layout, so that we can figure out where to | |
285 // insert column breaks. We also treat LayoutView (which may be paginated, | |
286 // which uses the multicol implmentation) as having non-auto height, since | |
287 // its height is deduced from the viewport height. | |
288 // We use computeLogicalHeight() to calculate the content box height. That | |
289 // method will clamp against max-height and min-height. Since we're now at | |
290 // the beginning of layout, and we don't know the actual height of the | |
291 // content yet, only call that method when height is definite, or we might | |
292 // fool ourselves into believing that columns have a definite height when | |
293 // they in fact don't. | |
294 LayoutUnit columnHeight; | |
295 if (hasDefiniteLogicalHeight() || isLayoutView()) { | |
296 LogicalExtentComputedValues computedValues; | |
297 computeLogicalHeight(LayoutUnit(), logicalTop(), computedValues); | |
298 columnHeight = computedValues.m_extent - borderAndPaddingLogicalHeight() - | |
299 scrollbarLogicalHeight(); | |
300 } | |
301 flowThread->setColumnHeightAvailable(std::max(columnHeight, LayoutUnit())); | |
302 } else if (isLayoutFlowThread()) { | |
303 LayoutFlowThread* flowThread = toLayoutFlowThread(this); | |
304 | |
305 // FIXME: This is a hack to always make sure we have a page logical height, | |
306 // if said height is known. The page logical height thing in LayoutState is | |
307 // meaningless for flow thread-based pagination (page height isn't | |
308 // necessarily uniform throughout the flow thread), but as long as it is | |
309 // used universally as a means to determine whether page height is known or | |
310 // not, we need this. Page height is unknown when column balancing is | |
311 // enabled and flow thread height is still unknown (i.e. during the first | |
312 // layout pass). When it's unknown, we need to prevent the pagination code | |
313 // from assuming page breaks everywhere and thereby eating every top margin. | |
314 // It should be trivial to clean up and get rid of this hack once the old | |
315 // multicol implementation is gone. | |
316 pageLogicalHeight = | |
317 flowThread->isPageLogicalHeightKnown() ? LayoutUnit(1) : LayoutUnit(); | |
318 } | |
319 } | |
320 | |
321 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) { | 280 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) { |
322 ASSERT(lineToBreak >= 0); | 281 ASSERT(lineToBreak >= 0); |
323 ensureRareData(); | 282 ensureRareData(); |
324 ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow); | 283 ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow); |
325 m_rareData->m_lineBreakToAvoidWidow = lineToBreak; | 284 m_rareData->m_lineBreakToAvoidWidow = lineToBreak; |
326 } | 285 } |
327 | 286 |
328 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() { | 287 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() { |
329 ASSERT(!shouldBreakAtLineToAvoidWidow()); | 288 ASSERT(!shouldBreakAtLineToAvoidWidow()); |
330 | 289 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 | 396 |
438 if (!relayoutChildren && simplifiedLayout()) | 397 if (!relayoutChildren && simplifiedLayout()) |
439 return; | 398 return; |
440 | 399 |
441 LayoutAnalyzer::BlockScope analyzer(*this); | 400 LayoutAnalyzer::BlockScope analyzer(*this); |
442 SubtreeLayoutScope layoutScope(*this); | 401 SubtreeLayoutScope layoutScope(*this); |
443 | 402 |
444 // Multiple passes might be required for column based layout. | 403 // Multiple passes might be required for column based layout. |
445 // The number of passes could be as high as the number of columns. | 404 // The number of passes could be as high as the number of columns. |
446 bool done = false; | 405 bool done = false; |
447 LayoutUnit pageLogicalHeight; | |
448 while (!done) | 406 while (!done) |
449 done = layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope); | 407 done = layoutBlockFlow(relayoutChildren, layoutScope); |
450 | 408 |
451 updateLayerTransformAfterLayout(); | 409 updateLayerTransformAfterLayout(); |
452 | 410 |
453 updateAfterLayout(); | 411 updateAfterLayout(); |
454 | 412 |
455 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) | 413 if (isHTMLDialogElement(node()) && isOutOfFlowPositioned()) |
456 positionDialog(); | 414 positionDialog(); |
457 | 415 |
458 clearNeedsLayout(); | 416 clearNeedsLayout(); |
459 updateIsSelfCollapsing(); | 417 updateIsSelfCollapsing(); |
460 } | 418 } |
461 | 419 |
462 DISABLE_CFI_PERF | 420 DISABLE_CFI_PERF |
463 inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, | 421 inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, |
464 LayoutUnit& pageLogicalHeight, | |
465 SubtreeLayoutScope& layoutScope) { | 422 SubtreeLayoutScope& layoutScope) { |
466 LayoutUnit oldLeft = logicalLeft(); | 423 LayoutUnit oldLeft = logicalLeft(); |
467 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); | 424 bool logicalWidthChanged = updateLogicalWidthAndColumnWidth(); |
468 relayoutChildren |= logicalWidthChanged; | 425 relayoutChildren |= logicalWidthChanged; |
469 | 426 |
470 rebuildFloatsFromIntruding(); | 427 rebuildFloatsFromIntruding(); |
471 | 428 |
472 checkForPaginationLogicalHeightChange(pageLogicalHeight); | 429 LayoutState state(*this, logicalWidthChanged); |
473 | |
474 LayoutState state(*this, pageLogicalHeight, logicalWidthChanged); | |
475 | 430 |
476 if (m_paginationStateChanged) { | 431 if (m_paginationStateChanged) { |
477 // We now need a deep layout to clean up struts after pagination, if we | 432 // We now need a deep layout to clean up struts after pagination, if we |
478 // just ceased to be paginated, or, if we just became paginated on the | 433 // just ceased to be paginated, or, if we just became paginated on the |
479 // other hand, we now need the deep layout, to insert pagination struts. | 434 // other hand, we now need the deep layout, to insert pagination struts. |
480 m_paginationStateChanged = false; | 435 m_paginationStateChanged = false; |
481 state.setPaginationStateChanged(); | 436 state.setPaginationStateChanged(); |
482 } | 437 } |
483 | 438 |
484 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, | 439 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); | 492 layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); |
538 | 493 |
539 bool preferredLogicalWidthsBecameDirty = | 494 bool preferredLogicalWidthsBecameDirty = |
540 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty(); | 495 !preferredLogicalWidthsWereDirty && preferredLogicalWidthsDirty(); |
541 if (preferredLogicalWidthsBecameDirty) { | 496 if (preferredLogicalWidthsBecameDirty) { |
542 // The only thing that should dirty preferred widths at this point is the | 497 // The only thing that should dirty preferred widths at this point is the |
543 // addition of overflow:auto scrollbars in a descendant. To avoid a | 498 // addition of overflow:auto scrollbars in a descendant. To avoid a |
544 // potential infinite loop, run layout again with auto scrollbars frozen in | 499 // potential infinite loop, run layout again with auto scrollbars frozen in |
545 // their current state. | 500 // their current state. |
546 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; | 501 PaintLayerScrollableArea::FreezeScrollbarsScope freezeScrollbars; |
547 return layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope); | 502 return layoutBlockFlow(relayoutChildren, layoutScope); |
548 } | 503 } |
549 | 504 |
550 // Expand our intrinsic height to encompass floats. | 505 // Expand our intrinsic height to encompass floats. |
551 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && | 506 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && |
552 createsNewFormattingContext()) | 507 createsNewFormattingContext()) |
553 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); | 508 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); |
554 | 509 |
555 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 510 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
556 if (flowThread->columnHeightsChanged()) { | 511 if (flowThread->columnHeightsChanged()) { |
557 setChildNeedsLayout(MarkOnlyThis); | 512 setChildNeedsLayout(MarkOnlyThis); |
(...skipping 3980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4538 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4493 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
4539 } | 4494 } |
4540 | 4495 |
4541 void LayoutBlockFlow::invalidateDisplayItemClients( | 4496 void LayoutBlockFlow::invalidateDisplayItemClients( |
4542 PaintInvalidationReason invalidationReason) const { | 4497 PaintInvalidationReason invalidationReason) const { |
4543 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4498 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
4544 invalidationReason); | 4499 invalidationReason); |
4545 } | 4500 } |
4546 | 4501 |
4547 } // namespace blink | 4502 } // namespace blink |
OLD | NEW |