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 10 matching lines...) Expand all Loading... |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "config.h" | 26 #include "config.h" |
27 #include "core/layout/LayoutMultiColumnFlowThread.h" | 27 #include "core/layout/LayoutMultiColumnFlowThread.h" |
28 | 28 |
29 #include "core/layout/LayoutMultiColumnSet.h" | 29 #include "core/layout/LayoutMultiColumnSet.h" |
30 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h" | 30 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h" |
| 31 #include "core/layout/LayoutView.h" |
31 #include "core/layout/MultiColumnFragmentainerGroup.h" | 32 #include "core/layout/MultiColumnFragmentainerGroup.h" |
| 33 #include "core/layout/ViewFragmentationContext.h" |
32 | 34 |
33 namespace blink { | 35 namespace blink { |
34 | 36 |
35 LayoutMultiColumnFlowThread::LayoutMultiColumnFlowThread() | 37 LayoutMultiColumnFlowThread::LayoutMultiColumnFlowThread() |
36 : m_lastSetWorkedOn(nullptr) | 38 : m_lastSetWorkedOn(nullptr) |
37 , m_columnCount(1) | 39 , m_columnCount(1) |
38 , m_columnHeightAvailable(0) | 40 , m_columnHeightAvailable(0) |
39 , m_inBalancingPass(false) | 41 , m_inBalancingPass(false) |
40 , m_needsColumnHeightsRecalculation(false) | 42 , m_needsColumnHeightsRecalculation(false) |
41 , m_progressionIsInline(true) | 43 , m_progressionIsInline(true) |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 350 |
349 void LayoutMultiColumnFlowThread::layoutColumns(SubtreeLayoutScope& layoutScope) | 351 void LayoutMultiColumnFlowThread::layoutColumns(SubtreeLayoutScope& layoutScope) |
350 { | 352 { |
351 // Since we ended up here, it means that the multicol container (our parent)
needed | 353 // Since we ended up here, it means that the multicol container (our parent)
needed |
352 // layout. Since contents of the multicol container are diverted to the flow
thread, the flow | 354 // layout. Since contents of the multicol container are diverted to the flow
thread, the flow |
353 // thread needs layout as well. | 355 // thread needs layout as well. |
354 layoutScope.setChildNeedsLayout(this); | 356 layoutScope.setChildNeedsLayout(this); |
355 | 357 |
356 m_needsColumnHeightsRecalculation = false; | 358 m_needsColumnHeightsRecalculation = false; |
357 | 359 |
358 m_blockOffsetInEnclosingFlowThread = enclosingFlowThread() ? multiColumnBloc
kFlow()->offsetFromLogicalTopOfFirstPage() : LayoutUnit(); | 360 m_blockOffsetInEnclosingFragmentationContext = enclosingFragmentationContext
() ? multiColumnBlockFlow()->offsetFromLogicalTopOfFirstPage() : LayoutUnit(); |
359 | 361 |
360 for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co
lumnBox->nextSiblingMultiColumnBox()) { | 362 for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co
lumnBox->nextSiblingMultiColumnBox()) { |
361 if (!columnBox->isLayoutMultiColumnSet()) { | 363 if (!columnBox->isLayoutMultiColumnSet()) { |
362 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot
her type is expected. | 364 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot
her type is expected. |
363 m_needsColumnHeightsRecalculation = true; | 365 m_needsColumnHeightsRecalculation = true; |
364 continue; | 366 continue; |
365 } | 367 } |
366 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); | 368 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); |
367 layoutScope.setChildNeedsLayout(columnSet); | 369 layoutScope.setChildNeedsLayout(columnSet); |
368 if (!m_inBalancingPass) { | 370 if (!m_inBalancingPass) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 return true; | 434 return true; |
433 } | 435 } |
434 | 436 |
435 LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::enclosingFlowThread()
const | 437 LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::enclosingFlowThread()
const |
436 { | 438 { |
437 if (multiColumnBlockFlow()->isInsideFlowThread()) | 439 if (multiColumnBlockFlow()->isInsideFlowThread()) |
438 return toLayoutMultiColumnFlowThread(locateFlowThreadContainingBlockOf(*
multiColumnBlockFlow())); | 440 return toLayoutMultiColumnFlowThread(locateFlowThreadContainingBlockOf(*
multiColumnBlockFlow())); |
439 return nullptr; | 441 return nullptr; |
440 } | 442 } |
441 | 443 |
| 444 FragmentationContext* LayoutMultiColumnFlowThread::enclosingFragmentationContext
() const |
| 445 { |
| 446 if (LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowTh
read()) |
| 447 return enclosingFlowThread; |
| 448 return view()->fragmentationContext(); |
| 449 } |
| 450 |
442 void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit
offsetInFlowThread) | 451 void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit
offsetInFlowThread) |
443 { | 452 { |
444 if (!isPageLogicalHeightKnown()) { | 453 if (!isPageLogicalHeightKnown()) { |
445 // If we have no clue about the height of the multicol container, bail.
This situation | 454 // If we have no clue about the height of the multicol container, bail.
This situation |
446 // occurs initially when an auto-height multicol container is nested ins
ide another | 455 // occurs initially when an auto-height multicol container is nested ins
ide another |
447 // auto-height multicol container. We need at least an estimated height
of the outer | 456 // auto-height multicol container. We need at least an estimated height
of the outer |
448 // multicol container before we can check what an inner fragmentainer gr
oup has room for. | 457 // multicol container before we can check what an inner fragmentainer gr
oup has room for. |
449 // Its height is indefinite for now. | 458 // Its height is indefinite for now. |
450 return; | 459 return; |
451 } | 460 } |
452 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread)
; | 461 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread)
; |
453 if (columnSet->isInitialHeightCalculated()) { | 462 if (columnSet->isInitialHeightCalculated()) { |
454 // We only insert additional fragmentainer groups in the initial layout
pass. We only want | 463 // 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 | 464 // 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. | 465 // want that last fragmentainer group to be the same one in all layout p
asses that follow. |
457 return; | 466 return; |
458 } | 467 } |
459 | 468 |
460 if (!columnSet->hasFragmentainerGroupForColumnAt(offsetInFlowThread)) { | 469 if (!columnSet->hasFragmentainerGroupForColumnAt(offsetInFlowThread)) { |
461 LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowTh
read(); | 470 FragmentationContext* enclosingFragmentationContext = this->enclosingFra
gmentationContext(); |
462 if (!enclosingFlowThread) | 471 if (!enclosingFragmentationContext) |
463 return; // Not nested. We'll never need more rows than the one we al
ready have then. | 472 return; // Not nested. We'll never need more rows than the one we al
ready have then. |
464 | 473 |
465 // We have run out of columns here, so we add another row to hold more c
olumns. When we add | 474 // We have run out of columns here, so we add another row to hold more c
olumns. When we add |
466 // a new row, it implicitly means that we're inserting another column in
our enclosing | 475 // a new row, it implicitly means that we're inserting another column in
our enclosing |
467 // multicol container. That in turn may mean that we've run out of colum
ns there too. | 476 // multicol container. That in turn may mean that we've run out of colum
ns there too. |
468 const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragme
ntainerGroup(); | 477 const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragme
ntainerGroup(); |
469 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOff
setInEnclosingFlowThread()); | 478 if (LayoutMultiColumnFlowThread* enclosingFlowThread = enclosingFragment
ationContext->associatedFlowThread()) |
| 479 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.bloc
kOffsetInEnclosingFragmentationContext()); |
470 } | 480 } |
471 } | 481 } |
472 | 482 |
| 483 bool LayoutMultiColumnFlowThread::isFragmentainerLogicalHeightKnown() |
| 484 { |
| 485 return isPageLogicalHeightKnown(); |
| 486 } |
| 487 |
| 488 LayoutUnit LayoutMultiColumnFlowThread::fragmentainerLogicalHeightAt(LayoutUnit
blockOffset) |
| 489 { |
| 490 return pageLogicalHeightForOffset(blockOffset); |
| 491 } |
| 492 |
| 493 LayoutUnit LayoutMultiColumnFlowThread::remainingLogicalHeightAt(LayoutUnit bloc
kOffset) |
| 494 { |
| 495 return pageRemainingLogicalHeightForOffset(blockOffset, AssociateWithLatterP
age); |
| 496 } |
| 497 |
473 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width
, unsigned& count) const | 498 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width
, unsigned& count) const |
474 { | 499 { |
475 LayoutBlock* columnBlock = multiColumnBlockFlow(); | 500 LayoutBlock* columnBlock = multiColumnBlockFlow(); |
476 const ComputedStyle* columnStyle = columnBlock->style(); | 501 const ComputedStyle* columnStyle = columnBlock->style(); |
477 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); | 502 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); |
478 LayoutUnit columnGap = columnBlock->columnGap(); | 503 LayoutUnit columnGap = columnBlock->columnGap(); |
479 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle->
columnWidth())); | 504 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle->
columnWidth())); |
480 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); | 505 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); |
481 | 506 |
482 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt
h()); | 507 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt
h()); |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 } | 933 } |
909 | 934 |
910 void LayoutMultiColumnFlowThread::contentWasLaidOut(LayoutUnit logicalTopInFlowT
hreadAfterPagination) | 935 void LayoutMultiColumnFlowThread::contentWasLaidOut(LayoutUnit logicalTopInFlowT
hreadAfterPagination) |
911 { | 936 { |
912 // Check if we need another fragmentainer group. If we've run out of columns
in the last | 937 // Check if we need another fragmentainer group. If we've run out of columns
in the last |
913 // fragmentainer group (column row), we need to insert another fragmentainer
group to hold more | 938 // fragmentainer group (column row), we need to insert another fragmentainer
group to hold more |
914 // columns. | 939 // columns. |
915 | 940 |
916 // First figure out if there's any chance that we're nested at all. If we ca
n be sure that | 941 // First figure out if there's any chance that we're nested at all. If we ca
n be sure that |
917 // we're not, bail early. This code is run very often, and since locating a
containing flow | 942 // we're not, bail early. This code is run very often, and since locating a
containing flow |
918 // thread has some cost (depending on tree depth), avoid calling enclosingFl
owThread() right | 943 // thread has some cost (depending on tree depth), avoid calling |
919 // away. This test may give some false positives (hence the "mayBe"), if we'
re in an | 944 // enclosingFragmentationContext() right away. This test may give some false
positives (hence |
920 // out-of-flow subtree and have an outer multicol container that doesn't aff
ect us, but that's | 945 // the "mayBe"), if we're in an out-of-flow subtree and have an outer multic
ol container that |
921 // okay. We'll discover that further down the road when trying to locate our
enclosing flow | 946 // doesn't affect us, but that's okay. We'll discover that further down the
road when trying to |
922 // thread for real. | 947 // locate our enclosing flow thread for real. |
923 bool mayBeNested = multiColumnBlockFlow()->isInsideFlowThread(); | 948 bool mayBeNested = multiColumnBlockFlow()->isInsideFlowThread() || view()->f
ragmentationContext(); |
924 if (!mayBeNested) | 949 if (!mayBeNested) |
925 return; | 950 return; |
926 appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); | 951 appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); |
927 } | 952 } |
928 | 953 |
929 } | 954 } |
OLD | NEW |