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 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 return nullptr; | 445 return nullptr; |
446 } | 446 } |
447 | 447 |
448 FragmentationContext* LayoutMultiColumnFlowThread::enclosingFragmentationContext
() const | 448 FragmentationContext* LayoutMultiColumnFlowThread::enclosingFragmentationContext
() const |
449 { | 449 { |
450 if (LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowTh
read()) | 450 if (LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowTh
read()) |
451 return enclosingFlowThread; | 451 return enclosingFlowThread; |
452 return view()->fragmentationContext(); | 452 return view()->fragmentationContext(); |
453 } | 453 } |
454 | 454 |
455 void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit
offsetInFlowThread) | 455 void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit
bottomOffsetInFlowThread) |
456 { | 456 { |
457 if (!isPageLogicalHeightKnown()) { | 457 if (!isPageLogicalHeightKnown()) { |
458 // If we have no clue about the height of the multicol container, bail.
This situation | 458 // If we have no clue about the height of the multicol container, bail.
This situation |
459 // occurs initially when an auto-height multicol container is nested ins
ide another | 459 // occurs initially when an auto-height multicol container is nested ins
ide another |
460 // auto-height multicol container. We need at least an estimated height
of the outer | 460 // auto-height multicol container. We need at least an estimated height
of the outer |
461 // multicol container before we can check what an inner fragmentainer gr
oup has room for. | 461 // multicol container before we can check what an inner fragmentainer gr
oup has room for. |
462 // Its height is indefinite for now. | 462 // Its height is indefinite for now. |
463 return; | 463 return; |
464 } | 464 } |
465 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread)
; | 465 // TODO(mstensho): bottomOffsetInFlowThread is an endpoint-exclusive offset,
i.e. the offset |
| 466 // just after the bottom of some object. So, ideally, columnSetAtBlockOffset
() should be |
| 467 // informed about this (i.e. take a PageBoundaryRule argument). This is not
the only place with |
| 468 // this issue; see also pageRemainingLogicalHeightForOffset(). |
| 469 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(bottomOffsetInFlowT
hread); |
466 if (columnSet->isInitialHeightCalculated()) { | 470 if (columnSet->isInitialHeightCalculated()) { |
467 // We only insert additional fragmentainer groups in the initial layout
pass. We only want | 471 // We only insert additional fragmentainer groups in the initial layout
pass. We only want |
468 // to balance columns in the last fragmentainer group (if we need to bal
ance at all), so we | 472 // to balance columns in the last fragmentainer group (if we need to bal
ance at all), so we |
469 // want that last fragmentainer group to be the same one in all layout p
asses that follow. | 473 // want that last fragmentainer group to be the same one in all layout p
asses that follow. |
470 return; | 474 return; |
471 } | 475 } |
472 | 476 |
473 if (!columnSet->hasFragmentainerGroupForColumnAt(offsetInFlowThread)) { | 477 if (!columnSet->hasFragmentainerGroupForColumnAt(bottomOffsetInFlowThread))
{ |
474 FragmentationContext* enclosingFragmentationContext = this->enclosingFra
gmentationContext(); | 478 FragmentationContext* enclosingFragmentationContext = this->enclosingFra
gmentationContext(); |
475 if (!enclosingFragmentationContext) | 479 if (!enclosingFragmentationContext) |
476 return; // Not nested. We'll never need more rows than the one we al
ready have then. | 480 return; // Not nested. We'll never need more rows than the one we al
ready have then. |
477 ASSERT(!isLayoutPagedFlowThread()); | 481 ASSERT(!isLayoutPagedFlowThread()); |
478 // We have run out of columns here, so we add another row to hold more c
olumns. When we add | 482 // We have run out of columns here, so we add another row to hold more c
olumns. When we add |
479 // a new row, it implicitly means that we're inserting another column in
our enclosing | 483 // a new row, it implicitly means that we're inserting another column in
our enclosing |
480 // multicol container. That in turn may mean that we've run out of colum
ns there too. | 484 // multicol container. That in turn may mean that we've run out of colum
ns there too. |
481 const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragme
ntainerGroup(); | 485 const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragme
ntainerGroup(); |
482 if (LayoutMultiColumnFlowThread* enclosingFlowThread = enclosingFragment
ationContext->associatedFlowThread()) | 486 if (LayoutMultiColumnFlowThread* enclosingFlowThread = enclosingFragment
ationContext->associatedFlowThread()) |
483 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.bloc
kOffsetInEnclosingFragmentationContext()); | 487 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.bloc
kOffsetInEnclosingFragmentationContext() + newRow.logicalHeight()); |
484 } | 488 } |
485 } | 489 } |
486 | 490 |
487 bool LayoutMultiColumnFlowThread::isFragmentainerLogicalHeightKnown() | 491 bool LayoutMultiColumnFlowThread::isFragmentainerLogicalHeightKnown() |
488 { | 492 { |
489 return isPageLogicalHeightKnown(); | 493 return isPageLogicalHeightKnown(); |
490 } | 494 } |
491 | 495 |
492 LayoutUnit LayoutMultiColumnFlowThread::fragmentainerLogicalHeightAt(LayoutUnit
blockOffset) | 496 LayoutUnit LayoutMultiColumnFlowThread::fragmentainerLogicalHeightAt(LayoutUnit
blockOffset) |
493 { | 497 { |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 // remaining in the currently last row. | 933 // remaining in the currently last row. |
930 LayoutRect layoutRect = layoutOverflowRect(); | 934 LayoutRect layoutRect = layoutOverflowRect(); |
931 LayoutUnit logicalBottomInFlowThread = isHorizontalWritingMode() ? l
ayoutRect.maxY() : layoutRect.maxX(); | 935 LayoutUnit logicalBottomInFlowThread = isHorizontalWritingMode() ? l
ayoutRect.maxY() : layoutRect.maxX(); |
932 ASSERT(logicalBottomInFlowThread >= logicalHeight()); | 936 ASSERT(logicalBottomInFlowThread >= logicalHeight()); |
933 lastSet->endFlow(logicalBottomInFlowThread); | 937 lastSet->endFlow(logicalBottomInFlowThread); |
934 } | 938 } |
935 } | 939 } |
936 m_lastSetWorkedOn = nullptr; | 940 m_lastSetWorkedOn = nullptr; |
937 } | 941 } |
938 | 942 |
939 void LayoutMultiColumnFlowThread::contentWasLaidOut(LayoutUnit logicalTopInFlowT
hreadAfterPagination) | 943 void LayoutMultiColumnFlowThread::contentWasLaidOut(LayoutUnit logicalBottomInFl
owThreadAfterPagination) |
940 { | 944 { |
941 // Check if we need another fragmentainer group. If we've run out of columns
in the last | 945 // Check if we need another fragmentainer group. If we've run out of columns
in the last |
942 // fragmentainer group (column row), we need to insert another fragmentainer
group to hold more | 946 // fragmentainer group (column row), we need to insert another fragmentainer
group to hold more |
943 // columns. | 947 // columns. |
944 | 948 |
945 // First figure out if there's any chance that we're nested at all. If we ca
n be sure that | 949 // First figure out if there's any chance that we're nested at all. If we ca
n be sure that |
946 // we're not, bail early. This code is run very often, and since locating a
containing flow | 950 // we're not, bail early. This code is run very often, and since locating a
containing flow |
947 // thread has some cost (depending on tree depth), avoid calling | 951 // thread has some cost (depending on tree depth), avoid calling |
948 // enclosingFragmentationContext() right away. This test may give some false
positives (hence | 952 // enclosingFragmentationContext() right away. This test may give some false
positives (hence |
949 // the "mayBe"), if we're in an out-of-flow subtree and have an outer multic
ol container that | 953 // the "mayBe"), if we're in an out-of-flow subtree and have an outer multic
ol container that |
950 // doesn't affect us, but that's okay. We'll discover that further down the
road when trying to | 954 // doesn't affect us, but that's okay. We'll discover that further down the
road when trying to |
951 // locate our enclosing flow thread for real. | 955 // locate our enclosing flow thread for real. |
952 bool mayBeNested = multiColumnBlockFlow()->isInsideFlowThread() || view()->f
ragmentationContext(); | 956 bool mayBeNested = multiColumnBlockFlow()->isInsideFlowThread() || view()->f
ragmentationContext(); |
953 if (!mayBeNested) | 957 if (!mayBeNested) |
954 return; | 958 return; |
955 appendNewFragmentainerGroupIfNeeded(logicalTopInFlowThreadAfterPagination); | 959 appendNewFragmentainerGroupIfNeeded(logicalBottomInFlowThreadAfterPagination
); |
956 } | 960 } |
957 | 961 |
958 } | 962 } |
OLD | NEW |