| Index: Source/core/rendering/RenderMultiColumnFlowThread.cpp
 | 
| diff --git a/Source/core/rendering/RenderMultiColumnFlowThread.cpp b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
 | 
| index 3fcf0db63513c843ae6c22dc48c08d79324a6d2d..b14915da9591a2cd601237165ef3bce56cd7e669 100644
 | 
| --- a/Source/core/rendering/RenderMultiColumnFlowThread.cpp
 | 
| +++ b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
 | 
| @@ -32,7 +32,8 @@
 | 
|  namespace blink {
 | 
|  
 | 
|  RenderMultiColumnFlowThread::RenderMultiColumnFlowThread()
 | 
| -    : m_columnCount(1)
 | 
| +    : m_lastSetWorkedOn(0)
 | 
| +    , m_columnCount(1)
 | 
|      , m_columnHeightAvailable(0)
 | 
|      , m_inBalancingPass(false)
 | 
|      , m_needsColumnHeightsRecalculation(false)
 | 
| @@ -150,11 +151,35 @@ bool RenderMultiColumnFlowThread::needsNewWidth() const
 | 
|      return newWidth != logicalWidth();
 | 
|  }
 | 
|  
 | 
| +RenderMultiColumnSet* RenderMultiColumnFlowThread::columnSetAtBlockOffset(LayoutUnit offset) const
 | 
| +{
 | 
| +    if (m_lastSetWorkedOn) {
 | 
| +        // Layout in progress. We are calculating the set heights as we speak, so the column set range
 | 
| +        // information is not up-to-date.
 | 
| +        return m_lastSetWorkedOn;
 | 
| +    }
 | 
| +
 | 
| +    ASSERT(!m_regionsInvalidated);
 | 
| +    if (m_multiColumnSetList.isEmpty())
 | 
| +        return 0;
 | 
| +    if (offset <= 0)
 | 
| +        return m_multiColumnSetList.first();
 | 
| +
 | 
| +    MultiColumnSetSearchAdapter adapter(offset);
 | 
| +    m_multiColumnSetIntervalTree.allOverlapsWithAdapter<MultiColumnSetSearchAdapter>(adapter);
 | 
| +
 | 
| +    // If no set was found, the offset is in the flow thread overflow.
 | 
| +    if (!adapter.result() && !m_multiColumnSetList.isEmpty())
 | 
| +        return m_multiColumnSetList.last();
 | 
| +    return adapter.result();
 | 
| +}
 | 
| +
 | 
|  void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
 | 
|  {
 | 
|      if (relayoutChildren)
 | 
|          layoutScope.setChildNeedsLayout(this);
 | 
|  
 | 
| +    m_needsColumnHeightsRecalculation = false;
 | 
|      if (!needsLayout()) {
 | 
|          // Just before the multicol container (our parent RenderBlockFlow) finishes laying out, it
 | 
|          // will call recalculateColumnHeights() on us unconditionally, but we only want that method
 | 
| @@ -162,13 +187,13 @@ void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa
 | 
|          // machinery would kick in needlessly, and trigger additional layout passes. Furthermore, we
 | 
|          // actually depend on a proper flowthread layout pass in order to do balancing, since it's
 | 
|          // flowthread layout that sets up content runs.
 | 
| -        m_needsColumnHeightsRecalculation = false;
 | 
|          return;
 | 
|      }
 | 
|  
 | 
| -    for (RenderBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = columnBox->nextSiblingBox()) {
 | 
| +    for (RenderBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = columnBox->nextSiblingMultiColumnBox()) {
 | 
|          if (!columnBox->isRenderMultiColumnSet()) {
 | 
|              ASSERT(columnBox->isRenderMultiColumnSpannerPlaceholder()); // no other type is expected.
 | 
| +            m_needsColumnHeightsRecalculation = true;
 | 
|              continue;
 | 
|          }
 | 
|          RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(columnBox);
 | 
| @@ -177,10 +202,11 @@ void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa
 | 
|              // typically have changed.
 | 
|              columnSet->resetColumnHeight();
 | 
|          }
 | 
| +        if (!m_needsColumnHeightsRecalculation)
 | 
| +            m_needsColumnHeightsRecalculation = columnSet->heightIsAuto();
 | 
|      }
 | 
|  
 | 
|      invalidateRegions();
 | 
| -    m_needsColumnHeightsRecalculation = heightIsAuto();
 | 
|      layout();
 | 
|  }
 | 
|  
 | 
