bug 617008 - avoid creating a rendering context that we may not need. r=roc
authorJonathan Kew <jkew@mozilla.com>
Mon, 31 Mar 2014 11:53:09 +0100
changeset 194702 670dc72450a8b1fceb88b1b551903802f8d4f210
parent 194701 09c556f22ff28db824b617226af37f1a06dd98a6
child 194703 7807eb5117413480bad9a3744b4e0d10297e9606
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs617008
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 617008 - avoid creating a rendering context that we may not need. r=roc
gfx/src/nsFontMetrics.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
layout/generic/nsTextFrame.cpp
--- a/gfx/src/nsFontMetrics.cpp
+++ b/gfx/src/nsFontMetrics.cpp
@@ -69,16 +69,24 @@ public:
     virtual int8_t GetHyphensOption() {
         NS_ERROR("This shouldn't be called because we never call BreakAndMeasureText");
         return NS_STYLE_HYPHENS_NONE;
     }
     virtual gfxFloat GetHyphenWidth() {
         NS_ERROR("This shouldn't be called because we never enable hyphens");
         return 0;
     }
+    virtual already_AddRefed<gfxContext> GetContext() {
+        NS_ERROR("This shouldn't be called because we never enable hyphens");
+        return nullptr;
+    }
+    virtual uint32_t GetAppUnitsPerDevUnit() {
+        NS_ERROR("This shouldn't be called because we never enable hyphens");
+        return 60;
+    }
     virtual void GetSpacing(uint32_t aStart, uint32_t aLength,
                             Spacing* aSpacing) {
         NS_ERROR("This shouldn't be called because we never enable spacing");
     }
 };
 
 } // anon namespace
 
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -4873,23 +4873,27 @@ gfxFontGroup::MakeHyphenTextRun(gfxConte
     }
 
     static const uint8_t dash = '-';
     return MakeTextRun(&dash, 1, aCtx, aAppUnitsPerDevUnit,
                        gfxFontGroup::TEXT_IS_PERSISTENT);
 }
 
 gfxFloat
-gfxFontGroup::GetHyphenWidth(gfxContext *aCtx, uint32_t aAppUnitsPerDevUnit)
+gfxFontGroup::GetHyphenWidth(gfxTextRun::PropertyProvider *aProvider)
 {
     if (mHyphenWidth < 0) {
-        nsAutoPtr<gfxTextRun> hyphRun(MakeHyphenTextRun(aCtx,
-                                                        aAppUnitsPerDevUnit));
-        mHyphenWidth = hyphRun.get() ?
-            hyphRun->GetAdvanceWidth(0, hyphRun->GetLength(), nullptr) : 0;
+        nsRefPtr<gfxContext> ctx(aProvider->GetContext());
+        if (ctx) {
+            nsAutoPtr<gfxTextRun>
+                hyphRun(MakeHyphenTextRun(ctx,
+                                          aProvider->GetAppUnitsPerDevUnit()));
+            mHyphenWidth = hyphRun.get() ?
+                hyphRun->GetAdvanceWidth(0, hyphRun->GetLength(), nullptr) : 0;
+        }
     }
     return mHyphenWidth;
 }
 
 gfxTextRun *
 gfxFontGroup::MakeTextRun(const uint8_t *aString, uint32_t aLength,
                           const Parameters *aParams, uint32_t aFlags)
 {
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -2829,16 +2829,24 @@ public:
         /**
          * Get the spacing around the indicated characters. Spacing must be zero
          * inside clusters. In other words, if character i is not
          * CLUSTER_START, then character i-1 must have zero after-spacing and
          * character i must have zero before-spacing.
          */
         virtual void GetSpacing(uint32_t aStart, uint32_t aLength,
                                 Spacing *aSpacing) = 0;
+
+        // Returns a gfxContext that can be used to measure the hyphen glyph.
+        // Only called if the hyphen width is requested.
+        virtual already_AddRefed<gfxContext> GetContext() = 0;
+
+        // Return the appUnitsPerDevUnit value to be used when measuring.
+        // Only called if the hyphen width is requested.
+        virtual uint32_t GetAppUnitsPerDevUnit() = 0;
     };
 
     class ClusterIterator {
     public:
         ClusterIterator(gfxTextRun *aTextRun);
 
         void Reset();
 
@@ -3428,17 +3436,17 @@ public:
     }
 
     /**
      * Get the (possibly-cached) width of the hyphen character.
      * The aCtx and aAppUnitsPerDevUnit parameters will be used only if
      * needed to initialize the cached hyphen width; otherwise they are
      * ignored.
      */
-    gfxFloat GetHyphenWidth(gfxContext *aCtx, uint32_t aAppUnitsPerDevUnit);
+    gfxFloat GetHyphenWidth(gfxTextRun::PropertyProvider* aProvider);
 
     /**
      * Make a text run representing a single hyphen character.
      * This will use U+2010 HYPHEN if available in the first font,
      * otherwise fall back to U+002D HYPHEN-MINUS.
      * The caller is responsible for deleting the returned text run
      * when no longer required.
      */
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -2834,16 +2834,24 @@ public:
   virtual void GetSpacing(uint32_t aStart, uint32_t aLength, Spacing* aSpacing);
   virtual gfxFloat GetHyphenWidth();
   virtual void GetHyphenationBreaks(uint32_t aStart, uint32_t aLength,
                                     bool* aBreakBefore);
   virtual int8_t GetHyphensOption() {
     return mTextStyle->mHyphens;
   }
 
+  virtual already_AddRefed<gfxContext> GetContext() {
+    return GetReferenceRenderingContext(GetFrame(), nullptr);
+  }
+
+  virtual uint32_t GetAppUnitsPerDevUnit() {
+    return mTextRun->GetAppUnitsPerDevUnit();
+  }
+
   void GetSpacingInternal(uint32_t aStart, uint32_t aLength, Spacing* aSpacing,
                           bool aIgnoreTabs);
 
   /**
    * Count the number of justifiable characters in the given DOM range
    */
   uint32_t ComputeJustifiableCharacters(int32_t aOffset, int32_t aLength);
   /**
@@ -3189,26 +3197,19 @@ PropertyProvider::CalcTabWidths(uint32_t
                                        aStart + aLength - startOffset);
   }
 }
 
 gfxFloat
 PropertyProvider::GetHyphenWidth()
 {
   if (mHyphenWidth < 0) {
-    mHyphenWidth = mLetterSpacing;
-    nsRefPtr<gfxContext> context(GetReferenceRenderingContext(GetFrame(),
-                                                              nullptr));
-    if (context) {
-      mHyphenWidth +=
-        GetFontGroup()->GetHyphenWidth(context,
-                                       mTextRun->GetAppUnitsPerDevUnit());
-    }
-  }
-  return mHyphenWidth;
+    mHyphenWidth = GetFontGroup()->GetHyphenWidth(this);
+  }
+  return mHyphenWidth + mLetterSpacing;
 }
 
 void
 PropertyProvider::GetHyphenationBreaks(uint32_t aStart, uint32_t aLength,
                                        bool* aBreakBefore)
 {
   NS_PRECONDITION(IsInBounds(mStart, mLength, aStart, aLength), "Range out of bounds");
   NS_PRECONDITION(mLength != INT32_MAX, "Can't call this with undefined length");