Bug 476504 - handle errors in fetching font metrics. r=vlad
--- a/gfx/thebes/src/gfxAtsuiFonts.cpp
+++ b/gfx/thebes/src/gfxAtsuiFonts.cpp
@@ -90,17 +90,18 @@ OSStatus ATSClearGlyphVector(void *glyph
#endif
eFontPrefLang GetFontPrefLangFor(PRUint8 aUnicodeRange);
gfxAtsuiFont::gfxAtsuiFont(MacOSFontEntry *aFontEntry,
const gfxFontStyle *fontStyle, PRBool aNeedsBold)
: gfxFont(aFontEntry, fontStyle),
mFontStyle(fontStyle), mATSUStyle(nsnull),
- mHasMirroring(PR_FALSE), mHasMirroringLookedUp(PR_FALSE), mAdjustedSize(0.0f)
+ mHasMirroring(PR_FALSE), mHasMirroringLookedUp(PR_FALSE),
+ mFontFace(nsnull), mScaledFont(nsnull), mAdjustedSize(0.0f)
{
ATSUFontID fontID = aFontEntry->GetFontID();
ATSFontRef fontRef = FMGetATSFontRefFromFont(fontID);
// determine whether synthetic bolding is needed
PRInt8 baseWeight, weightDistance;
mFontStyle->ComputeWeightAndOffset(&baseWeight, &weightDistance);
PRUint16 targetWeight = (baseWeight * 100) + (weightDistance * 100);
@@ -111,16 +112,19 @@ gfxAtsuiFont::gfxAtsuiFont(MacOSFontEntr
// at the first bolder step beyond available faces, no matter how light the boldest face
if (!aFontEntry->IsBold()
&& ((weightDistance == 0 && targetWeight >= 600) || (weightDistance > 0 && aNeedsBold)))
{
mSyntheticBoldOffset = 1; // devunit offset when double-striking text to fake boldness
}
InitMetrics(fontID, fontRef);
+ if (!mIsValid) {
+ return;
+ }
mFontFace = cairo_quartz_font_face_create_for_atsu_font_id(fontID);
cairo_matrix_t sizeMatrix, ctm;
cairo_matrix_init_identity(&ctm);
cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
// synthetic oblique by skewing via the font matrix
@@ -261,18 +265,31 @@ gfxAtsuiFont::InitMetrics(ATSUFontID aFo
// we don't know where the line-breaks are at the time we're applying shaping,
// and it would be bad to put words with line-end swashes into the text-run
// cache until we have a way to distinguish them from mid-line occurrences.
DisableUncommonLigaturesAndLineBoundarySwashes(mATSUStyle);
/* Now pull out the metrics */
ATSFontMetrics atsMetrics;
- ATSFontGetHorizontalMetrics(aFontRef, kATSOptionFlagsDefault,
+ OSStatus err;
+
+ err = ATSFontGetHorizontalMetrics(aFontRef, kATSOptionFlagsDefault,
&atsMetrics);
+
+ if (err != noErr) {
+ mIsValid = PR_FALSE;
+
+#ifdef DEBUG
+ char warnBuf[1024];
+ sprintf(warnBuf, "Bad font metrics for: %s err: %8.8x", NS_ConvertUTF16toUTF8(GetName()).get(), PRUint32(err));
+ NS_WARNING(warnBuf);
+#endif
+ return;
+ }
if (atsMetrics.xHeight)
mMetrics.xHeight = atsMetrics.xHeight * size;
else
mMetrics.xHeight = GetCharHeight('x');
if (mAdjustedSize == 0.0f) {
if (mMetrics.xHeight != 0.0f && GetStyle()->sizeAdjust != 0.0f) {
@@ -416,20 +433,23 @@ gfxAtsuiFont::GetCharHeight(PRUnichar c)
ATSUDisposeTextLayout(layout);
return rect.bottom - rect.top;
}
gfxAtsuiFont::~gfxAtsuiFont()
{
- cairo_scaled_font_destroy(mScaledFont);
- cairo_font_face_destroy(mFontFace);
+ if (mScaledFont)
+ cairo_scaled_font_destroy(mScaledFont);
+ if (mFontFace)
+ cairo_font_face_destroy(mFontFace);
- ATSUDisposeStyle(mATSUStyle);
+ if (mATSUStyle)
+ ATSUDisposeStyle(mATSUStyle);
}
const gfxFont::Metrics&
gfxAtsuiFont::GetMetrics()
{
return mMetrics;
}