| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/MultiColumnFragmentainerGroup.h" | 5 #include "core/layout/MultiColumnFragmentainerGroup.h" |
| 6 | 6 |
| 7 #include "core/layout/ColumnBalancer.h" | 7 #include "core/layout/ColumnBalancer.h" |
| 8 #include "core/layout/FragmentationContext.h" | 8 #include "core/layout/FragmentationContext.h" |
| 9 #include "core/layout/LayoutMultiColumnSet.h" | 9 #include "core/layout/LayoutMultiColumnSet.h" |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 } | 30 } |
| 31 | 31 |
| 32 LayoutUnit | 32 LayoutUnit |
| 33 MultiColumnFragmentainerGroup::blockOffsetInEnclosingFragmentationContext() | 33 MultiColumnFragmentainerGroup::blockOffsetInEnclosingFragmentationContext() |
| 34 const { | 34 const { |
| 35 return logicalTop() + m_columnSet.logicalTopFromMulticolContentEdge() + | 35 return logicalTop() + m_columnSet.logicalTopFromMulticolContentEdge() + |
| 36 m_columnSet.multiColumnFlowThread() | 36 m_columnSet.multiColumnFlowThread() |
| 37 ->blockOffsetInEnclosingFragmentationContext(); | 37 ->blockOffsetInEnclosingFragmentationContext(); |
| 38 } | 38 } |
| 39 | 39 |
| 40 LayoutUnit MultiColumnFragmentainerGroup::logicalHeightInFlowThreadAt( |
| 41 unsigned columnIndex) const { |
| 42 if (!m_columnHeight) |
| 43 return LayoutUnit(); |
| 44 LayoutUnit logicalTop = logicalTopInFlowThreadAt(columnIndex); |
| 45 LayoutUnit logicalBottom = logicalTop + m_columnHeight; |
| 46 if (logicalBottom > logicalBottomInFlowThread()) { |
| 47 DCHECK_EQ(columnIndex + 1, actualColumnCount()); |
| 48 logicalBottom = logicalBottomInFlowThread(); |
| 49 } |
| 50 return (logicalBottom - logicalTop).clampNegativeToZero(); |
| 51 } |
| 52 |
| 40 void MultiColumnFragmentainerGroup::resetColumnHeight() { | 53 void MultiColumnFragmentainerGroup::resetColumnHeight() { |
| 41 m_maxColumnHeight = calculateMaxColumnHeight(); | 54 m_maxColumnHeight = calculateMaxColumnHeight(); |
| 42 | 55 |
| 43 LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(); | 56 LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(); |
| 44 if (m_columnSet.heightIsAuto()) { | 57 if (m_columnSet.heightIsAuto()) { |
| 45 FragmentationContext* enclosingFragmentationContext = | 58 FragmentationContext* enclosingFragmentationContext = |
| 46 flowThread->enclosingFragmentationContext(); | 59 flowThread->enclosingFragmentationContext(); |
| 47 if (enclosingFragmentationContext && | 60 if (enclosingFragmentationContext && |
| 48 enclosingFragmentationContext->isFragmentainerLogicalHeightKnown()) { | 61 enclosingFragmentationContext->isFragmentainerLogicalHeightKnown()) { |
| 49 // Set an initial height, based on the fragmentainer height in the outer | 62 // Set an initial height, based on the fragmentainer height in the outer |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 LayoutUnit::max()); // If this happens, we probably have a bug. | 375 LayoutUnit::max()); // If this happens, we probably have a bug. |
| 363 if (minSpaceShortage == LayoutUnit::max()) | 376 if (minSpaceShortage == LayoutUnit::max()) |
| 364 return m_columnHeight; // So bail out rather than looping infinitely. | 377 return m_columnHeight; // So bail out rather than looping infinitely. |
| 365 | 378 |
| 366 return m_columnHeight + minSpaceShortage; | 379 return m_columnHeight + minSpaceShortage; |
| 367 } | 380 } |
| 368 | 381 |
| 369 LayoutRect MultiColumnFragmentainerGroup::columnRectAt( | 382 LayoutRect MultiColumnFragmentainerGroup::columnRectAt( |
| 370 unsigned columnIndex) const { | 383 unsigned columnIndex) const { |
| 371 LayoutUnit columnLogicalWidth = m_columnSet.pageLogicalWidth(); | 384 LayoutUnit columnLogicalWidth = m_columnSet.pageLogicalWidth(); |
| 372 LayoutUnit columnLogicalHeight = m_columnHeight; | 385 LayoutUnit columnLogicalHeight = logicalHeightInFlowThreadAt(columnIndex); |
| 373 LayoutUnit columnLogicalTop; | 386 LayoutUnit columnLogicalTop; |
| 374 LayoutUnit columnLogicalLeft; | 387 LayoutUnit columnLogicalLeft; |
| 375 LayoutUnit columnGap = m_columnSet.columnGap(); | 388 LayoutUnit columnGap = m_columnSet.columnGap(); |
| 376 LayoutUnit portionOutsideFlowThread = | |
| 377 logicalTopInFlowThread() + (columnIndex + 1) * columnLogicalHeight - | |
| 378 logicalBottomInFlowThread(); | |
| 379 if (portionOutsideFlowThread > 0) { | |
| 380 // The last column may not be using all available space. | |
| 381 ASSERT(columnIndex + 1 == actualColumnCount()); | |
| 382 columnLogicalHeight -= portionOutsideFlowThread; | |
| 383 ASSERT(columnLogicalHeight >= 0); | |
| 384 } | |
| 385 | 389 |
| 386 if (m_columnSet.multiColumnFlowThread()->progressionIsInline()) { | 390 if (m_columnSet.multiColumnFlowThread()->progressionIsInline()) { |
| 387 if (m_columnSet.style()->isLeftToRightDirection()) | 391 if (m_columnSet.style()->isLeftToRightDirection()) |
| 388 columnLogicalLeft += columnIndex * (columnLogicalWidth + columnGap); | 392 columnLogicalLeft += columnIndex * (columnLogicalWidth + columnGap); |
| 389 else | 393 else |
| 390 columnLogicalLeft += m_columnSet.contentLogicalWidth() - | 394 columnLogicalLeft += m_columnSet.contentLogicalWidth() - |
| 391 columnLogicalWidth - | 395 columnLogicalWidth - |
| 392 columnIndex * (columnLogicalWidth + columnGap); | 396 columnIndex * (columnLogicalWidth + columnGap); |
| 393 } else { | 397 } else { |
| 394 columnLogicalTop += columnIndex * (m_columnHeight + columnGap); | 398 columnLogicalTop += columnIndex * (m_columnHeight + columnGap); |
| 395 } | 399 } |
| 396 | 400 |
| 397 LayoutRect columnRect(columnLogicalLeft, columnLogicalTop, columnLogicalWidth, | 401 LayoutRect columnRect(columnLogicalLeft, columnLogicalTop, columnLogicalWidth, |
| 398 columnLogicalHeight); | 402 columnLogicalHeight); |
| 399 if (!m_columnSet.isHorizontalWritingMode()) | 403 if (!m_columnSet.isHorizontalWritingMode()) |
| 400 return columnRect.transposedRect(); | 404 return columnRect.transposedRect(); |
| 401 return columnRect; | 405 return columnRect; |
| 402 } | 406 } |
| 403 | 407 |
| 404 LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionRectAt( | 408 LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionRectAt( |
| 405 unsigned columnIndex) const { | 409 unsigned columnIndex) const { |
| 406 LayoutUnit logicalTop = logicalTopInFlowThreadAt(columnIndex); | 410 LayoutUnit logicalTop = logicalTopInFlowThreadAt(columnIndex); |
| 407 LayoutUnit logicalBottom = logicalTop + m_columnHeight; | 411 LayoutUnit portionLogicalHeight = logicalHeightInFlowThreadAt(columnIndex); |
| 408 if (logicalBottom > logicalBottomInFlowThread()) { | |
| 409 // The last column may not be using all available space. | |
| 410 ASSERT(columnIndex + 1 == actualColumnCount()); | |
| 411 logicalBottom = logicalBottomInFlowThread(); | |
| 412 ASSERT(logicalBottom >= logicalTop); | |
| 413 } | |
| 414 LayoutUnit portionLogicalHeight = logicalBottom - logicalTop; | |
| 415 if (m_columnSet.isHorizontalWritingMode()) | 412 if (m_columnSet.isHorizontalWritingMode()) |
| 416 return LayoutRect(LayoutUnit(), logicalTop, m_columnSet.pageLogicalWidth(), | 413 return LayoutRect(LayoutUnit(), logicalTop, m_columnSet.pageLogicalWidth(), |
| 417 portionLogicalHeight); | 414 portionLogicalHeight); |
| 418 return LayoutRect(logicalTop, LayoutUnit(), portionLogicalHeight, | 415 return LayoutRect(logicalTop, LayoutUnit(), portionLogicalHeight, |
| 419 m_columnSet.pageLogicalWidth()); | 416 m_columnSet.pageLogicalWidth()); |
| 420 } | 417 } |
| 421 | 418 |
| 422 LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionOverflowRectAt( | 419 LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionOverflowRectAt( |
| 423 unsigned columnIndex) const { | 420 unsigned columnIndex) const { |
| 424 // This function determines the portion of the flow thread that paints for the | 421 // This function determines the portion of the flow thread that paints for the |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 | 519 |
| 523 void MultiColumnFragmentainerGroup::columnIntervalForBlockRangeInFlowThread( | 520 void MultiColumnFragmentainerGroup::columnIntervalForBlockRangeInFlowThread( |
| 524 LayoutUnit logicalTopInFlowThread, | 521 LayoutUnit logicalTopInFlowThread, |
| 525 LayoutUnit logicalBottomInFlowThread, | 522 LayoutUnit logicalBottomInFlowThread, |
| 526 unsigned& firstColumn, | 523 unsigned& firstColumn, |
| 527 unsigned& lastColumn) const { | 524 unsigned& lastColumn) const { |
| 528 logicalTopInFlowThread = | 525 logicalTopInFlowThread = |
| 529 std::max(logicalTopInFlowThread, this->logicalTopInFlowThread()); | 526 std::max(logicalTopInFlowThread, this->logicalTopInFlowThread()); |
| 530 logicalBottomInFlowThread = | 527 logicalBottomInFlowThread = |
| 531 std::min(logicalBottomInFlowThread, this->logicalBottomInFlowThread()); | 528 std::min(logicalBottomInFlowThread, this->logicalBottomInFlowThread()); |
| 532 ASSERT(logicalTopInFlowThread <= logicalBottomInFlowThread); | |
| 533 firstColumn = columnIndexAtOffset(logicalTopInFlowThread, | 529 firstColumn = columnIndexAtOffset(logicalTopInFlowThread, |
| 534 LayoutBox::AssociateWithLatterPage); | 530 LayoutBox::AssociateWithLatterPage); |
| 535 if (logicalBottomInFlowThread == logicalTopInFlowThread) { | 531 if (logicalBottomInFlowThread <= logicalTopInFlowThread) { |
| 536 // Zero-height block range. There'll be one column in the interval. Set it | 532 // Zero-height block range. There'll be one column in the interval. Set it |
| 537 // right away. This is important if we're at a column boundary, since | 533 // right away. This is important if we're at a column boundary, since |
| 538 // calling columnIndexAtOffset() with the end-exclusive bottom offset would | 534 // calling columnIndexAtOffset() with the end-exclusive bottom offset would |
| 539 // actually give us the *previous* column. | 535 // actually give us the *previous* column. |
| 540 lastColumn = firstColumn; | 536 lastColumn = firstColumn; |
| 541 } else { | 537 } else { |
| 542 lastColumn = columnIndexAtOffset(logicalBottomInFlowThread, | 538 lastColumn = columnIndexAtOffset(logicalBottomInFlowThread, |
| 543 LayoutBox::AssociateWithFormerPage); | 539 LayoutBox::AssociateWithFormerPage); |
| 544 } | 540 } |
| 545 } | 541 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 MultiColumnFragmentainerGroupList::addExtraGroup() { | 588 MultiColumnFragmentainerGroupList::addExtraGroup() { |
| 593 append(MultiColumnFragmentainerGroup(m_columnSet)); | 589 append(MultiColumnFragmentainerGroup(m_columnSet)); |
| 594 return last(); | 590 return last(); |
| 595 } | 591 } |
| 596 | 592 |
| 597 void MultiColumnFragmentainerGroupList::deleteExtraGroups() { | 593 void MultiColumnFragmentainerGroupList::deleteExtraGroups() { |
| 598 shrink(1); | 594 shrink(1); |
| 599 } | 595 } |
| 600 | 596 |
| 601 } // namespace blink | 597 } // namespace blink |
| OLD | NEW |