Bail out of gfxFont::Draw if setting up the Cairo font fails. b=390476 r+sr=pavlov a19=pavlov
authormats.palmgren@bredband.net
Mon, 06 Aug 2007 05:30:13 -0700
changeset 4304 d8e588aa488ce5e6de133e7168c8567004d7b7c7
parent 4303 b03016c98bb6dcf46fa48b19871bf4e2187fdeb3
child 4305 9119e2dc0aea7349896706f53e30edfd6276a297
push idunknown
push userunknown
push dateunknown
bugs390476
milestone1.9a8pre
Bail out of gfxFont::Draw if setting up the Cairo font fails. b=390476 r+sr=pavlov a19=pavlov
gfx/thebes/public/gfxAtsuiFonts.h
gfx/thebes/public/gfxFont.h
gfx/thebes/public/gfxOS2Fonts.h
gfx/thebes/public/gfxPangoFonts.h
gfx/thebes/public/gfxWindowsFonts.h
gfx/thebes/src/gfxAtsuiFonts.cpp
gfx/thebes/src/gfxFont.cpp
gfx/thebes/src/gfxOS2Fonts.cpp
gfx/thebes/src/gfxPangoFonts.cpp
gfx/thebes/src/gfxWindowsFonts.cpp
--- a/gfx/thebes/public/gfxAtsuiFonts.h
+++ b/gfx/thebes/public/gfxAtsuiFonts.h
@@ -88,20 +88,17 @@ protected:
 
     gfxFont::Metrics mMetrics;
 
     gfxFloat mAdjustedSize;
     PRUint32 mSpaceGlyph;    
 
     void InitMetrics(ATSUFontID aFontID, ATSFontRef aFontRef);
 
-    virtual void SetupCairoFont(cairo_t *aCR)
-    {
-        cairo_set_scaled_font (aCR, CairoScaledFont());
-    }
+    virtual PRBool SetupCairoFont(cairo_t *aCR);
 };
 
 class THEBES_API gfxAtsuiFontGroup : public gfxFontGroup {
 public:
     gfxAtsuiFontGroup(const nsAString& families,
                       const gfxFontStyle *aStyle);
     virtual ~gfxAtsuiFontGroup();
 
--- a/gfx/thebes/public/gfxFont.h
+++ b/gfx/thebes/public/gfxFont.h
@@ -413,17 +413,17 @@ public:
 
 protected:
     // The family name of the font
     nsString          mName;
     nsExpirationState mExpirationState;
     gfxFontStyle      mStyle;
 
     // This is called by the default Draw() implementation above.
-    virtual void SetupCairoFont(cairo_t *aCR) = 0;
+    virtual PRBool SetupCairoFont(cairo_t *aCR) = 0;
 };
 
 class THEBES_API gfxTextRunFactory {
     THEBES_INLINE_DECL_REFCOUNTING(gfxTextRunFactory)
 
 public:
     // Flags in the mask 0xFFFF0000 are reserved for textrun clients
     // Flags in the mask 0x0000F000 are reserved for per-platform fonts
--- a/gfx/thebes/public/gfxOS2Fonts.h
+++ b/gfx/thebes/public/gfxOS2Fonts.h
@@ -67,17 +67,17 @@ public:
     virtual PRUint32 GetSpaceGlyph() {
         if (!mMetrics)
             GetMetrics();
         return mSpaceGlyph;
     }
 
 protected:
     gfxMatrix mCTM;
-    virtual void SetupCairoFont(cairo_t *aCR);
+    virtual PRBool SetupCairoFont(cairo_t *aCR);
 
 private:
     cairo_font_face_t *mFontFace;
     cairo_scaled_font_t *mScaledFont;
     Metrics *mMetrics;
     PRUint32 mSpaceGlyph;
 };
 
--- a/gfx/thebes/public/gfxPangoFonts.h
+++ b/gfx/thebes/public/gfxPangoFonts.h
@@ -106,17 +106,17 @@ protected:
     gfxFloat mAdjustedSize;
 
     void RealizeFont(PRBool force = PR_FALSE);
     void RealizeXftFont(PRBool force = PR_FALSE);
     void RealizePangoFont(PRBool aForce = PR_FALSE);
     void GetCharSize(const char aChar, gfxSize& aInkSize, gfxSize& aLogSize,
                      PRUint32 *aGlyphID = nsnull);
 
