Add a font inflation data structure per block formatting context. (Bug 706193, patch 2) r=roc
authorL. David Baron <dbaron@dbaron.org>
Mon, 16 Apr 2012 15:32:12 -0700
changeset 91791 9499f6b28addcbcd9c480eb80cfe6c4c63a4a3a1
parent 91790 30dce13b71d0d9099553b71c8b6feffc561c5e0f
child 91792 9cf58850cf26befc69b189d831ae6d8e5bff8a7d
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersroc
bugs706193
milestone14.0a1
Add a font inflation data structure per block formatting context. (Bug 706193, patch 2) r=roc This structure is per block formatting context because we have to make a single inflation decision for things like consecutive runs of paragraphs of text. Inflating some paragraphs and not others (within the same sequence of adjacent paragraphs) based on the amount of text in each one would be disastrous. Otherwise it's ideal for the units to be as small as possible as long as they merge such sequences; therefore this uses a definition corresponding to CSS's idea of elements that establish new block formatting contexts.
layout/generic/Makefile.in
layout/generic/nsBlockFrame.cpp
layout/generic/nsFontInflationData.cpp
layout/generic/nsFontInflationData.h
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsIFrame.h
layout/svg/base/src/nsSVGForeignObjectFrame.cpp
layout/svg/base/src/nsSVGOuterSVGFrame.cpp
layout/tables/nsTableCellFrame.cpp
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsLeafBoxFrame.cpp
--- a/layout/generic/Makefile.in
+++ b/layout/generic/Makefile.in
@@ -82,16 +82,17 @@ CPPSRCS		= \
 		nsBlockFrame.cpp \
 		nsBlockReflowContext.cpp \
 		nsBlockReflowState.cpp \
 		nsBulletFrame.cpp \
 		nsColumnSetFrame.cpp \
 		nsContainerFrame.cpp \
 		nsFirstLetterFrame.cpp \
 		nsFloatManager.cpp \
+		nsFontInflationData.cpp \
 		nsFrame.cpp \
 		nsFrameList.cpp \
 		nsFrameSetFrame.cpp \
 		nsFrameUtil.cpp \
 		nsGfxScrollFrame.cpp \
 		nsHTMLCanvasFrame.cpp \
 		nsCanvasFrame.cpp \
 		nsHTMLReflowMetrics.cpp \
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6505,16 +6505,22 @@ nsBlockFrame::Init(nsIContent*      aCon
   }
 
   nsresult rv = nsBlockFrameSuper::Init(aContent, aParent, aPrevInFlow);
 
   if (!aPrevInFlow ||
       aPrevInFlow->GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION)
     AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
 
