Bug 749186, Followup Patch 1: Cache font inflation settings in pres shell to prevent crash. [r=dbaron][a=blassey] THUNDERBIRD_14.0b1_BUILD1 THUNDERBIRD_14.0b1_RELEASE THUNDERBIRD_14_0b1_BUILD2 THUNDERBIRD_14_0b1_RELEASE
authorScott Johnson <sjohnson@mozilla.com>
Tue, 05 Jun 2012 23:28:21 -0500
changeset 95993 e835d6524759b89620f078a98e4f0dfb4d5862a2
parent 95992 23f3e1dfaa6c98dc670e93cc1566fa74ad238849
child 95994 7054a9e24f11f1bad0503a19588eb43d4900c849
child 95996 a1001cd8194bfae19cce4ec09c887c2f8ece9f30
child 95997 881db16090d6fdb84bd3d6457a667d2fe2d88008
push idunknown
push userunknown
push dateunknown
reviewersdbaron, blassey
bugs749186
milestone14.0
Bug 749186, Followup Patch 1: Cache font inflation settings in pres shell to prevent crash. [r=dbaron][a=blassey]
dom/base/nsDOMWindowUtils.cpp
layout/base/nsIPresShell.h
layout/base/nsLayoutUtils.cpp
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/generic/nsFontInflationData.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -284,40 +284,42 @@ static void DestroyNsRect(void* aObject,
 {
   nsRect* rect = static_cast<nsRect*>(aPropertyValue);
   delete rect;
 }
 
 static void
 MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
 {
-  if (aPresContext &&
-      nsLayoutUtils::FontSizeInflationEnabled(aPresContext) &&
-      nsLayoutUtils::FontSizeInflationMinTwips() != 0) {
-    bool changed;
-    aPresContext->ScreenWidthInchesForFontInflation(&changed);
-    if (changed) {
-      nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
-      nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
-      if (docShell) {
-        nsCOMPtr<nsIContentViewer> cv;
-        docShell->GetContentViewer(getter_AddRefs(cv));
-        nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
-        if (mudv) {
-          nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
-          mudv->AppendSubtree(array);
-          for (PRUint32 i = 0, iEnd = array.Length(); i < iEnd; ++i) {
-            nsCOMPtr<nsIPresShell> shell;
-            nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
-            cv->GetPresShell(getter_AddRefs(shell));
-            if (shell) {
-              nsIFrame *rootFrame = shell->GetRootFrame();
-              if (rootFrame) {
-                shell->FrameNeedsReflow(rootFrame, nsIPresShell::eResize,
-                                        NS_FRAME_IS_DIRTY);
+  if (aPresContext) {
+    nsIPresShell* presShell = aPresContext->GetPresShell();
+    if (presShell && nsLayoutUtils::FontSizeInflationEnabled(aPresContext) &&
+        presShell->FontSizeInflationMinTwips() != 0) {
+      bool changed;
+      aPresContext->ScreenWidthInchesForFontInflation(&changed);
+      if (changed) {
+        nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
+        nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
+        if (docShell) {
+          nsCOMPtr<nsIContentViewer> cv;
+          docShell->GetContentViewer(getter_AddRefs(cv));
+          nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
+          if (mudv) {
+            nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
+            mudv->AppendSubtree(array);
+            for (PRUint32 i = 0, iEnd = array.Length(); i < iEnd; ++i) {
+              nsCOMPtr<nsIPresShell> shell;
+              nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
+              cv->GetPresShell(getter_AddRefs(shell));
+              if (shell) {
+                nsIFrame *rootFrame = shell->GetRootFrame();
+                if (rootFrame) {
+                  shell->FrameNeedsReflow(rootFrame, nsIPresShell::eResize,
+                                          NS_FRAME_IS_DIRTY);
+                }
               }
             }
           }
         }
       }
     }
   }
 }
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1219,17 +1219,34 @@ public:
   virtual bool IsVisible() = 0;
   virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange) = 0;
 
   virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                    size_t *aArenasSize,
                                    size_t *aStyleSetsSize,
                                    size_t *aTextRunsSize) const = 0;
 
+
   /**
+   * Methods that retrieve the cached font inflation preferences.
+   */
+  PRUint32 FontSizeInflationEmPerLine() const {
+    return mFontSizeInflationEmPerLine;
+  }
+
+  PRUint32 FontSizeInflationMinTwips() const {
+    return mFontSizeInflationMinTwips;
+  }
+
+  PRUint32 FontSizeInflationLineThreshold() const {
+    return mFontSizeInflationLineThreshold;
+  }
+
+  /**
+   *
    * Refresh observer management.
    */
 protected:
   virtual bool AddRefreshObserverExternal(nsARefreshObserver* aObserver,
                                             mozFlushType aFlushType);
   bool AddRefreshObserverInternal(nsARefreshObserver* aObserver,
                                     mozFlushType aFlushType);
   virtual bool RemoveRefreshObserverExternal(nsARefreshObserver* aObserver,
@@ -1342,16 +1359,23 @@ protected:
   // Used to force allocation and rendering of proportionally more or
   // less pixels in the given dimension.
   float                     mXResolution;
   float                     mYResolution;
 
   nsSize                    mScrollPositionClampingScrollPortSize;
 
   static nsIContent* gKeyDownTarget;
+
+
+  // Cached font inflation values. This is done to prevent changing of font
+  // inflation until a page is reloaded.
+  PRUint32 mFontSizeInflationEmPerLine;
+  PRUint32 mFontSizeInflationMinTwips;
+  PRUint32 mFontSizeInflationLineThreshold;
 };
 
 /**
  * Create a new empty presentation shell. Upon success, call Init
  * before attempting to use the shell.
  */
 nsresult
 NS_NewPresShell(nsIPresShell** aInstancePtrResult);
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4646,18 +4646,20 @@ nsReflowFrameRunnable::Run()
 /**
  * Compute the minimum font size inside of a container with the given
  * width, such that **when the user zooms the container to fill the full
  * width of the device**, the fonts satisfy our minima.
  */
 static nscoord
 MinimumFontSizeFor(nsPresContext* aPresContext, nscoord aContainerWidth)
 {
-  PRUint32 emPerLine = nsLayoutUtils::FontSizeInflationEmPerLine();
-  PRUint32 minTwips = nsLayoutUtils::FontSizeInflationMinTwips();
+  nsIPresShell* presShell = aPresContext->PresShell();
+
+  PRUint32 emPerLine = presShell->FontSizeInflationEmPerLine();
+  PRUint32 minTwips = presShell->FontSizeInflationMinTwips();
   if (emPerLine == 0 && minTwips == 0) {
     return 0;
   }
 
   // Clamp the container width to the device dimensions
   nscoord iFrameWidth = aPresContext->GetVisibleArea().width;
   nscoord effectiveContainerWidth = NS_MIN(iFrameWidth, aContainerWidth);
 
@@ -4794,18 +4796,21 @@ nsLayoutUtils::FontSizeInflationFor(cons
   }
 
   return FontSizeInflationInner(aFrame, InflationMinFontSizeFor(aFrame));
 }
 
 /* static */ bool
 nsLayoutUtils::FontSizeInflationEnabled(nsPresContext *aPresContext)
 {
-  if ((sFontSizeInflationEmPerLine == 0 &&
-       sFontSizeInflationMinTwips == 0) ||
+  nsIPresShell* presShell = aPresContext->GetPresShell();
+
+  if (!presShell ||
+      (presShell->FontSizeInflationEmPerLine() == 0 &&
+       presShell->FontSizeInflationMinTwips() == 0) ||
        aPresContext->IsChrome()) {
     return false;
   }
 
   ViewportInfo vInf =
     nsContentUtils::GetViewportInfo(aPresContext->PresShell()->GetDocument());
 
   if (vInf.defaultZoom >= 1.0 || vInf.autoSize) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1015,16 +1015,19 @@ PresShell::Init(nsIDocument* aDocument,
   if (mDocument->HasAnimationController()) {
     nsSMILAnimationController* animCtrl = mDocument->GetAnimationController();
     animCtrl->NotifyRefreshDriverCreated(GetPresContext()->RefreshDriver());
   }
 
   // Get our activeness from the docShell.
   QueryIsActive();
 
+  // Setup our font inflation preferences.
+  SetupFontInflation();
+
   return NS_OK;
 }
 
 void
 PresShell::Destroy()
 {
   NS_TIME_FUNCTION_MIN(1.0);
 
@@ -9171,8 +9174,16 @@ PresShell::SizeOfTextRuns(nsMallocSizeOf
 
 void
 nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight)
 {
   mScrollPositionClampingScrollPortSizeSet = true;
   mScrollPositionClampingScrollPortSize.width = aWidth;
   mScrollPositionClampingScrollPortSize.height = aHeight;
 }
+
+void
+PresShell::SetupFontInflation()
+{
+  mFontSizeInflationEmPerLine = nsLayoutUtils::FontSizeInflationEmPerLine();
+  mFontSizeInflationMinTwips = nsLayoutUtils::FontSizeInflationMinTwips();
+  mFontSizeInflationLineThreshold = nsLayoutUtils::FontSizeInflationLineThreshold();
+}
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -492,16 +492,25 @@ protected:
 #endif
 
   // Helper for ScrollContentIntoView
   void DoScrollContentIntoView(nsIContent* aContent,
                                ScrollAxis  aVertical,
                                ScrollAxis  aHorizontal,
                                PRUint32    aFlags);
 
+  /**
+   * Initialize cached font inflation preference values.
+   *
+   * @see nsLayoutUtils::sFontSizeInflationEmPerLine
+   * @see nsLayoutUtils::sFontSizeInflationMinTwips
+   * @see nsLayoutUtils::sFontSizeInflationLineThreshold
+   */
+  void SetupFontInflation();
+
   friend struct AutoRenderingStateSaveRestore;
   friend struct RenderingState;
 
   struct RenderingState {
     RenderingState(PresShell* aPresShell) 
       : mRenderFlags(aPresShell->mRenderFlags)
       , mXResolution(aPresShell->mXResolution)
       , mYResolution(aPresShell->mYResolution)
--- a/layout/generic/nsFontInflationData.cpp
+++ b/layout/generic/nsFontInflationData.cpp
@@ -221,17 +221,18 @@ nsFontInflationData::UpdateWidth(const n
   while (!nsLayoutUtils::IsContainerForFontSizeInflation(nca)) {
     nca = nca->GetParent()->GetFirstInFlow();
   }
 
   nscoord newNCAWidth = ComputeDescendantWidth(aReflowState, nca);
 
   // See comment above "font.size.inflation.lineThreshold" in
   // modules/libpref/src/init/all.js .
-  PRUint32 lineThreshold = nsLayoutUtils::FontSizeInflationLineThreshold();
+  nsIPresShell* presShell = bfc->PresContext()->PresShell();
+  PRUint32 lineThreshold = presShell->FontSizeInflationLineThreshold();
   nscoord newTextThreshold = (newNCAWidth * lineThreshold) / 100;
 
   if (mTextThreshold <= mTextAmount && mTextAmount < newTextThreshold) {
     // Because we truncate our scan when we hit sufficient text, we now
     // need to rescan.
     mTextDirty = true;
   }