Bug 857324: Make column set reflow continue without balancing rather than restarting if computed height is exceeded. [r=mats][a=akeybl]
authorScott Johnson <sjohnson@mozilla.com>
Tue, 28 May 2013 16:14:41 -0500
changeset 137703 8ca75debb97abe39f82bf0487422e74e79ab9501
parent 137702 77099bfc09329ae8774773d9c6f009daa00168d3
child 137704 51c78e9573f4005b06bc9d3a0bbf72fc29fed757
child 137706 91d9aba291a09316fb26c035a0ff04c37636bad4
child 137708 3fca8ec8331682c19a4b74809c5bcc6837184ae3
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersmats, akeybl
bugs857324
milestone22.0
Bug 857324: Make column set reflow continue without balancing rather than restarting if computed height is exceeded. [r=mats][a=akeybl]
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsColumnSetFrame.h
layout/reftests/columns/columnfill-auto-2-ref.html
layout/reftests/columns/columnfill-auto-2.html
layout/reftests/columns/columnfill-auto-3.html
layout/reftests/columns/reftest.list
layout/reftests/pagination/resize-reflow-001.inner.html
layout/reftests/pagination/resize-reflow-001.ref.html
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -296,16 +296,44 @@ nsColumnSetFrame::ChooseColumnStrategy(c
          numColumns, colWidth, expectedWidthLeftOver, colHeight, colGap);
 #endif
   ReflowConfig config = { numColumns, colWidth, expectedWidthLeftOver, colGap,
                           colHeight, isBalancing, knownFeasibleHeight,
                           knownInfeasibleHeight };
   return config;
 }
 
+bool
+nsColumnSetFrame::ReflowColumns(nsHTMLReflowMetrics& aDesiredSize,
+                                const nsHTMLReflowState& aReflowState,
+                                nsReflowStatus& aReflowStatus,
+                                ReflowConfig& aConfig,
+                                bool aLastColumnUnbounded,
+                                nsCollapsingMargin* aCarriedOutBottomMargin,
+                                ColumnBalanceData& aColData)
+{
+  bool feasible = ReflowChildren(aDesiredSize, aReflowState,
+                                 aReflowStatus, aConfig, aLastColumnUnbounded,
+                                 aCarriedOutBottomMargin, aColData);
+
+  if (aColData.mHasExcessHeight) {
+    aConfig = ChooseColumnStrategy(aReflowState, true);
+
+    // We need to reflow our children again one last time, otherwise we might
+    // end up with a stale column height for some of our columns, since we
+    // bailed out of balancing.
+    // Return value doesn't matter when !mIsBalancing.
+    ReflowChildren(aDesiredSize, aReflowState, aReflowStatus,
+                   aConfig, aLastColumnUnbounded,
+                   aCarriedOutBottomMargin, aColData);
+  }
+
+  return feasible;
+}
+
 // XXX copied from nsBlockFrame, should this be moved to nsContainerFrame?
 static void
 PlaceFrameView(nsIFrame* aFrame)
 {
   if (aFrame->HasView())
     nsContainerFrame::PositionFrameView(aFrame);
   else
     nsContainerFrame::PositionChildViews(aFrame);
@@ -606,24 +634,23 @@ nsColumnSetFrame::ReflowChildren(nsHTMLR
         }
       }
       else if (kidNextInFlow->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
         aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
         reflowNext = true;
         kidNextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
       }
 
