Set inflation container to null during parts of intrinsic sizing that should not have inflation applied. (Bug 706609, patch 4) r=roc
authorL. David Baron <dbaron@dbaron.org>
Tue, 24 Jan 2012 17:21:29 -0800
changeset 86528 3051be6f12c23ceda14b80dc37ac46906a22d14f
parent 86527 b626d3cc9ab17fee1b5d155df172d068036aba6f
child 86529 8213675b8a78cc6e8d9c43e5ebdfe66786ae02e5
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs706609
milestone12.0a1
Set inflation container to null during parts of intrinsic sizing that should not have inflation applied. (Bug 706609, patch 4) r=roc This is the first of two patches to honor inflation during intrinsic width calculation (which we need to do to make some form controls inflate correctly).
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/tests/Makefile.in
layout/base/tests/font-inflation/intrinsic-fit-1a-ref.html
layout/base/tests/font-inflation/intrinsic-fit-1a.html
layout/base/tests/font-inflation/intrinsic-fit-1b-ref.html
layout/base/tests/font-inflation/intrinsic-fit-1b.html
layout/base/tests/font-inflation/intrinsic-fit-1c-ref.html
layout/base/tests/font-inflation/intrinsic-fit-1c.html
layout/base/tests/font-inflation/intrinsic-fit-2a.html
layout/base/tests/font-inflation/intrinsic-fit-2b.html
layout/base/tests/font-inflation/intrinsic-fit-2c.html
layout/base/tests/font-inflation/intrinsic-max-1-ref.html
layout/base/tests/font-inflation/intrinsic-max-1.html
layout/base/tests/font-inflation/intrinsic-min-1-ref.html
layout/base/tests/font-inflation/intrinsic-min-1.html
layout/base/tests/test_font_inflation_reftests.html
layout/forms/nsFieldSetFrame.cpp
layout/generic/nsFrame.cpp
layout/tables/BasicTableLayoutStrategy.cpp
layout/tables/nsTableFrame.cpp
layout/tables/nsTableOuterFrame.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -116,16 +116,17 @@
 #include "nsXULPopupManager.h"
 #endif
 
 #include "sampler.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
+using namespace mozilla::layout;
 
 #ifdef DEBUG
 // TODO: remove, see bug 598468.
 bool nsLayoutUtils::gPreventAssertInCompareTreePosition = false;
 #endif // DEBUG
 
 typedef gfxPattern::GraphicsFilter GraphicsFilter;
 typedef FrameMetrics::ViewID ViewID;
@@ -2323,16 +2324,21 @@ GetIntrinsicCoord(const nsStyleCoord& aS
     else
       // constrain small 'width' or 'max-width' values up to -moz-min-content
       val = NS_STYLE_WIDTH_MIN_CONTENT;
   }
 
   NS_ASSERTION(val == NS_STYLE_WIDTH_MAX_CONTENT ||
                val == NS_STYLE_WIDTH_MIN_CONTENT,
                "should have reduced everything remaining to one of these");
+
+  // If aFrame is a container for font size inflation, then shrink
+  // wrapping inside of it should not apply font size inflation.
+  AutoMaybeNullInflationContainer an(aFrame);
+
   if (val == NS_STYLE_WIDTH_MAX_CONTENT)
     aResult = aFrame->GetPrefWidth(aRenderingContext);
   else
     aResult = aFrame->GetMinWidth(aRenderingContext);
   return true;
 }
 
 #undef  DEBUG_INTRINSIC_WIDTH
