Bail out of gfxFont::Draw if setting up the Cairo font fails.
b=390476 r+sr=pavlov a19=pavlov
--- 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, ¤tCTM);
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, ¤tCTM, 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;