-
       if ((contentBottom > aReflowState.mComputedMaxHeight ||
            contentBottom > aReflowState.ComputedHeight()) &&
            aConfig.mBalanceColCount < INT32_MAX) {
-        // We overflowed vertically, but have not exceeded the number
-        // of columns. If we're balancing, then we should try reverting
-        // to auto instead.
-        aColData.mShouldRevertToAuto = true;
+        // We overflowed vertically, but have not exceeded the number of
+        // columns. We're going to go into overflow columns now, so balancing
+        // no longer applies.
+        aColData.mHasExcessHeight = true;
       }
 
       if (columnCount >= aConfig.mBalanceColCount) {
         // No more columns allowed here. Stop.
         aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
         kidNextInFlow->AddStateBits(NS_FRAME_IS_DIRTY);
         // Move any of our leftover columns to our overflow list. Our
         // next-in-flow will eventually pick them up.
@@ -783,180 +810,173 @@ nsColumnSetFrame::Reflow(nsPresContext* 
   // what the average column height should be, because we can measure
   // the heights of all the columns and sum them up. But don't do this
   // if we have a next in flow because we don't want to suck all its
   // content back here and then have to push it out again!
   nsIFrame* nextInFlow = GetNextInFlow();
   bool unboundedLastColumn = config.mIsBalancing && !nextInFlow;
   nsCollapsingMargin carriedOutBottomMargin;
   ColumnBalanceData colData;
-  colData.mShouldRevertToAuto = false;
+  colData.mHasExcessHeight = false;
 
-  // This loop exists in order to try balancing initially. If the balancing
-  // overflows, then we want to revert to column-fill: auto.
+  bool feasible = ReflowColumns(aDesiredSize, aReflowState, aStatus, config,
+                                unboundedLastColumn, &carriedOutBottomMargin,
+                                colData);
+
+  if (config.mIsBalancing && !aPresContext->HasPendingInterrupt()) {
+    nscoord availableContentHeight = GetAvailableContentHeight(aReflowState);
 
-  // Our loop invariant is: colData.mShouldRevertToAuto is true if and only
-  // if we've reflowed our children, and during the most recent reflow of
-  // children, we were balancing and we overflowed in the block direction.
-  do {
-    if (colData.mShouldRevertToAuto) {
-      config = ChooseColumnStrategy(aReflowState, true);
-      config.mIsBalancing = false;
-    }
+    // Termination of the algorithm below is guaranteed because
+    // config.mKnownFeasibleHeight - config.mKnownInfeasibleHeight decreases
+    // in every iteration.
 
-    bool feasible = ReflowChildren(aDesiredSize, aReflowState,
-      aStatus, config, unboundedLastColumn, &carriedOutBottomMargin, colData);
+    // We set this flag when we detect that we may contain a frame
+    // that can break anywhere (thus foiling the linear decrease-by-one
+    // search)
+    bool maybeContinuousBreakingDetected = false;
+
+    while (!aPresContext->HasPendingInterrupt()) {
+      nscoord lastKnownFeasibleHeight = config.mKnownFeasibleHeight;
 
-    if (config.mIsBalancing && !aPresContext->HasPendingInterrupt()) {
-      nscoord availableContentHeight = GetAvailableContentHeight(aReflowState);
-
-      // Termination of the algorithm below is guaranteed because
-      // config.mKnownFeasibleHeight - config.mKnownInfeasibleHeight decreases
-      // in every iteration.
+      // Record what we learned from the last reflow
+      if (feasible) {
+        // maxHeight is feasible. Also, mLastBalanceHeight is feasible.
+        config.mKnownFeasibleHeight = std::min(config.mKnownFeasibleHeight,
+                                               colData.mMaxHeight);
+        config.mKnownFeasibleHeight = std::min(config.mKnownFeasibleHeight,
+                                               mLastBalanceHeight);
 
-      // We set this flag when we detect that we may contain a frame
-      // that can break anywhere (thus foiling the linear decrease-by-one
-      // search)
-      bool maybeContinuousBreakingDetected = false;
+        // Furthermore, no height less than the height of the last
+        // column can ever be feasible. (We might be able to reduce the
+        // height of a non-last column by moving content to a later column,
+        // but we can't do that with the last column.)
+        if (mFrames.GetLength() == config.mBalanceColCount) {
+          config.mKnownInfeasibleHeight =
+            std::max(config.mKnownInfeasibleHeight, colData.mLastHeight - 1);
+        }
+      } else {
+        config.mKnownInfeasibleHeight =
+          std::max(config.mKnownInfeasibleHeight, mLastBalanceHeight);
+        // If a column didn't fit in its available height, then its current
+        // height must be the minimum height for unbreakable content in
+        // the column, and therefore no smaller height can be feasible.
+        config.mKnownInfeasibleHeight =
+          std::max(config.mKnownInfeasibleHeight,
+                   colData.mMaxOverflowingHeight - 1);
 
-      while (!aPresContext->HasPendingInterrupt()) {
-        nscoord lastKnownFeasibleHeight = config.mKnownFeasibleHeight;
-
-        // Record what we learned from the last reflow
-        if (feasible) {
-          // maxHeight is feasible. Also, mLastBalanceHeight is feasible.
+        if (unboundedLastColumn) {
+          // The last column is unbounded, so all content got reflowed, so the
+          // mColMaxHeight is feasible.
           config.mKnownFeasibleHeight = std::min(config.mKnownFeasibleHeight,
                                                  colData.mMaxHeight);
-          config.mKnownFeasibleHeight = std::min(config.mKnownFeasibleHeight,
-                                                 mLastBalanceHeight);
-
-          // Furthermore, no height less than the height of the last
-          // column can ever be feasible. (We might be able to reduce the
-          // height of a non-last column by moving content to a later column,
-          // but we can't do that with the last column.)
-          if (mFrames.GetLength() == config.mBalanceColCount) {
-            config.mKnownInfeasibleHeight =
-              std::max(config.mKnownInfeasibleHeight, colData.mLastHeight - 1);
-          }
-        } else {
-          config.mKnownInfeasibleHeight =
-            std::max(config.mKnownInfeasibleHeight, mLastBalanceHeight);
-          // If a column didn't fit in its available height, then its current
-          // height must be the minimum height for unbreakable content in
-          // the column, and therefore no smaller height can be feasible.
-          config.mKnownInfeasibleHeight =
-            std::max(config.mKnownInfeasibleHeight,
-                     colData.mMaxOverflowingHeight - 1);
-
-          if (unboundedLastColumn) {
-            // The last column is unbounded, so all content got reflowed, so the
-            // mColMaxHeight is feasible.
-            config.mKnownFeasibleHeight = std::min(config.mKnownFeasibleHeight,
-                                                   colData.mMaxHeight);
-          }
         }
+      }
 
 #ifdef DEBUG_roc
-        printf("*** nsColumnSetFrame::Reflow balancing knownInfeasible=%d knownFeasible=%d\n",
-               config.mKnownInfeasibleHeight, config.mKnownFeasibleHeight);
+      printf("*** nsColumnSetFrame::Reflow balancing knownInfeasible=%d knownFeasible=%d\n",
+             config.mKnownInfeasibleHeight, config.mKnownFeasibleHeight);
 #endif
 
 
-        if (config.mKnownInfeasibleHeight >= config.mKnownFeasibleHeight - 1) {
-          // config.mKnownFeasibleHeight is where we want to be
-          break;
+      if (config.mKnownInfeasibleHeight >= config.mKnownFeasibleHeight - 1) {
+        // config.mKnownFeasibleHeight is where we want to be
+        break;
 
-        }
-        if (config.mKnownInfeasibleHeight >= availableContentHeight) {
-          break;
-        }
+      }
+      if (config.mKnownInfeasibleHeight >= availableContentHeight) {
+        break;
+      }
 
-        if (lastKnownFeasibleHeight - config.mKnownFeasibleHeight == 1) {
-          // We decreased the feasible height by one twip only. This could
-          // indicate that there is a continuously breakable child frame
-          // that we are crawling through.
-          maybeContinuousBreakingDetected = true;
-        }
+      if (lastKnownFeasibleHeight - config.mKnownFeasibleHeight == 1) {
+        // We decreased the feasible height by one twip only. This could
+        // indicate that there is a continuously breakable child frame
+        // that we are crawling through.
+        maybeContinuousBreakingDetected = true;
+      }
 
-        nscoord nextGuess =
-          (config.mKnownFeasibleHeight + config.mKnownInfeasibleHeight)/2;
-        // The constant of 600 twips is arbitrary. It's about two line-heights.
-        if (config.mKnownFeasibleHeight - nextGuess < 600 &&
-            !maybeContinuousBreakingDetected) {
-          // We're close to our target, so just try shrinking just the
-          // minimum amount that will cause one of our columns to break
-          // differently.
-          nextGuess = config.mKnownFeasibleHeight - 1;
-        } else if (unboundedLastColumn) {
-          // Make a guess by dividing that into N columns. Add some slop
-          // to try to make it on the feasible side.  The constant of
-          // 600 twips is arbitrary. It's about two line-heights.
-          nextGuess = colData.mSumHeight/config.mBalanceColCount + 600;
-          // Sanitize it
-          nextGuess = clamped(nextGuess, config.mKnownInfeasibleHeight + 1,
-                                         config.mKnownFeasibleHeight - 1);
-        } else if (config.mKnownFeasibleHeight == NS_INTRINSICSIZE) {
-          // This can happen when we had a next-in-flow so we didn't
-          // want to do an unbounded height measuring step. Let's just increase
-          // from the infeasible height by some reasonable amount.
-          nextGuess = config.mKnownInfeasibleHeight*2 + 600;
-        }
-        // Don't bother guessing more than our height constraint.
-        nextGuess = std::min(availableContentHeight, nextGuess);
+      nscoord nextGuess =
+        (config.mKnownFeasibleHeight + config.mKnownInfeasibleHeight)/2;
+      // The constant of 600 twips is arbitrary. It's about two line-heights.
+      if (config.mKnownFeasibleHeight - nextGuess < 600 &&
+          !maybeContinuousBreakingDetected) {
+        // We're close to our target, so just try shrinking just the
+        // minimum amount that will cause one of our columns to break
+        // differently.
+        nextGuess = config.mKnownFeasibleHeight - 1;
+      } else if (unboundedLastColumn) {
+        // Make a guess by dividing that into N columns. Add some slop
+        // to try to make it on the feasible side.  The constant of
+        // 600 twips is arbitrary. It's about two line-heights.
+        nextGuess = colData.mSumHeight/config.mBalanceColCount + 600;
+        // Sanitize it
+        nextGuess = clamped(nextGuess, config.mKnownInfeasibleHeight + 1,
+                                       config.mKnownFeasibleHeight - 1);
+      } else if (config.mKnownFeasibleHeight == NS_INTRINSICSIZE) {
+        // This can happen when we had a next-in-flow so we didn't
+        // want to do an unbounded height measuring step. Let's just increase
+        // from the infeasible height by some reasonable amount.
+        nextGuess = config.mKnownInfeasibleHeight*2 + 600;
+      }
+      // Don't bother guessing more than our height constraint.
+      nextGuess = std::min(availableContentHeight, nextGuess);
 
 #ifdef DEBUG_roc
-        printf("*** nsColumnSetFrame::Reflow balancing choosing next guess=%d\n", nextGuess);
+      printf("*** nsColumnSetFrame::Reflow balancing choosing next guess=%d\n", nextGuess);
 #endif
 
-        config.mColMaxHeight = nextGuess;
-
-        unboundedLastColumn = false;
-        AddStateBits(NS_FRAME_IS_DIRTY);
-        feasible = ReflowChildren(aDesiredSize, aReflowState,
-                                  aStatus, config, false,
-                                  &carriedOutBottomMargin, colData);
-      }
+      config.mColMaxHeight = nextGuess;
 
-      if (!feasible && !aPresContext->HasPendingInterrupt()) {
-        // We may need to reflow one more time at the feasible height to
-        // get a valid layout.
-        bool skip = false;
-        if (config.mKnownInfeasibleHeight >= availableContentHeight) {
-            config.mColMaxHeight = availableContentHeight;
-          if (mLastBalanceHeight == availableContentHeight) {
-            skip = true;
-          }
-        } else {
-          config.mColMaxHeight = config.mKnownFeasibleHeight;
-        }
-        if (!skip) {
-          // If our height is unconstrained, make sure that the last column is
-          // allowed to have arbitrary height here, even though we were balancing.
-          // Otherwise we'd have to split, and it's not clear what we'd do with
-          // that.
-          AddStateBits(NS_FRAME_IS_DIRTY);
-          ReflowChildren(aDesiredSize, aReflowState, aStatus, config,
-                         availableContentHeight == NS_UNCONSTRAINEDSIZE,
-                         &carriedOutBottomMargin, colData);
-        }
+      unboundedLastColumn = false;
+      AddStateBits(NS_FRAME_IS_DIRTY);
+      feasible = ReflowColumns(aDesiredSize, aReflowState, aStatus, config, false,
+                               &carriedOutBottomMargin, colData);
+
+      if (!config.mIsBalancing) {
+        // Looks like we had excess height when balancing, so we gave up on
+        // trying to balance.
+        break;
       }
     }
 
- } while (colData.mShouldRevertToAuto);
+    if (config.mIsBalancing && !feasible &&
+        !aPresContext->HasPendingInterrupt()) {
+      // We may need to reflow one more time at the feasible height to
+      // get a valid layout.
+      bool skip = false;
+      if (config.mKnownInfeasibleHeight >= availableContentHeight) {
+          config.mColMaxHeight = availableContentHeight;
+        if (mLastBalanceHeight == availableContentHeight) {
+          skip = true;
+        }
+      } else {
+        config.mColMaxHeight = config.mKnownFeasibleHeight;
+      }
+      if (!skip) {
+        // If our height is unconstrained, make sure that the last column is
+        // allowed to have arbitrary height here, even though we were balancing.
+        // Otherwise we'd have to split, and it's not clear what we'd do with
+        // that.
+        AddStateBits(NS_FRAME_IS_DIRTY);
+        ReflowColumns(aDesiredSize, aReflowState, aStatus, config,
+                      availableContentHeight == NS_UNCONSTRAINEDSIZE,
+                      &carriedOutBottomMargin, colData);
+      }
+    }
+  }
 
-    if (aPresContext->HasPendingInterrupt() &&
-        aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) {
-      // In this situation, we might be lying about our reflow status, because
-      // our last kid (the one that got interrupted) was incomplete.  Fix that.
-      aStatus = NS_FRAME_COMPLETE;
-    }
+  if (aPresContext->HasPendingInterrupt() &&
+      aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) {
+    // In this situation, we might be lying about our reflow status, because
+    // our last kid (the one that got interrupted) was incomplete.  Fix that.
+    aStatus = NS_FRAME_COMPLETE;
+  }
 
-    FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus, false);
+  FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus, false);
 
-    aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
+  aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
 
   NS_ASSERTION(NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
                aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE,
                "Column set should be complete if the available height is unconstrained");
 
   return NS_OK;
--- a/layout/generic/nsColumnSetFrame.h
+++ b/layout/generic/nsColumnSetFrame.h
@@ -132,33 +132,42 @@ protected:
     nscoord mMaxHeight;
     // The sum of the "content heights" for all columns
     nscoord mSumHeight;
     // The "content height" of the last column
     nscoord mLastHeight;
     // The maximum "content height" of all columns that overflowed
     // their available height
     nscoord mMaxOverflowingHeight;
-    // Whether or not we should revert back to 'auto' setting for column-fill.
-    // This happens if we overflow our columns such that we no longer have
-    // enough room to keep balancing.
-    bool mShouldRevertToAuto;
+    // This flag determines whether the last reflow of children exceeded the
+    // computed height of the column set frame. If so, we set the height to
+    // this maximum allowable height, and continue reflow without balancing.
+    bool mHasExcessHeight;
+
     void Reset() {
       mMaxHeight = mSumHeight = mLastHeight = mMaxOverflowingHeight = 0;
-      mShouldRevertToAuto = false;
+      mHasExcessHeight = false;
     }
   };
 
   /**
    * Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
    * handled by our prev-in-flow, and any columns sitting on our own
    * overflow list, and put them in our primary child list for reflowing.
    */
   void DrainOverflowColumns();
 
+  bool ReflowColumns(nsHTMLReflowMetrics& aDesiredSize,
+                     const nsHTMLReflowState& aReflowState,
+                     nsReflowStatus& aReflowStatus,
+                     ReflowConfig& aConfig,
+                     bool aLastColumnUnbounded,
+                     nsCollapsingMargin* aCarriedOutBottomMargin,
+                     ColumnBalanceData& aColData);
+
   /**
    * The basic reflow strategy is to call this function repeatedly to
    * obtain specific parameters that determine the layout of the
    * columns. This function will compute those parameters from the CSS
    * style. This function will also be responsible for implementing
    * the state machine that controls column balancing.
    */
   ReflowConfig ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-auto-2-ref.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="ahem.css" />
+<style>
+  html {
+    line-height: 1.5;
+    font-family: ahem;
+  }
+
+  body {
+    margin: 0;
+    padding: 0;
+  }
+
+  #test {
+    padding: 5px 0px 0px 10px;
+    position: absolute;
+    left: 500px;
+    right: 0px;
+    top: 0px;
+    bottom: 0px;
+    background-color: orange;
+    height: 120px;
+    -moz-column-width: 640px;
+    -moz-column-fill: balance;
+    -moz-column-gap: 0;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+
+  #parent {
+    background-color: lightBlue;
+    position: absolute;
+    left: 0px;
+    bottom: 0px;
+    right: 0px;
+    height: 120px;
+    width: 70em;
+  }
+</style>
+</head>
+<body>
+  <div id="parent">
+    <div id="test">To Mrs. Aville, England St. Petersburgh, Dec. 11th, 17- You will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings. I arrived here yesterday; and my first task is to assure my dear sister of my welfare, and increasing confidence in the success of my undertaking. I am already far north of London; and as I walk in the streets of Petersburgh. I feel a cold northern breeze play upon my cheeks, which braces my nerves, and fills me with delight.</div>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-auto-2.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="ahem.css" />
+<style>
+  html {
+    line-height: 1.5;
+    font-family: ahem;
+  }
+
+  body {
+    margin: 0;
+    padding: 0;
+  }
+
+  #test {
+    padding: 5px 0px 0px 10px;
+    position: absolute;
+    left: 500px;
+    right: 0px;
+    top: 0px;
+    bottom: 0px;
+    background-color: orange;
+    height: 120px;
+    -moz-column-width: 640px;
+    -moz-column-fill: auto;
+    -moz-column-gap: 0;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+
+  #parent {
+    background-color: lightBlue;
+    position: absolute;
+    left: 0px;
+    bottom: 0px;
+    right: 0px;
+    height: 120px;
+    width: 70em;
+  }
+</style>
+</head>
+<body>
+  <div id="parent">
+    <div id="test">To Mrs. Aville, England St. Petersburgh, Dec. 11th, 17- You will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings. I arrived here yesterday; and my first task is to assure my dear sister of my welfare, and increasing confidence in the success of my undertaking. I am already far north of London; and as I walk in the streets of Petersburgh. I feel a cold northern breeze play upon my cheeks, which braces my nerves, and fills me with delight.</div>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/columnfill-auto-3.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="ahem.css" />
+<style>
+  html {
+    line-height: 1.5;
+    font-family: ahem;
+  }
+
+  body {
+    margin: 0;
+    padding: 0;
+  }
+
+  #test {
+    padding: 5px 0px 0px 10px;
+    position: absolute;
+    left: 500px;
+    right: 0px;
+    top: 0px;
+    background-color: orange;
+    max-height: 120px;
+    -moz-column-width: 640px;
+    -moz-column-fill: auto;
+    -moz-column-gap: 0;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+
+  #parent {
+    background-color: lightBlue;
+    position: absolute;
+    left: 0px;
+    bottom: 0px;
+    right: 0px;
+    height: 120px;
+    width: 70em;
+  }
+</style>
+</head>
+<body>
+  <div id="parent">
+    <div id="test">To Mrs. Aville, England St. Petersburgh, Dec. 11th, 17- You will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings. I arrived here yesterday; and my first task is to assure my dear sister of my welfare, and increasing confidence in the success of my undertaking. I am already far north of London; and as I walk in the streets of Petersburgh. I feel a cold northern breeze play upon my cheeks, which braces my nerves, and fills me with delight.</div>
+  </div>
+</body>
+</html>
--- a/layout/reftests/columns/reftest.list
+++ b/layout/reftests/columns/reftest.list
@@ -14,16 +14,18 @@
 == column-balancing-000.html column-balancing-000.ref.html
 == column-balancing-001.html column-balancing-000.ref.html
 == column-balancing-002.html column-balancing-002.ref.html
 == column-balancing-003.html column-balancing-000.ref.html
 == column-balancing-004.html column-balancing-004.ref.html
 == column-box-alignment-rtl.html column-box-alignment-rtl-ref.html
 HTTP(..) == columnfill-balance.html columnfill-balance-ref.html
 HTTP(..) == columnfill-auto.html columnfill-auto-ref.html