@@ -2351,16 +2357,20 @@ nsLayoutUtils::IntrinsicForContainer(nsR
 
 #ifdef DEBUG_INTRINSIC_WIDTH
   nsFrame::IndentBy(stdout, gNoiseIndent);
   static_cast<nsFrame*>(aFrame)->ListTag(stdout);
   printf(" %s intrinsic width for container:\n",
          aType == MIN_WIDTH ? "min" : "pref");
 #endif
 
+  // If aFrame is a container for font size inflation, then shrink
+  // wrapping inside of it should not apply font size inflation.
+  AutoMaybeNullInflationContainer an(aFrame);
+
   nsIFrame::IntrinsicWidthOffsetData offsets =
     aFrame->IntrinsicWidthOffsets(aRenderingContext);
 
   const nsStylePosition *stylePos = aFrame->GetStylePosition();
   PRUint8 boxSizing = stylePos->mBoxSizing;
   const nsStyleCoord &styleWidth = stylePos->mWidth;
   const nsStyleCoord &styleMinWidth = stylePos->mMinWidth;
   const nsStyleCoord &styleMaxWidth = stylePos->mMaxWidth;
@@ -2606,16 +2616,20 @@ nsLayoutUtils::ComputeWidthValue(
   nscoord result;
   if (aCoord.IsCoordPercentCalcUnit()) {
     result = nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockWidth);
     // The result of a calc() expression might be less than 0; we
     // should clamp at runtime (below).  (Percentages and coords that
     // are less than 0 have already been dropped by the parser.)
     result -= aContentEdgeToBoxSizing;
   } else if (eStyleUnit_Enumerated == aCoord.GetUnit()) {
+    // If aFrame is a container for font size inflation, then shrink
+    // wrapping inside of it should not apply font size inflation.
+    AutoMaybeNullInflationContainer an(aFrame);
+
     PRInt32 val = aCoord.GetIntValue();
     switch (val) {
       case NS_STYLE_WIDTH_MAX_CONTENT:
         result = aFrame->GetPrefWidth(aRenderingContext);
         NS_ASSERTION(result >= 0, "width less than zero");
         break;
       case NS_STYLE_WIDTH_MIN_CONTENT:
         result = aFrame->GetMinWidth(aRenderingContext);
@@ -2952,27 +2966,33 @@ nsLayoutUtils::ComputeAutoSizeWithIntrin
 
   return nsSize(width, height);
 }
 
 /* static */ nscoord
 nsLayoutUtils::MinWidthFromInline(nsIFrame* aFrame,
                                   nsRenderingContext* aRenderingContext)
 {
+  NS_ASSERTION(!nsLayoutUtils::IsContainerForFontSizeInflation(aFrame),
+               "should not be container for font size inflation");
+
   nsIFrame::InlineMinWidthData data;
   DISPLAY_MIN_WIDTH(aFrame, data.prevLines);
   aFrame->AddInlineMinWidth(aRenderingContext, &data);
   data.ForceBreak(aRenderingContext);
   return data.prevLines;
 }
 
 /* static */ nscoord
 nsLayoutUtils::PrefWidthFromInline(nsIFrame* aFrame,
                                    nsRenderingContext* aRenderingContext)
 {
+  NS_ASSERTION(!nsLayoutUtils::IsContainerForFontSizeInflation(aFrame),
+               "should not be container for font size inflation");
+
   nsIFrame::InlinePrefWidthData data;
   DISPLAY_PREF_WIDTH(aFrame, data.prevLines);
   aFrame->AddInlinePrefWidth(aRenderingContext, &data);
   data.ForceBreak(aRenderingContext);
   return data.prevLines;
 }
 
 static nscolor
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1633,16 +1633,53 @@ public:
    * Assert that the frame tree rooted at |aSubtreeRoot| is empty, i.e.,
    * that it contains no first-in-flows.
    */
   static void
   AssertTreeOnlyEmptyNextInFlows(nsIFrame *aSubtreeRoot);
 #endif
 };
 
+namespace mozilla {
+  namespace layout {
+
+    /**
+     * An RAII class which will, for the duration of its lifetime,
+     * **if** the frame given is a container for font size inflation,
+     * set the current inflation container on the pres context to null
+     * (and then, in its destructor, restore the old value).
+     */
+    class AutoMaybeNullInflationContainer {
+    public:
+      AutoMaybeNullInflationContainer(nsIFrame *aFrame)
+      {
+        if (nsLayoutUtils::IsContainerForFontSizeInflation(aFrame)) {
+          mPresContext = aFrame->PresContext();
+          mOldValue = mPresContext->mCurrentInflationContainer;
+          mPresContext->mCurrentInflationContainer = nsnull;
+        } else {
+          // indicate we have nothing to restore
+          mPresContext = nsnull;
+        }
+      }
+
+      ~AutoMaybeNullInflationContainer()
+      {
+        if (mPresContext) {
+          mPresContext->mCurrentInflationContainer = mOldValue;
+        }
+      }
+    private:
+      nsPresContext *mPresContext;
+      nsIFrame *mOldValue;
+    };
+
+  }
+}
+
 class nsSetAttrRunnable : public nsRunnable
 {
 public:
   nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
                     const nsAString& aValue);
   nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
                     PRInt32 aValue);
 
--- a/layout/base/tests/Makefile.in
+++ b/layout/base/tests/Makefile.in
@@ -378,16 +378,17 @@ endif
 
 _BROWSER_FILES = \
 	browser_bug617076.js \
 	$(NULL)
 
 _INFLATION_REFTEST_FILES = \
 		$(shell find $(srcdir)/font-inflation/ -name '*.html' -o -name '*.xhtml') \
 		$(srcdir)/../../reftests/webm-video/black140x100.webm \
