OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 | 357 |
358 m_blockOffsetInEnclosingFlowThread = enclosingFlowThread() ? multiColumnBloc
kFlow()->offsetFromLogicalTopOfFirstPage() : LayoutUnit(); | 358 m_blockOffsetInEnclosingFlowThread = enclosingFlowThread() ? multiColumnBloc
kFlow()->offsetFromLogicalTopOfFirstPage() : LayoutUnit(); |
359 | 359 |
360 for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co
lumnBox->nextSiblingMultiColumnBox()) { | 360 for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co
lumnBox->nextSiblingMultiColumnBox()) { |
361 if (!columnBox->isLayoutMultiColumnSet()) { | 361 if (!columnBox->isLayoutMultiColumnSet()) { |
362 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot
her type is expected. | 362 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot
her type is expected. |
363 m_needsColumnHeightsRecalculation = true; | 363 m_needsColumnHeightsRecalculation = true; |
364 continue; | 364 continue; |
365 } | 365 } |
366 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); | 366 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); |
| 367 layoutScope.setChildNeedsLayout(columnSet); |
367 if (!m_inBalancingPass) { | 368 if (!m_inBalancingPass) { |
368 // This is the initial layout pass. We need to reset the column heig
ht, because contents | 369 // This is the initial layout pass. We need to reset the column heig
ht, because contents |
369 // typically have changed. | 370 // typically have changed. |
370 columnSet->resetColumnHeight(); | 371 columnSet->resetColumnHeight(); |
371 } | 372 } |
372 if (!m_needsColumnHeightsRecalculation) | 373 if (!m_needsColumnHeightsRecalculation) |
373 m_needsColumnHeightsRecalculation = columnSet->heightIsAuto(); | 374 m_needsColumnHeightsRecalculation = columnSet->heightIsAuto(); |
374 } | 375 } |
375 | 376 |
376 invalidateColumnSets(); | 377 invalidateColumnSets(); |
377 layout(); | 378 layout(); |
378 } | 379 } |
379 | 380 |
380 bool LayoutMultiColumnFlowThread::recalculateColumnHeights() | 381 bool LayoutMultiColumnFlowThread::recalculateColumnHeights() |
381 { | 382 { |
382 // All column sets that needed layout have now been laid out, so we can fina
lly validate them. | 383 // All column sets that needed layout have now been laid out, so we can fina
lly validate them. |
383 validateColumnSets(); | 384 validateColumnSets(); |
384 | 385 |
385 if (!m_needsColumnHeightsRecalculation) | 386 if (!m_needsColumnHeightsRecalculation) |
386 return false; | 387 return false; |
387 | 388 |
388 // Column heights may change here because of balancing. We may have to do mu
ltiple layout | 389 // Column heights may change here because of balancing. We may have to do mu
ltiple layout |
389 // passes, depending on how the contents is fitted to the changed column hei
ghts. In most | 390 // passes, depending on how the contents is fitted to the changed column hei
ghts. In most |
390 // cases, laying out again twice or even just once will suffice. Sometimes w
e need more | 391 // cases, laying out again twice or even just once will suffice. Sometimes w
e need more |
391 // passes than that, though, but the number of retries should not exceed the
number of | 392 // passes than that, though, but the number of retries should not exceed the
number of |
392 // columns, unless we have a bug. | 393 // columns, unless we have a bug. |
393 bool needsRelayout = false; | 394 bool needsRelayout = false; |
394 for (LayoutMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet;
multicolSet = multicolSet->nextSiblingMultiColumnSet()) { | 395 for (LayoutMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet;
multicolSet = multicolSet->nextSiblingMultiColumnSet()) |
395 needsRelayout |= multicolSet->recalculateColumnHeight(m_inBalancingPass
? StretchBySpaceShortage : GuessFromFlowThreadPortion); | 396 needsRelayout |= multicolSet->recalculateColumnHeight(m_inBalancingPass
? StretchBySpaceShortage : GuessFromFlowThreadPortion); |
396 if (needsRelayout) { | |
397 // Once a column set gets a new column height, that column set and a
ll successive column | |
398 // sets need to be laid out over again, since their logical top will
be affected by | |
399 // this, and therefore their column heights may change as well, at l
east if the multicol | |
400 // height is constrained. | |
401 multicolSet->setChildNeedsLayout(MarkOnlyThis); | |
402 } | |
403 } | |
404 | 397 |
405 if (needsRelayout) | 398 if (needsRelayout) |
406 setChildNeedsLayout(MarkOnlyThis); | 399 setChildNeedsLayout(MarkOnlyThis); |
407 | 400 |
408 m_inBalancingPass = needsRelayout; | 401 m_inBalancingPass = needsRelayout; |
409 return needsRelayout; | 402 return needsRelayout; |
410 } | 403 } |
411 | 404 |
412 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange() | 405 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange() |
413 { | 406 { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 insertBeforeColumnBox = firstMultiColumnBox(); | 531 insertBeforeColumnBox = firstMultiColumnBox(); |
539 } else if (LayoutMultiColumnSpannerPlaceholder* previousPlaceholder
= containingColumnSpannerPlaceholder(previousLayoutObject)) { | 532 } else if (LayoutMultiColumnSpannerPlaceholder* previousPlaceholder
= containingColumnSpannerPlaceholder(previousLayoutObject)) { |
540 // Before us is another spanner. We belong right after it then. | 533 // Before us is another spanner. We belong right after it then. |
541 insertBeforeColumnBox = previousPlaceholder->nextSiblingMultiCol
umnBox(); | 534 insertBeforeColumnBox = previousPlaceholder->nextSiblingMultiCol
umnBox(); |
542 } else { | 535 } else { |
543 // We're inside regular column content with both feet. Find out
which column | 536 // We're inside regular column content with both feet. Find out
which column |
544 // set this is. It needs to be split it into two sets, so that w
e can insert | 537 // set this is. It needs to be split it into two sets, so that w
e can insert |
545 // a new spanner placeholder between them. | 538 // a new spanner placeholder between them. |
546 setToSplit = mapDescendantToColumnSet(previousLayoutObject); | 539 setToSplit = mapDescendantToColumnSet(previousLayoutObject); |
547 ASSERT(setToSplit == mapDescendantToColumnSet(insertedBeforeInFl
owThread)); | 540 ASSERT(setToSplit == mapDescendantToColumnSet(insertedBeforeInFl
owThread)); |
548 setToSplit->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalid
ationReason::ColumnsChanged); | |
549 insertBeforeColumnBox = setToSplit->nextSiblingMultiColumnBox(); | 541 insertBeforeColumnBox = setToSplit->nextSiblingMultiColumnBox(); |
550 // We've found out which set that needs to be split. Now proceed
to | 542 // We've found out which set that needs to be split. Now proceed
to |
551 // inserting the spanner placeholder, and then insert a second c
olumn set. | 543 // inserting the spanner placeholder, and then insert a second c
olumn set. |
552 } | 544 } |
553 } | 545 } |
554 ASSERT(setToSplit || insertBeforeColumnBox); | 546 ASSERT(setToSplit || insertBeforeColumnBox); |
555 } | 547 } |
556 | 548 |
557 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); | 549 LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); |
558 LayoutMultiColumnSpannerPlaceholder* newPlaceholder = LayoutMultiColumnSpann
erPlaceholder::createAnonymous(multicolContainer->styleRef(), *spannerObjectInFl
owThread); | 550 LayoutMultiColumnSpannerPlaceholder* newPlaceholder = LayoutMultiColumnSpann
erPlaceholder::createAnonymous(multicolContainer->styleRef(), *spannerObjectInFl
owThread); |
559 ASSERT(!insertBeforeColumnBox || insertBeforeColumnBox->parent() == multicol
Container); | 551 ASSERT(!insertBeforeColumnBox || insertBeforeColumnBox->parent() == multicol
Container); |
560 multicolContainer->LayoutBlock::addChild(newPlaceholder, insertBeforeColumnB
ox); | 552 multicolContainer->LayoutBlock::addChild(newPlaceholder, insertBeforeColumnB
ox); |
561 spannerObjectInFlowThread->setSpannerPlaceholder(*newPlaceholder); | 553 spannerObjectInFlowThread->setSpannerPlaceholder(*newPlaceholder); |
562 | 554 |
563 if (setToSplit) | 555 if (setToSplit) |
564 createAndInsertMultiColumnSet(insertBeforeColumnBox); | 556 createAndInsertMultiColumnSet(insertBeforeColumnBox); |
565 } | 557 } |
566 | 558 |
567 void LayoutMultiColumnFlowThread::destroySpannerPlaceholder(LayoutMultiColumnSpa
nnerPlaceholder* placeholder) | 559 void LayoutMultiColumnFlowThread::destroySpannerPlaceholder(LayoutMultiColumnSpa
nnerPlaceholder* placeholder) |
568 { | 560 { |
569 if (LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox()) { | 561 if (LayoutBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox()) { |
570 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColumnBo
x(); | 562 LayoutBox* previousColumnBox = placeholder->previousSiblingMultiColumnBo
x(); |
571 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet() | 563 if (nextColumnBox && nextColumnBox->isLayoutMultiColumnSet() |
572 && previousColumnBox && previousColumnBox->isLayoutMultiColumnSet())
{ | 564 && previousColumnBox && previousColumnBox->isLayoutMultiColumnSet())
{ |
573 // Need to merge two column sets. | 565 // Need to merge two column sets. |
574 nextColumnBox->destroy(); | 566 nextColumnBox->destroy(); |
575 previousColumnBox->setNeedsLayout(LayoutInvalidationReason::ColumnsC
hanged); | |
576 invalidateColumnSets(); | 567 invalidateColumnSets(); |
577 } | 568 } |
578 } | 569 } |
579 placeholder->destroy(); | 570 placeholder->destroy(); |
580 } | 571 } |
581 | 572 |
582 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
escendant) const | 573 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
escendant) const |
583 { | 574 { |
584 // This method needs to behave correctly in the following situations: | 575 // This method needs to behave correctly in the following situations: |
585 // - When the descendant doesn't have a spanner placeholder but should have
one (return true) | 576 // - When the descendant doesn't have a spanner placeholder but should have
one (return true) |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); | 947 appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); |
957 } | 948 } |
958 | 949 |
959 void LayoutMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, Lay
outUnit minHeight) | 950 void LayoutMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, Lay
outUnit minHeight) |
960 { | 951 { |
961 if (LayoutMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) | 952 if (LayoutMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) |
962 multicolSet->updateMinimumColumnHeight(offset, minHeight); | 953 multicolSet->updateMinimumColumnHeight(offset, minHeight); |
963 } | 954 } |
964 | 955 |
965 } | 956 } |
OLD | NEW |