+HTTP(..) == columnfill-auto-2.html columnfill-auto-2-ref.html
+HTTP(..) == columnfill-auto-3.html columnfill-auto-2-ref.html
 skip-if(B2G) == columnrule-basic.html columnrule-basic-ref.html # bug 773482
 skip-if(B2G) == columnrule-complex.html columnrule-complex-ref.html # bug 773482
 != columnrule-linestyles.html columnrule-linestyles-notref.html
 == columnrule-padding.html columnrule-padding-ref.html
 skip-if(B2G) == columnfill-overflow.html columnfill-overflow-ref.html # bug 773482
 == margin-collapsing-bug616722-1.html margin-collapsing-bug616722-1-ref.html
 == margin-collapsing-bug616722-2.html margin-collapsing-bug616722-2-ref.html
 == column-balancing-nested-000.html column-balancing-nested-000-ref.html
--- a/layout/reftests/pagination/resize-reflow-001.inner.html
+++ b/layout/reftests/pagination/resize-reflow-001.inner.html
@@ -6,17 +6,17 @@
     html, body { margin: 0; padding: 0; }
     html { overflow: hidden }
   </style>
 </head>
 <body>
 
 <div style="-moz-column-width: 12em;
             border: silver solid;
-            height: 4em;">
+            height: 5em;">
   <div style="border: dotted;
               background: aqua;
               color: gray;">
         blah<br>
         blah<br>
         blah<br>
         blah
   </div>
--- a/layout/reftests/pagination/resize-reflow-001.ref.html
+++ b/layout/reftests/pagination/resize-reflow-001.ref.html
@@ -2,17 +2,17 @@
 <html>
 <head>
   <title>Resize Reflow Test</title>
 </head>
 <body style="width: 28em">
 
 <div style="-moz-column-width: 12em;
             border: silver solid;
-            height: 4em;">
+            height: 5em;">
   <div style="border: dotted;
               background: aqua;
               color: gray;">
         blah<br>
         blah<br>
         blah<br>
         blah
   </div>