+  if ((GetStateBits() &
+       (NS_FRAME_FONT_INFLATION_CONTAINER | NS_BLOCK_FLOAT_MGR)) ==
+      (NS_FRAME_FONT_INFLATION_CONTAINER | NS_BLOCK_FLOAT_MGR)) {
+    AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
+  }
+
   return rv;
 }
 
 NS_IMETHODIMP
 nsBlockFrame::SetInitialChildList(ChildListID     aListID,
                                   nsFrameList&    aChildList)
 {
   NS_ASSERTION(aListID != kPrincipalList ||
new file mode 100644
--- /dev/null
+++ b/layout/generic/nsFontInflationData.cpp
@@ -0,0 +1,61 @@
+/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the font size inflation manager.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
+
+#include "nsFontInflationData.h"
+#include "FramePropertyTable.h"
+
+using namespace mozilla;
+
+static void
+DestroyFontInflationData(void *aPropertyValue)
+{
+  delete static_cast<nsFontInflationData*>(aPropertyValue);
+}
+
+NS_DECLARE_FRAME_PROPERTY(FontInflationDataProperty, DestroyFontInflationData);
+
+/* static */ nsFontInflationData*
+nsFontInflationData::FindFontInflationDataFor(const nsIFrame *aFrame)
+{
+  // We have one set of font inflation data per block formatting context.
+  const nsIFrame *bfc = FlowRootFor(aFrame);
+
+  return static_cast<nsFontInflationData*>(
+             bfc->Properties().Get(FontInflationDataProperty()));
+}
new file mode 100644
--- /dev/null
+++ b/layout/generic/nsFontInflationData.h
@@ -0,0 +1,65 @@
+/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the font size inflation manager.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
+
+#ifndef nsFontInflationData_h_
+#define nsFontInflationData_h_
+
+#include "nsIFrame.h"
+#include "nsLayoutUtils.h"
+#include "nsBlockFrame.h"
+
+class nsFontInflationData
+{
+public:
+
+  static nsFontInflationData* FindFontInflationDataFor(const nsIFrame *aFrame);
+
+private:
+
+  static const nsIFrame* FlowRootFor(const nsIFrame *aFrame)
+  {
+    while (!(aFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT)) {
+      aFrame = aFrame->GetParent();
+    }
+    return aFrame;
+  }
+
+};
+
+#endif /* !defined(nsFontInflationData_h_) */
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -116,16 +116,17 @@
 #include "nsBlockFrame.h"
 #include "nsDisplayList.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsExpirationTracker.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGEffects.h"
 #include "nsChangeHint.h"
 #include "nsDeckFrame.h"
+#include "nsTableFrame.h"
 
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
 #include "CSSCalc.h"
 #include "nsAbsoluteContainingBlock.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
@@ -531,18 +532,26 @@ nsFrame::Init(nsIContent*      aContent,
   if (nsLayoutUtils::FontSizeInflationEnabled(PresContext())
 #ifdef DEBUG
       // We have assertions that check inflation invariants even when
       // font size inflation is not enabled.
       || true
 #endif
       ) {
     if (IsFontSizeInflationContainer(this, disp)) {
-      mState |= NS_FRAME_FONT_INFLATION_CONTAINER;
-    }
+      AddStateBits(NS_FRAME_FONT_INFLATION_CONTAINER);
+      if (!GetParent() ||
+          // I'd use NS_FRAME_OUT_OF_FLOW, but it's not set yet.
+          disp->IsFloating() || disp->IsAbsolutelyPositioned()) {
+        AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
+      }
+    }
+    NS_ASSERTION(GetParent() ||
+                 (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER),
+                 "root frame should always be a container");
   }
 
   DidSetStyleContext(nsnull);
 
   if (IsBoxWrapped())
     InitBoxMetrics(false);
 
   return NS_OK;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -123,16 +123,26 @@ void
 nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   mInner.Destroy();
   DestroyAbsoluteFrames(aDestructRoot);
   nsContainerFrame::DestroyFrom(aDestructRoot);
 }
 
 NS_IMETHODIMP
+nsHTMLScrollFrame::Init(nsIContent* aContent,
+                        nsIFrame*   aParent,
+                        nsIFrame*   aPrevInFlow)
+{
+  nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
+  mInner.Init();
+  return rv;
+}
+
+NS_IMETHODIMP
 nsHTMLScrollFrame::SetInitialChildList(ChildListID  aListID,
                                        nsFrameList& aChildList)
 {
   nsresult rv = nsContainerFrame::SetInitialChildList(aListID, aChildList);
   mInner.ReloadChildFrames();
   return rv;
 }
 
@@ -1058,16 +1068,26 @@ nsXULScrollFrame::AppendAnonymousContent
 void
 nsXULScrollFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   mInner.Destroy();
   nsBoxFrame::DestroyFrom(aDestructRoot);
 }
 
 NS_IMETHODIMP
+nsXULScrollFrame::Init(nsIContent* aContent,
+                       nsIFrame*   aParent,
+                       nsIFrame*   aPrevInFlow)
+{
+  nsresult rv = nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
+  mInner.Init();
+  return rv;
+}
+
+NS_IMETHODIMP
 nsXULScrollFrame::SetInitialChildList(ChildListID     aListID,
                                       nsFrameList&    aChildList)
 {
   nsresult rv = nsBoxFrame::SetInitialChildList(aListID, aChildList);
   mInner.ReloadChildFrames();
   return rv;
 }
 
@@ -1599,16 +1619,24 @@ nsGfxScrollFrameInner::~nsGfxScrollFrame
   delete mAsyncScroll;
 
   if (mScrollActivityTimer) {
     mScrollActivityTimer->Cancel();
     mScrollActivityTimer = nsnull;
   }
 }
 
