Index: Source/core/layout/LayoutMultiColumnFlowThread.cpp |
diff --git a/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/Source/core/layout/LayoutMultiColumnFlowThread.cpp |
index 4e2041b5546e9daf9cd5d8394e4e43e356191e9a..478f89d9d701fd067c66d0e799cfbdb7284497dc 100644 |
--- a/Source/core/layout/LayoutMultiColumnFlowThread.cpp |
+++ b/Source/core/layout/LayoutMultiColumnFlowThread.cpp |
@@ -28,6 +28,7 @@ |
#include "core/layout/LayoutMultiColumnSet.h" |
#include "core/layout/LayoutMultiColumnSpannerPlaceholder.h" |
+#include "core/layout/MultiColumnFragmentainerGroup.h" |
namespace blink { |
@@ -270,10 +271,7 @@ LayoutSize LayoutMultiColumnFlowThread::columnOffset(const LayoutPoint& point) c |
LayoutPoint flowThreadPoint = flipForWritingMode(point); |
LayoutUnit blockOffset = isHorizontalWritingMode() ? flowThreadPoint.y() : flowThreadPoint.x(); |
- LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(blockOffset); |
- if (!columnSet) |
- return LayoutSize(0, 0); |
- return columnSet->flowThreadTranslationAtOffset(blockOffset); |
+ return flowThreadTranslationAtOffset(blockOffset); |
} |
bool LayoutMultiColumnFlowThread::needsNewWidth() const |
@@ -284,6 +282,21 @@ bool LayoutMultiColumnFlowThread::needsNewWidth() const |
return newWidth != logicalWidth(); |
} |
+bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const |
+{ |
+ if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) |
+ return columnSet->isPageLogicalHeightKnown(); |
+ return false; |
+} |
+ |
+LayoutSize LayoutMultiColumnFlowThread::flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) const |
+{ |
+ LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread); |
+ if (!columnSet) |
+ return LayoutSize(0, 0); |
+ return columnSet->flowThreadTranslationAtOffset(offsetInFlowThread); |
+} |
+ |
LayoutPoint LayoutMultiColumnFlowThread::visualPointToFlowThreadPoint(const LayoutPoint& visualPoint) const |
{ |
LayoutUnit blockOffset = isHorizontalWritingMode() ? visualPoint.y() : visualPoint.x(); |
@@ -344,6 +357,8 @@ void LayoutMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa |
return; |
} |
+ m_blockOffsetInEnclosingFlowThread = enclosingFlowThread() ? multiColumnBlockFlow()->offsetFromLogicalTopOfFirstPage() : LayoutUnit(); |
+ |
for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = columnBox->nextSiblingMultiColumnBox()) { |
if (!columnBox->isLayoutMultiColumnSet()) { |
ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no other type is expected. |
@@ -421,6 +436,46 @@ bool LayoutMultiColumnFlowThread::removeSpannerPlaceholderIfNoLongerValid(Layout |
return true; |
} |
+LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::enclosingFlowThread() const |
+{ |
+ if (multiColumnBlockFlow()->isInsideFlowThread()) |
+ return toLayoutMultiColumnFlowThread(locateFlowThreadContainingBlockOf(*multiColumnBlockFlow())); |
+ return nullptr; |
+} |
+ |
+bool LayoutMultiColumnFlowThread::hasFragmentainerGroupForColumnAt(LayoutUnit offsetInFlowThread) const |
+{ |
+ // If there's no enclosing flow thread, there'll always be only one fragmentainer group, and it |
+ // can hold as many columns as we like. We shouldn't even be here in that case. |
+ ASSERT(enclosingFlowThread()); |
+ |
+ LayoutMultiColumnSet* lastColumnSet = lastMultiColumnSet(); |
+ if (!lastColumnSet) { |
+ ASSERT_NOT_REACHED(); |
+ return true; |
+ } |
+ if (lastColumnSet->logicalTopInFlowThread() > offsetInFlowThread) |
+ return true; |
+ const MultiColumnFragmentainerGroup& lastRow = lastColumnSet->lastFragmentainerGroup(); |
+ if (lastRow.logicalTopInFlowThread() > offsetInFlowThread) |
+ return true; |
+ return offsetInFlowThread - lastRow.logicalTopInFlowThread() < lastRow.logicalHeight() * lastColumnSet->usedColumnCount(); |
+} |
+ |
+void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit offsetInFlowThread) |
+{ |
+ LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowThread(); |
+ if (!enclosingFlowThread) |
+ return; // Not nested. We'll never need more rows than the one we already have then. |
+ if (!hasFragmentainerGroupForColumnAt(offsetInFlowThread)) { |
+ // We have run out of columns here, so we add another row to hold more columns. When we add |
+ // a new row, it implicitly means that we're inserting another column in our enclosing |
+ // multicol container. That in turn may mean that we've run out of columns there too. |
+ const MultiColumnFragmentainerGroup& newRow = lastMultiColumnSet()->appendNewFragmentainerGroup(); |
+ enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOffsetInEnclosingFlowThread()); |
+ } |
+} |
+ |
void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const |
{ |
LayoutBlock* columnBlock = multiColumnBlockFlow(); |
@@ -916,11 +971,4 @@ bool LayoutMultiColumnFlowThread::addForcedColumnBreak(LayoutUnit offset, Layout |
return false; |
} |
-bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const |
-{ |
- if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) |
- return columnSet->isPageLogicalHeightKnown(); |
- return false; |
-} |
- |
} |