| @@ -327,6 +353,34 @@ void RenderMultiColumnFlowThread::willBeRemovedFromTree()
 | 
|      RenderFlowThread::willBeRemovedFromTree();
 | 
|  }
 | 
|  
 | 
| +LayoutUnit RenderMultiColumnFlowThread::skipColumnSpanner(RenderBox* renderer, LayoutUnit logicalTopInFlowThread)
 | 
| +{
 | 
| +    ASSERT(renderer->isColumnSpanAll());
 | 
| +    RenderMultiColumnSpannerPlaceholder* placeholder = renderer->spannerPlaceholder();
 | 
| +    LayoutUnit adjustment;
 | 
| +    RenderBox* previousColumnBox = placeholder->previousSiblingMultiColumnBox();
 | 
| +    if (previousColumnBox && previousColumnBox->isRenderMultiColumnSet()) {
 | 
| +        // Pad flow thread offset to a column boundary, so that any column content that's supposed
 | 
| +        // to come after the spanner doesn't bleed into the column row preceding the spanner.
 | 
| +        RenderMultiColumnSet* previousSet = toRenderMultiColumnSet(previousColumnBox);
 | 
| +        if (previousSet->pageLogicalHeight()) {
 | 
| +            LayoutUnit columnLogicalTopInFlowThread = previousSet->pageLogicalTopForOffset(logicalTopInFlowThread);
 | 
| +            if (columnLogicalTopInFlowThread != logicalTopInFlowThread) {
 | 
| +                adjustment = columnLogicalTopInFlowThread + previousSet->pageLogicalHeight() - logicalTopInFlowThread;
 | 
| +                logicalTopInFlowThread += adjustment;
 | 
| +            }
 | 
| +        }
 | 
| +        previousSet->endFlow(logicalTopInFlowThread);
 | 
| +    }
 | 
| +    RenderBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox();
 | 
| +    if (nextColumnBox && nextColumnBox->isRenderMultiColumnSet()) {
 | 
| +        RenderMultiColumnSet* nextSet = toRenderMultiColumnSet(nextColumnBox);
 | 
| +        m_lastSetWorkedOn = nextSet;
 | 
| +        nextSet->beginFlow(logicalTopInFlowThread);
 | 
| +    }
 | 
| +    return adjustment;
 | 
| +}
 | 
| +
 | 
|  void RenderMultiColumnFlowThread::flowThreadDescendantWasInserted(RenderObject* descendant)
 | 
|  {
 | 
|      ASSERT(!m_isBeingEvacuated);
 | 
| @@ -390,11 +444,19 @@ void RenderMultiColumnFlowThread::updateLogicalWidth()
 | 
|  
 | 
|  void RenderMultiColumnFlowThread::layout()
 | 
|  {
 | 
| +    ASSERT(!m_lastSetWorkedOn);
 | 
| +    m_lastSetWorkedOn = firstMultiColumnSet();
 | 
| +    if (m_lastSetWorkedOn)
 | 
| +        m_lastSetWorkedOn->beginFlow(LayoutUnit());
 | 
|      RenderFlowThread::layout();
 | 
|      if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) {
 | 
| -        if (!lastSet->nextSiblingMultiColumnBox())
 | 
| +        ASSERT(lastSet == m_lastSetWorkedOn);
 | 
| +        if (!lastSet->nextSiblingMultiColumnBox()) {
 | 
| +            lastSet->endFlow(logicalHeight());
 | 
|              lastSet->expandToEncompassFlowThreadContentsIfNeeded();
 | 
| +        }
 | 
|      }
 | 
| +    m_lastSetWorkedOn = 0;
 | 
|  }
 | 
|  
 | 
|  void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
 | 
| @@ -416,12 +478,6 @@ void RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, Lay
 | 
|          multicolSet->updateMinimumColumnHeight(minHeight);
 | 
|  }
 | 
|  
 | 
| -RenderMultiColumnSet* RenderMultiColumnFlowThread::columnSetAtBlockOffset(LayoutUnit /*offset*/) const
 | 
| -{
 | 
| -    // For now there's only one column set, so this is easy:
 | 
| -    return firstMultiColumnSet();
 | 
| -}
 | 
| -
 | 
|  bool RenderMultiColumnFlowThread::addForcedRegionBreak(LayoutUnit offset, RenderObject* /*breakChild*/, bool /*isBefore*/, LayoutUnit* offsetBreakAdjustment)
 | 
|  {
 | 
|      if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) {
 | 
| 
 |