+void
+nsGfxScrollFrameInner::Init()
+{
+  if (mOuter->GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
+    mOuter->AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
+  }
+}
+
 static nscoord
 Clamp(nscoord aLower, nscoord aVal, nscoord aUpper)
 {
   if (aVal < aLower)
     return aLower;
   if (aVal > aUpper)
     return aUpper;
   return aVal;
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -72,16 +72,18 @@ struct ScrollReflowState;
 
 class nsGfxScrollFrameInner : public nsIReflowCallback {
 public:
   class AsyncScroll;
 
   nsGfxScrollFrameInner(nsContainerFrame* aOuter, bool aIsRoot);
   ~nsGfxScrollFrameInner();
 
+  void Init();
+
   typedef nsIScrollableFrame::ScrollbarStyles ScrollbarStyles;
   ScrollbarStyles GetScrollbarStylesFromFrame() const;
 
   // If a child frame was added or removed on the scrollframe,
   // reload our child frame list.
   // We need this if a scrollbar frame is recreated.
   void ReloadChildFrames();
 
@@ -365,16 +367,19 @@ class nsHTMLScrollFrame : public nsConta
 public:
   friend nsIFrame* NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot);
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // Called to set the child frames. We typically have three: the scroll area,
   // the vertical scrollbar, and the horizontal scrollbar.
+  NS_IMETHOD Init(nsIContent*      aContent,
+                  nsIFrame*        aParent,
+                  nsIFrame*        aPrevInFlow);
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists) {
     return mInner.BuildDisplayList(aBuilder, aDirtyRect, aLists);
   }
@@ -593,16 +598,19 @@ class nsXULScrollFrame : public nsBoxFra
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot);
 
   // Called to set the child frames. We typically have three: the scroll area,
   // the vertical scrollbar, and the horizontal scrollbar.
+  NS_IMETHOD Init(nsIContent*      aContent,
+                  nsIFrame*        aParent,
+                  nsIFrame*        aPrevInFlow);
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList);
 
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists) {
     return mInner.BuildDisplayList(aBuilder, aDirtyRect, aLists);
   }
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -301,16 +301,21 @@ typedef PRUint64 nsFrameState;
 // This is only set during painting
 #define NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO    NS_FRAME_STATE_BIT(40)
 
 // Is this frame a container for font size inflation, i.e., is it a
 // frame whose width is used to determine the inflation factor for
 // everything whose nearest ancestor container for this frame?
 #define NS_FRAME_FONT_INFLATION_CONTAINER           NS_FRAME_STATE_BIT(41)
 