+		$(srcdir)/../../reftests/fonts/Ahem.ttf \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 libs:: $(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
 libs:: $(_INFLATION_REFTEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)/font-inflation/
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-1a-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 10px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: 60px;
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 60px container, the minimum font size at 15em per line is 4px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-1a.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 10px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: -moz-fit-content; /* computes to 60px */
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 60px container, the minimum font size at 15em per line is 4px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-1b-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 450px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: 300px;
+  font: 24px Ahem;
+}
+</style>
+<!--
+In a 300px container, the minimum font size at 15em per line is 20px.
+This means we map 0px-30px into 20px-30px, so 12px gets mapped to 24px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-1b.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 450px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: -moz-fit-content; /* computes to 300px */
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 300px container, the minimum font size at 15em per line is 20px.
+This means we map 0px-30px into 20px-30px, so 12px gets mapped to 24px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-1c-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 150px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: 150px;
+  font: 14px Ahem;
+}
+</style>
+<!--
+In a 150px container, the minimum font size at 15em per line is 10px.
+This means we map 0px-15px into 10px-15px, so 12px gets mapped to 14px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-1c.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 150px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: -moz-fit-content; /* computes to 150px */
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 150px container, the minimum font size at 15em per line is 10px.
+This means we map 0px-15px into 10px-15px, so 12px gets mapped to 14px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-2a.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 10px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  float: left;
+  width: auto; /* computes to 60px */
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 60px container, the minimum font size at 15em per line is 4px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-2b.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 450px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  float: left;
+  width: auto; /* computes to 300px */
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 300px container, the minimum font size at 15em per line is 20px.
+This means we map 0px-30px into 20px-30px, so 12px gets mapped to 24px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-fit-2c.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 150px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  float: left;
+  width: auto; /* computes to 150px */
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 150px container, the minimum font size at 15em per line is 10px.
+This means we map 0px-15px into 10px-15px, so 12px gets mapped to 14px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-max-1-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 450px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: 300px;
+  font: 24px Ahem;
+}
+</style>
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-max-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 450px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: -moz-max-content; /* computes to 300px */
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 300px container, the minimum font size at 15em per line is 20px.
+This means we map 0px-30px into 20px-30px, so 12px gets mapped to 24px.
+-->
+<p>This is tiny bit of text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-min-1-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 450px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: 60px;
+  font: 12px Ahem;
+}
+</style>
+<!--
+In a 60px container, the minimum font size at 15em per line is 4px.
+-->
+<p>This is some text.</p>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/font-inflation/intrinsic-min-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<style>
+@font-face { font-family: Ahem; src: url(Ahem.ttf); }
+html, body { margin: 0; padding: 0; }
+body { width: 450px }
+p {
+  margin: 0;
+  background: yellow;
+  color: blue;
+  width: -moz-min-content; /* computes to 60px */
+  font: 12px Ahem;
+}
+</style>
+<p>This is some text.</p>
--- a/layout/base/tests/test_font_inflation_reftests.html
+++ b/layout/base/tests/test_font_inflation_reftests.html
@@ -42,16 +42,24 @@ var gTests = [
   "== input-text-3.html input-text-3-ref.html",
   "== textarea-1.html textarea-1-ref.html",
   "== textarea-2.html textarea-2-ref.html",
   "== textarea-3.html textarea-3-ref.html",
   "== css-transform-1.html css-transform-1-ref.html",
   "== css-transform-2.html css-transform-2-ref.html",
   "== container-with-clamping.html container-with-clamping-ref.html",
   "!= video-1.html about:blank", // crashtest
+  "== intrinsic-min-1.html intrinsic-min-1-ref.html",
+  "== intrinsic-max-1.html intrinsic-max-1-ref.html",
+  "== intrinsic-fit-1a.html intrinsic-fit-1a-ref.html",
+  "== intrinsic-fit-1b.html intrinsic-fit-1b-ref.html",
+  "== intrinsic-fit-1c.html intrinsic-fit-1c-ref.html",
+  "== intrinsic-fit-2a.html intrinsic-fit-1a-ref.html",
+  "== intrinsic-fit-2b.html intrinsic-fit-1b-ref.html",
+  "== intrinsic-fit-2c.html intrinsic-fit-1c-ref.html",
 ];
 
 // Maintain a reference count of how many things we're waiting for until
 // we can say the tests are done.
 var gDelayCount = 0;
 function AddFinishDependency()
   { ++gDelayCount; }
 function RemoveFinishDependency()
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -58,16 +58,19 @@
 #include "nsCOMPtr.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 #include "nsIServiceManager.h"
 #include "nsDisplayList.h"
 #include "nsRenderingContext.h"
 
