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 idunknown
push userunknown
push dateunknown
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