+// Does this frame manage a region in which we do font size inflation,
+// i.e., roughly, is it an element establishing a new block formatting
+// context?
+#define NS_FRAME_FONT_INFLATION_FLOW_ROOT           NS_FRAME_STATE_BIT(42)
+
 // Box layout bits
 #define NS_STATE_IS_HORIZONTAL                      NS_FRAME_STATE_BIT(22)
 #define NS_STATE_IS_DIRECTION_NORMAL                NS_FRAME_STATE_BIT(31)
 
 // Helper macros
 #define NS_SUBTREE_DIRTY(_frame)  \
   (((_frame)->GetStateBits() &      \
     (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0)
--- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
@@ -48,16 +48,19 @@
 #include "nsLayoutUtils.h"
 #include "nsRegion.h"
 #include "nsRenderingContext.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGEffects.h"
 #include "nsSVGForeignObjectElement.h"
 #include "nsSVGOuterSVGFrame.h"
 #include "nsSVGUtils.h"
+#include "mozilla/AutoRestore.h"
+
+using namespace mozilla;
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsIFrame*
 NS_NewSVGForeignObjectFrame(nsIPresShell   *aPresShell,
                             nsStyleContext *aContext)
 {
@@ -88,16 +91,18 @@ nsSVGForeignObjectFrame::Init(nsIContent
 #ifdef DEBUG
   nsCOMPtr<nsIDOMSVGForeignObjectElement> foreignObject = do_QueryInterface(aContent);
   NS_ASSERTION(foreignObject, "Content is not an SVG foreignObject!");
 #endif
 
   nsresult rv = nsSVGForeignObjectFrameBase::Init(aContent, aParent, aPrevInFlow);
   AddStateBits(aParent->GetStateBits() &
                (NS_STATE_SVG_NONDISPLAY_CHILD | NS_STATE_SVG_CLIPPATH_CHILD));
+  AddStateBits(NS_FRAME_FONT_INFLATION_CONTAINER |
+               NS_FRAME_FONT_INFLATION_FLOW_ROOT);
   return rv;
 }
 
 nsIAtom *
 nsSVGForeignObjectFrame::GetType() const
 {
   return nsGkAtoms::svgForeignObjectFrame;
 }
@@ -570,16 +575,24 @@ nsSVGForeignObjectFrame::DoReflow()
   // initiate a synchronous reflow here and now:  
   nsIPresShell* presShell = presContext->PresShell();
   NS_ASSERTION(presShell, "null presShell");
   nsRefPtr<nsRenderingContext> renderingContext =
     presShell->GetReferenceRenderingContext();
   if (!renderingContext)
     return;
 
+  AutoRestore<nsIFrame*> restoreCurrentInflationContainer(
+    presContext->mCurrentInflationContainer);
+  AutoRestore<nscoord> restoreCurrentInflationContainerWidth(
+    presContext->mCurrentInflationContainerWidth);
+
+  presContext->mCurrentInflationContainer = this;
+  presContext->mCurrentInflationContainerWidth = mRect.width;
+
   mInReflow = true;
 
   nsHTMLReflowState reflowState(presContext, kid,
                                 renderingContext,
                                 nsSize(mRect.width, NS_UNCONSTRAINEDSIZE));
   nsHTMLReflowMetrics desiredSize;
   nsReflowStatus status;
 
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
@@ -153,17 +153,19 @@ nsSVGOuterSVGFrame::Init(nsIContent* aCo
                          nsIFrame* aParent,
                          nsIFrame* aPrevInFlow)
 {
 #ifdef DEBUG
   nsCOMPtr<nsIDOMSVGSVGElement> svgElement = do_QueryInterface(aContent);
   NS_ASSERTION(svgElement, "Content is not an SVG 'svg' element!");
 #endif
 
-  AddStateBits(NS_STATE_IS_OUTER_SVG);
+  AddStateBits(NS_STATE_IS_OUTER_SVG |
+               NS_FRAME_FONT_INFLATION_CONTAINER |
+               NS_FRAME_FONT_INFLATION_FLOW_ROOT);
 
   // Check for conditional processing attributes here rather than in
   // nsCSSFrameConstructor::FindSVGData because we want to avoid
   // simply giving failing outer <svg> elements an nsSVGContainerFrame.
   // We don't create other SVG frames if PassesConditionalProcessingTests
   // returns false, but since we do create nsSVGOuterSVGFrame frames we
   // prevent them from painting by [ab]use NS_STATE_SVG_NONDISPLAY_CHILD. The
   // frame will be recreated via an nsChangeHint_ReconstructFrame restyle if
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -102,16 +102,20 @@ nsTableCellFrame::GetNextCell() const
 NS_IMETHODIMP
 nsTableCellFrame::Init(nsIContent*      aContent,
                        nsIFrame*        aParent,
                        nsIFrame*        aPrevInFlow)
 {
   // Let the base class do its initialization
   nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
 
+  if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
+    AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
+  }
+
   if (aPrevInFlow) {
     // Set the column index
     nsTableCellFrame* cellFrame = (nsTableCellFrame*)aPrevInFlow;
     PRInt32           colIndex;
     cellFrame->GetColIndex(colIndex);
     SetColIndex(colIndex);
   }
 
--- a/layout/xul/base/src/nsBoxFrame.cpp
+++ b/layout/xul/base/src/nsBoxFrame.cpp
@@ -195,16 +195,20 @@ nsBoxFrame::DidSetStyleContext(nsStyleCo
 NS_IMETHODIMP
 nsBoxFrame::Init(nsIContent*      aContent,
                  nsIFrame*        aParent,
                  nsIFrame*        aPrevInFlow)
 {
   nsresult  rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
+    AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
+  }
+
   MarkIntrinsicWidthsDirty();
 
   CacheAttributes();
 
 #ifdef DEBUG_LAYOUT
     // if we are root and this
   if (mState & NS_STATE_IS_ROOT) 
       GetDebugPref(GetPresContext());
--- a/layout/xul/base/src/nsLeafBoxFrame.cpp
+++ b/layout/xul/base/src/nsLeafBoxFrame.cpp
@@ -90,16 +90,20 @@ NS_IMETHODIMP
 nsLeafBoxFrame::Init(
               nsIContent*      aContent,
               nsIFrame*        aParent,
               nsIFrame*        aPrevInFlow)
 {
   nsresult  rv = nsLeafFrame::Init(aContent, aParent, aPrevInFlow);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
+    AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
+  }
+
   UpdateMouseThrough();
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsLeafBoxFrame::AttributeChanged(PRInt32 aNameSpaceID,
                                  nsIAtom* aAttribute,