+using namespace mozilla;
+using namespace mozilla::layout;
+
 class nsLegendFrame;
 
 class nsFieldSetFrame : public nsContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   nsFieldSetFrame(nsStyleContext* aContext);
 
@@ -398,16 +401,21 @@ nsFieldSetFrame::ComputeSize(nsRendering
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              bool aShrinkWrap)
 {
   nsSize result =
     nsContainerFrame::ComputeSize(aRenderingContext, aCBSize, aAvailableWidth,
                                   aMargin, aBorder, aPadding, aShrinkWrap);
 
   // Fieldsets never shrink below their min width.
+
+  // If we're a container for font size inflation, then shrink
+  // wrapping inside of us should not apply font size inflation.
+  AutoMaybeNullInflationContainer an(this);
+
   nscoord minWidth = GetMinWidth(aRenderingContext);
   if (minWidth > result.width)
     result.width = minWidth;
 
   return result;
 }
 
 NS_IMETHODIMP 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -127,16 +127,17 @@
 #include "CSSCalc.h"
 #include "nsAbsoluteContainingBlock.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
+using namespace mozilla::layout;
 
 // Struct containing cached metrics for box-wrapped frames.
 struct nsBoxLayoutMetrics
 {
   nsSize mPrefSize;
   nsSize mMinSize;
   nsSize mMaxSize;
 
@@ -3847,16 +3848,20 @@ nsFrame::ComputeAutoSize(nsRenderingCont
   }
   return result;
 }
 
 nscoord
 nsFrame::ShrinkWidthToFit(nsRenderingContext *aRenderingContext,
                           nscoord aWidthInCB)
 {
+  // If we're a container for font size inflation, then shrink
+  // wrapping inside of us should not apply font size inflation.
+  AutoMaybeNullInflationContainer an(this);
+
   nscoord result;
   nscoord minWidth = GetMinWidth(aRenderingContext);
   if (minWidth > aWidthInCB) {
     result = minWidth;
   } else {
     nscoord prefWidth = GetPrefWidth(aRenderingContext);
     if (prefWidth > aWidthInCB) {
       result = aWidthInCB;
@@ -7234,18 +7239,26 @@ nsFrame::RefreshSizeCache(nsBoxLayoutSta
     nsRect oldRect = GetRect();
 
     // the rect we plan to size to.
     nsRect rect(oldRect);
 
     nsMargin bp(0,0,0,0);
     GetBorderAndPadding(bp);
 
-    metrics->mBlockPrefSize.width = GetPrefWidth(rendContext) + bp.LeftRight();
-    metrics->mBlockMinSize.width = GetMinWidth(rendContext) + bp.LeftRight();
+    {
+      // If we're a container for font size inflation, then shrink
+      // wrapping inside of us should not apply font size inflation.
+      AutoMaybeNullInflationContainer an(this);
+
+      metrics->mBlockPrefSize.width =
+        GetPrefWidth(rendContext) + bp.LeftRight();
+      metrics->mBlockMinSize.width =
+        GetMinWidth(rendContext) + bp.LeftRight();
+    }
 
     // do the nasty.
     nsHTMLReflowMetrics desiredSize;
     rv = BoxReflow(aState, presContext, desiredSize, rendContext,
                    rect.x, rect.y,
                    metrics->mBlockPrefSize.width, NS_UNCONSTRAINEDSIZE);
 
     nsRect newRect = GetRect();
--- a/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/layout/tables/BasicTableLayoutStrategy.cpp
@@ -43,16 +43,19 @@
 
 #include "BasicTableLayoutStrategy.h"
 #include "nsTableFrame.h"
 #include "nsTableCellFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsGkAtoms.h"
 #include "SpanningCellSorter.h"
 
+using namespace mozilla;
+using namespace mozilla::layout;
+
 namespace css = mozilla::css;
 
 #undef  DEBUG_TABLE_STRATEGY 
 
 BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aTableFrame)
   : nsITableLayoutStrategy(nsITableLayoutStrategy::Auto)
   , mTableFrame(aTableFrame)
 {
@@ -105,16 +108,20 @@ struct CellWidthInfo {
 // Used for both column and cell calculations.  The parts needed only
 // for cells are skipped when aIsCell is false.
 static CellWidthInfo
 GetWidthInfo(nsRenderingContext *aRenderingContext,
              nsIFrame *aFrame, bool aIsCell)
 {
     nscoord minCoord, prefCoord;
     if (aIsCell) {
+        // If aFrame is a container for font size inflation, then shrink
+        // wrapping inside of it should not apply font size inflation.
+        AutoMaybeNullInflationContainer an(aFrame);
+
         minCoord = aFrame->GetMinWidth(aRenderingContext);
         prefCoord = aFrame->GetPrefWidth(aRenderingContext);
     } else {
         minCoord = 0;
         prefCoord = 0;
     }
     float prefPercent = 0.0f;
     bool hasSpecifiedWidth = false;
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -71,16 +71,17 @@
 #include "nsAutoPtr.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsStyleSet.h"
 #include "nsDisplayList.h"
 #include "nsIScrollableFrame.h"
 #include "nsCSSProps.h"
 
 using namespace mozilla;
+using namespace mozilla::layout;
 
 /********************************************************************************
  ** nsTableReflowState                                                         **
  ********************************************************************************/
 
 struct nsTableReflowState {
 
   // the real reflow state
@@ -1507,28 +1508,36 @@ nsTableFrame::ComputeSize(nsRenderingCon
                           nsSize aCBSize, nscoord aAvailableWidth,
                           nsSize aMargin, nsSize aBorder, nsSize aPadding,
                           bool aShrinkWrap)
 {
   nsSize result =
     nsContainerFrame::ComputeSize(aRenderingContext, aCBSize, aAvailableWidth,
                                   aMargin, aBorder, aPadding, aShrinkWrap);
 
+  // If we're a container for font size inflation, then shrink
+  // wrapping inside of us should not apply font size inflation.
+  AutoMaybeNullInflationContainer an(this);
+
   // Tables never shrink below their min width.
   nscoord minWidth = GetMinWidth(aRenderingContext);
   if (minWidth > result.width)
     result.width = minWidth;
 
   return result;
 }
 
 nscoord
 nsTableFrame::TableShrinkWidthToFit(nsRenderingContext *aRenderingContext,
                                     nscoord aWidthInCB)
 {
+  // If we're a container for font size inflation, then shrink
+  // wrapping inside of us should not apply font size inflation.
+  AutoMaybeNullInflationContainer an(this);
+
   nscoord result;
   nscoord minWidth = GetMinWidth(aRenderingContext);
   if (minWidth > aWidthInCB) {
     result = minWidth;
   } else {
     // Tables shrink width to fit with a slightly different algorithm
     // from the one they use for their intrinsic widths (the difference
     // relates to handling of percentage widths on columns).  So this
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -49,16 +49,19 @@
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 #include "nsIServiceManager.h"
 #include "nsIDOMNode.h"
 #include "nsDisplayList.h"
 #include "nsLayoutUtils.h"
 
+using namespace mozilla;
+using namespace mozilla::layout;
+
 /* ----------- nsTableCaptionFrame ---------- */
 
 #define NS_TABLE_FRAME_CAPTION_LIST_INDEX 1
 #define NO_SIDE 100
 
 // caption frame
 nsTableCaptionFrame::nsTableCaptionFrame(nsStyleContext* aContext):
   nsBlockFrame(aContext)
@@ -92,16 +95,21 @@ nsTableOuterFrame::GetBaseline() const
 /* virtual */ nsSize
 nsTableCaptionFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                      nsSize aCBSize, nscoord aAvailableWidth,
                                      nsSize aMargin, nsSize aBorder,
                                      nsSize aPadding, bool aShrinkWrap)
 {
   nsSize result = nsBlockFrame::ComputeAutoSize(aRenderingContext, aCBSize,
                     aAvailableWidth, aMargin, aBorder, aPadding, aShrinkWrap);
+
+  // If we're a container for font size inflation, then shrink
+  // wrapping inside of us should not apply font size inflation.
+  AutoMaybeNullInflationContainer an(this);
+
   PRUint8 captionSide = GetStyleTableBorder()->mCaptionSide;
   if (captionSide == NS_STYLE_CAPTION_SIDE_LEFT ||
       captionSide == NS_STYLE_CAPTION_SIDE_RIGHT) {
     result.width = GetMinWidth(aRenderingContext);
   } else if (captionSide == NS_STYLE_CAPTION_SIDE_TOP ||
              captionSide == NS_STYLE_CAPTION_SIDE_BOTTOM) {
     // The outer frame constrains our available width to the width of
     // the table.  Grow if our min-width is bigger than that, but not