| 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 |