-    virtual void SetupCairoFont(cairo_t *aCR);
+    virtual PRBool SetupCairoFont(cairo_t *aCR);
 };
 
 class FontSelector;
 
 class THEBES_API gfxPangoFontGroup : public gfxFontGroup {
 public:
     gfxPangoFontGroup (const nsAString& families,
                        const gfxFontStyle *aStyle);
--- a/gfx/thebes/public/gfxWindowsFonts.h
+++ b/gfx/thebes/public/gfxWindowsFonts.h
@@ -528,17 +528,17 @@ private:
     cairo_scaled_font_t *mScaledFont;
 
     gfxFont::Metrics *mMetrics;
 
     LOGFONTW mLogFont;
 
     nsRefPtr<FontEntry> mFontEntry;
     
-    virtual void SetupCairoFont(cairo_t *aCR);
+    virtual PRBool SetupCairoFont(cairo_t *aCR);
 };
 
 /**********************************************************************
  *
  * class gfxWindowsFontGroup
  *
  **********************************************************************/
 
--- a/gfx/thebes/src/gfxAtsuiFonts.cpp
+++ b/gfx/thebes/src/gfxAtsuiFonts.cpp
@@ -218,16 +218,27 @@ gfxAtsuiFont::InitMetrics(ATSUFontID aFo
     fprintf (stderr, "    emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
     fprintf (stderr, "    maxAscent: %f maxDescent: %f maxAdvance: %f\n", mMetrics.maxAscent, mMetrics.maxDescent, mMetrics.maxAdvance);
     fprintf (stderr, "    internalLeading: %f externalLeading: %f\n", mMetrics.externalLeading, mMetrics.internalLeading);
     fprintf (stderr, "    spaceWidth: %f aveCharWidth: %f xHeight: %f\n", mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.xHeight);
     fprintf (stderr, "    uOff: %f uSize: %f stOff: %f stSize: %f suOff: %f suSize: %f\n", mMetrics.underlineOffset, mMetrics.underlineSize, mMetrics.strikeoutOffset, mMetrics.strikeoutSize, mMetrics.superscriptOffset, mMetrics.subscriptOffset);
 #endif
 }
 
+PRBool
+gfxAtsuiFont::SetupCairoFont(cairo_t *aCR)
+{
+    cairo_scaled_font_t *scaledFont = CairoScaledFont();
+    if (NS_LIKELY(scaledFont)) {
+        cairo_set_scaled_font(aCR, scaledFont);
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+}
+
 nsString
 gfxAtsuiFont::GetUniqueName()
 {
     return mName;
 }
 
 float
 gfxAtsuiFont::GetCharWidth(PRUnichar c, PRUint32 *aGlyphID)
--- a/gfx/thebes/src/gfxFont.cpp
+++ b/gfx/thebes/src/gfxFont.cpp
@@ -208,20 +208,20 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUi
     const double devUnitsPerAppUnit = 1.0/double(appUnitsPerDevUnit);
     PRBool isRTL = aTextRun->IsRightToLeft();
     double direction = aTextRun->GetDirection();
     PRUint32 i;
     // Current position in appunits
     double x = aPt->x;
     double y = aPt->y;
 
-    NS_ASSERTION(appUnitsPerDevUnit != 0, "Invalid app unit scale");
-
     cairo_t *cr = aContext->GetCairo();
-    SetupCairoFont(cr);
+    PRBool success = SetupCairoFont(cr);
+    if (NS_UNLIKELY(!success))
+        return;
 
     GlyphBuffer glyphs;
     cairo_glyph_t *glyph;
     
     if (aSpacing) {
         x += direction*aSpacing[0].mBefore;
     }
     for (i = aStart; i < aEnd; ++i) {
@@ -674,16 +674,17 @@ AccountStorageForTextRun(gfxTextRun *aTe
 
 gfxTextRun::gfxTextRun(const gfxTextRunFactory::Parameters *aParams, const void *aText,
                        PRUint32 aLength, gfxFontGroup *aFontGroup, PRUint32 aFlags)
   : mUserData(aParams->mUserData),
     mFontGroup(aFontGroup),
     mAppUnitsPerDevUnit(aParams->mAppUnitsPerDevUnit),
     mFlags(aFlags), mCharacterCount(aLength), mHashCode(0)
 {
+    NS_ASSERTION(mAppUnitsPerDevUnit != 0, "Invalid app unit scale");
     MOZ_COUNT_CTOR(gfxTextRun);
     NS_ADDREF(mFontGroup);
     if (aParams->mSkipChars) {
         mSkipChars.TakeFrom(aParams->mSkipChars);
     }
     if (aLength > 0) {
         mCharacterGlyphs = new CompressedGlyph[aLength];
         if (mCharacterGlyphs) {
--- a/gfx/thebes/src/gfxOS2Fonts.cpp
+++ b/gfx/thebes/src/gfxOS2Fonts.cpp
@@ -332,26 +332,31 @@ nsString gfxOS2Font::GetUniqueName()
     printf("gfxOS2Font::GetUniqueName()=%s\n", (char *)mName.get());
 #endif
     // gfxFont::mName should already be unique enough
     // Atsui uses that, too, while Win appends size, and properties...
     // doesn't seem to get called at all anyway
     return mName;
 }
 
-void gfxOS2Font::SetupCairoFont(cairo_t *aCR)
+PRBool gfxOS2Font::SetupCairoFont(cairo_t *aCR)
 {
 #ifdef DEBUG_thebes_2
     printf("gfxOS2Font[%#x]::SetupCairoFont(%#x)\n",
            (unsigned)this, (unsigned) aCR);
 #endif
     // gfxPangoFont checks the CTM but Windows doesn't so leave away here, too
 
     // this implicitely ensures that mScaledFont is created if NULL
-    cairo_set_scaled_font(aCR, CairoScaledFont());
+    cairo_scaled_font_t *scaledFont = CairoScaledFont();
+    if (NS_LIKELY(scaledFont)) {
+        cairo_set_scaled_font(aCR, scaledFont);
+        return PR_TRUE;
+    }
+    return PR_FALSE;
 }
 
 /**********************************************************************
  * class gfxOS2FontGroup
  **********************************************************************/
 gfxOS2FontGroup::gfxOS2FontGroup(const nsAString& aFamilies,
                                  const gfxFontStyle* aStyle)
     : gfxFontGroup(aFamilies, aStyle)
--- a/gfx/thebes/src/gfxPangoFonts.cpp
+++ b/gfx/thebes/src/gfxPangoFonts.cpp
@@ -909,38 +909,42 @@ CreateScaledFont(cairo_t *aCR, cairo_mat
     cairo_get_font_options(aCR, fontOptions);
     cairo_scaled_font_t *scaledFont =
         cairo_scaled_font_create(face, &fontMatrix, aCTM, fontOptions);
     cairo_font_options_destroy(fontOptions);
     cairo_font_face_destroy(face);
     return scaledFont;
 }
 
-void
+PRBool
 gfxPangoFont::SetupCairoFont(cairo_t *aCR)
 {
     cairo_matrix_t currentCTM;
     cairo_get_matrix(aCR, &currentCTM);
 
     if (mCairoFont) {
         // Need to validate that its CTM is OK
         cairo_matrix_t fontCTM;
         cairo_scaled_font_get_ctm(mCairoFont, &fontCTM);
         if (fontCTM.xx == currentCTM.xx && fontCTM.yy == currentCTM.yy &&
             fontCTM.xy == currentCTM.xy && fontCTM.yx == currentCTM.yx) {
             cairo_set_scaled_font(aCR, mCairoFont);
-            return;
+            return PR_TRUE;
         }
 
         // Just recreate it from scratch, simplest way
         cairo_scaled_font_destroy(mCairoFont);
     }
 
     mCairoFont = CreateScaledFont(aCR, &currentCTM, GetPangoFont());
-    cairo_set_scaled_font(aCR, mCairoFont);
+    if (NS_LIKELY(mCairoFont)) {
+        cairo_set_scaled_font(aCR, mCairoFont);
+        return PR_TRUE;
+    }
+    return PR_FALSE;
 }
 
 static void
 SetupClusterBoundaries(gfxTextRun* aTextRun, const gchar *aUTF8, PRUint32 aUTF8Length,
                        PRUint32 aUTF16Offset, PangoAnalysis *aAnalysis)
 {
     if (aTextRun->GetFlags() & gfxTextRunFactory::TEXT_IS_8BIT) {
         // 8-bit text doesn't have clusters.
--- a/gfx/thebes/src/gfxWindowsFonts.cpp
+++ b/gfx/thebes/src/gfxWindowsFonts.cpp
@@ -154,17 +154,18 @@ gfxWindowsFont::CairoScaledFont()
         cairo_matrix_init_identity(&identityMatrix);
 
         cairo_font_options_t *fontOptions = cairo_font_options_create();
         mScaledFont = cairo_scaled_font_create(CairoFontFace(), &sizeMatrix,
                                                &identityMatrix, fontOptions);
         cairo_font_options_destroy(fontOptions);
     }
 
-    NS_ASSERTION(mScaledFont, "Failed to make scaled font");
+    NS_ASSERTION(mScaledFont || mAdjustedSize == 0.0,
+                 "Failed to make scaled font");
 
     return mScaledFont;
 }
 
 HFONT
 gfxWindowsFont::MakeHFONT()
 {
     if (mFont)
@@ -409,20 +410,25 @@ gfxWindowsFont::Draw(gfxTextRun *aTextRu
                      gfxContext *aContext, PRBool aDrawToPath, gfxPoint *aBaselineOrigin,
                      Spacing *aSpacing)
 {
     // XXX stuart may want us to do something faster here
     gfxFont::Draw(aTextRun, aStart, aEnd, aContext, aDrawToPath, aBaselineOrigin,
                   aSpacing);
 }
 
-void
+PRBool
 gfxWindowsFont::SetupCairoFont(cairo_t *aCR)
 {
-    cairo_set_scaled_font(aCR, CairoScaledFont());
+    cairo_scaled_font_t *scaledFont = CairoScaledFont();
+    if (NS_LIKELY(scaledFont)) {
+        cairo_set_scaled_font(aCR, scaledFont);
+        return PR_TRUE;
+    }
+    return PR_FALSE;
 }
 
 /**********************************************************************
  *
  * class gfxWindowsFontGroup
  *
  **********************************************************************/
 
@@ -1100,35 +1106,38 @@ public:
             }
             ++offset;
         }
     }
 
     void SetCurrentFont(gfxWindowsFont *aFont) {
         if (mCurrentFont != aFont) {
             mCurrentFont = aFont;
-            cairo_win32_scaled_font_done_font(mCurrentFont->CairoScaledFont());
+            cairo_scaled_font_t *scaledFont = mCurrentFont->CairoScaledFont();
+            if (scaledFont)
+                cairo_win32_scaled_font_done_font(scaledFont);
             mFontSelected = PR_FALSE;
         }
     }
 
     gfxWindowsFont *GetCurrentFont() {
         return mCurrentFont;
     }
 
     void SelectFont() {
         if (mFontSelected)
             return;
 
         cairo_t *cr = mContext->GetCairo();
 
         cairo_set_font_face(cr, mCurrentFont->CairoFontFace());
         cairo_set_font_size(cr, mCurrentFont->GetAdjustedSize());
-
-        cairo_win32_scaled_font_select_font(mCurrentFont->CairoScaledFont(), mDC);
+        cairo_scaled_font_t *scaledFont = mCurrentFont->CairoScaledFont();
+        if (scaledFont)
+            cairo_win32_scaled_font_select_font(scaledFont, mDC);
 
         mFontSelected = PR_TRUE;
     }
 
     struct TextRange {
         TextRange(PRUint32 aStart,  PRUint32 aEnd) : start(aStart), end(aEnd) { }
         PRUint32 Length() const { return end - start; }
         nsRefPtr<FontEntry> font;