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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 return true; | 432 return true; |
433 } | 433 } |
434 | 434 |
435 LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::enclosingFlowThread()
const | 435 LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::enclosingFlowThread()
const |
436 { | 436 { |
437 if (multiColumnBlockFlow()->isInsideFlowThread()) | 437 if (multiColumnBlockFlow()->isInsideFlowThread()) |
438 return toLayoutMultiColumnFlowThread(locateFlowThreadContainingBlockOf(*
multiColumnBlockFlow())); | 438 return toLayoutMultiColumnFlowThread(locateFlowThreadContainingBlockOf(*
multiColumnBlockFlow())); |
439 return nullptr; | 439 return nullptr; |
440 } | 440 } |
441 | 441 |
442 bool LayoutMultiColumnFlowThread::hasFragmentainerGroupForColumnAt(LayoutUnit of
fsetInFlowThread) const | 442 void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit
offsetInFlowThread) |
443 { | 443 { |
444 // If there's no enclosing flow thread, there'll always be only one fragment
ainer group, and it | |
445 // can hold as many columns as we like. We shouldn't even be here in that ca
se. | |
446 ASSERT(enclosingFlowThread()); | |
447 | |
448 if (!isPageLogicalHeightKnown()) { | 444 if (!isPageLogicalHeightKnown()) { |
449 // If we have no clue about the height of the multicol container, bail.
This situation | 445 // If we have no clue about the height of the multicol container, bail.
This situation |
450 // occurs initially when an auto-height multicol container is nested ins
ide another | 446 // occurs initially when an auto-height multicol container is nested ins
ide another |
451 // auto-height multicol container. We need at least an estimated height
of the outer | 447 // auto-height multicol container. We need at least an estimated height
of the outer |
452 // multicol container before we can check what an inner fragmentainer gr
oup has room for. | 448 // multicol container before we can check what an inner fragmentainer gr
oup has room for. |
453 // Its height height is indefinite for now. | 449 // Its height is indefinite for now. |
454 return true; | 450 return; |
| 451 } |
| 452 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread)
; |
| 453 if (columnSet->isInitialHeightCalculated()) { |
| 454 // We only insert additional fragmentainer groups in the initial layout
pass. We only want |
| 455 // to balance columns in the last fragmentainer group (if we need to bal
ance at all), so we |
| 456 // want that last fragmentainer group to be the same one in all layout p
asses that follow. |
| 457 return; |
455 } | 458 } |
456 | 459 |
457 LayoutMultiColumnSet* lastColumnSet = lastMultiColumnSet(); | 460 if (!columnSet->hasFragmentainerGroupForColumnAt(offsetInFlowThread)) { |
458 if (!lastColumnSet) { | 461 LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowTh
read(); |
459 ASSERT_NOT_REACHED(); | 462 if (!enclosingFlowThread) |
460 return true; | 463 return; // Not nested. We'll never need more rows than the one we al
ready have then. |
461 } | |
462 if (lastColumnSet->logicalTopInFlowThread() > offsetInFlowThread) | |
463 return true; | |
464 const MultiColumnFragmentainerGroup& lastRow = lastColumnSet->lastFragmentai
nerGroup(); | |
465 if (lastRow.logicalTopInFlowThread() > offsetInFlowThread) | |
466 return true; | |
467 return offsetInFlowThread - lastRow.logicalTopInFlowThread() < lastRow.logic
alHeight() * lastColumnSet->usedColumnCount(); | |
468 } | |
469 | 464 |
470 void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit
offsetInFlowThread) | |
471 { | |
472 LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowThread
(); | |
473 if (!enclosingFlowThread) | |
474 return; // Not nested. We'll never need more rows than the one we alread
y have then. | |
475 if (!hasFragmentainerGroupForColumnAt(offsetInFlowThread)) { | |
476 // We have run out of columns here, so we add another row to hold more c
olumns. When we add | 465 // We have run out of columns here, so we add another row to hold more c
olumns. When we add |
477 // a new row, it implicitly means that we're inserting another column in
our enclosing | 466 // a new row, it implicitly means that we're inserting another column in
our enclosing |
478 // multicol container. That in turn may mean that we've run out of colum
ns there too. | 467 // multicol container. That in turn may mean that we've run out of colum
ns there too. |
479 const MultiColumnFragmentainerGroup& newRow = lastMultiColumnSet()->appe
ndNewFragmentainerGroup(); | 468 const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragme
ntainerGroup(); |
480 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOff
setInEnclosingFlowThread()); | 469 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOff
setInEnclosingFlowThread()); |
481 } | 470 } |
482 } | 471 } |
483 | 472 |
484 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width
, unsigned& count) const | 473 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width
, unsigned& count) const |
485 { | 474 { |
486 LayoutBlock* columnBlock = multiColumnBlockFlow(); | 475 LayoutBlock* columnBlock = multiColumnBlockFlow(); |
487 const ComputedStyle* columnStyle = columnBlock->style(); | 476 const ComputedStyle* columnStyle = columnBlock->style(); |
488 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); | 477 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); |
489 LayoutUnit columnGap = columnBlock->columnGap(); | 478 LayoutUnit columnGap = columnBlock->columnGap(); |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 // First figure out if there's any chance that we're nested at all. If we ca
n be sure that | 916 // First figure out if there's any chance that we're nested at all. If we ca
n be sure that |
928 // we're not, bail early. This code is run very often, and since locating a
containing flow | 917 // we're not, bail early. This code is run very often, and since locating a
containing flow |
929 // thread has some cost (depending on tree depth), avoid calling enclosingFl
owThread() right | 918 // thread has some cost (depending on tree depth), avoid calling enclosingFl
owThread() right |
930 // away. This test may give some false positives (hence the "mayBe"), if we'
re in an | 919 // away. This test may give some false positives (hence the "mayBe"), if we'
re in an |
931 // out-of-flow subtree and have an outer multicol container that doesn't aff
ect us, but that's | 920 // out-of-flow subtree and have an outer multicol container that doesn't aff
ect us, but that's |
932 // okay. We'll discover that further down the road when trying to locate our
enclosing flow | 921 // okay. We'll discover that further down the road when trying to locate our
enclosing flow |
933 // thread for real. | 922 // thread for real. |
934 bool mayBeNested = multiColumnBlockFlow()->isInsideFlowThread(); | 923 bool mayBeNested = multiColumnBlockFlow()->isInsideFlowThread(); |
935 if (!mayBeNested) | 924 if (!mayBeNested) |
936 return; | 925 return; |
937 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(logicalTopInFlowThr
eadAfterPagination); | |
938 if (!columnSet) | |
939 return; | |
940 if (columnSet->isInitialHeightCalculated()) { | |
941 // We only insert additional fragmentainer groups in the initial layout
pass. We only want | |
942 // to balance columns in the last fragmentainer group (if we need to bal
ance at all), so we | |
943 // want that last fragmentainer group to be the same one in all layout p
asses that follow. | |
944 return; | |
945 } | |
946 MultiColumnFragmentainerGroup& row = columnSet->fragmentainerGroupAtFlowThre
adOffset(logicalTopInFlowThreadAfterPagination); | |
947 if (!row.isLastGroup()) | |
948 return; | |
949 appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); | 926 appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); |
950 } | 927 } |
951 | 928 |
952 } | 929 } |
OLD | NEW |