diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index 9df6ac97ebe4..f502c09f6def 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -84,8 +84,7 @@ gfxDWriteFont::gfxDWriteFont(const RefPtr& aUnscaledFont, mMetrics(nullptr), mUseSubpixelPositions(false), mAllowManualShowGlyphs(true), - mAzureScaledFontUsedClearType(false), - mAzureScaledFontForcedGDI(false) { + mAzureScaledFontUsedClearType(false) { // If the IDWriteFontFace1 interface is available, we can use that for // faster glyph width retrieval. mFontFace->QueryInterface(__uuidof(IDWriteFontFace1), @@ -754,12 +753,14 @@ void gfxDWriteFont::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, already_AddRefed gfxDWriteFont::GetScaledFont( const TextRunDrawParams& aRunParams) { - bool forceGDI = aRunParams.allowGDI && GetForceGDIClassic(); - if (mAzureScaledFontUsedClearType != UsingClearType() || - mAzureScaledFontForcedGDI != forceGDI) { + if (mAzureScaledFontUsedClearType != UsingClearType()) { mAzureScaledFont = nullptr; + mAzureScaledFontGDI = nullptr; } - if (!mAzureScaledFont) { + bool forceGDI = aRunParams.allowGDI && GetForceGDIClassic(); + RefPtr& azureScaledFont = + forceGDI ? mAzureScaledFontGDI : mAzureScaledFont; + if (!azureScaledFont) { gfxDWriteFontEntry* fe = static_cast(mFontEntry.get()); bool useEmbeddedBitmap = (gfxVars::SystemTextRenderingMode() == DWRITE_RENDERING_MODE_DEFAULT || @@ -767,19 +768,17 @@ already_AddRefed gfxDWriteFont::GetScaledFont( fe->IsCJKFont() && HasBitmapStrikeForSize(NS_lround(mAdjustedSize)); const gfxFontStyle* fontStyle = GetStyle(); - mAzureScaledFont = Factory::CreateScaledFontForDWriteFont( + azureScaledFont = Factory::CreateScaledFontForDWriteFont( mFontFace, fontStyle, GetUnscaledFont(), GetAdjustedSize(), useEmbeddedBitmap, forceGDI); - if (!mAzureScaledFont) { + if (!azureScaledFont) { return nullptr; } - InitializeScaledFont(); + InitializeScaledFont(azureScaledFont); mAzureScaledFontUsedClearType = UsingClearType(); - mAzureScaledFontForcedGDI = forceGDI; } - RefPtr scaledFont(mAzureScaledFont); - return scaledFont.forget(); + return do_AddRef(azureScaledFont); } bool gfxDWriteFont::ShouldRoundXOffset(cairo_t* aCairo) const { diff --git a/gfx/thebes/gfxDWriteFonts.h b/gfx/thebes/gfxDWriteFonts.h index 2964c35020e4..f5771dfff124 100644 --- a/gfx/thebes/gfxDWriteFonts.h +++ b/gfx/thebes/gfxDWriteFonts.h @@ -103,7 +103,11 @@ class gfxDWriteFont final : public gfxFont { // Used to record the sUseClearType setting at the time mAzureScaledFont // was set up, so we can tell if it's stale and needs to be re-created. bool mAzureScaledFontUsedClearType; - bool mAzureScaledFontForcedGDI; + + // Cache the GDI version of the ScaledFont so that font keys and other + // meta-data can remain stable even if there is thrashing between GDI and + // non-GDI usage. + RefPtr mAzureScaledFontGDI; bool UsingClearType() { return mozilla::gfx::gfxVars::SystemTextQuality() == CLEARTYPE_QUALITY; diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 79f89b397d30..8685523393e4 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -1552,14 +1552,15 @@ already_AddRefed gfxFont::GetScaledFont( return GetScaledFont(params); } -void gfxFont::InitializeScaledFont() { - if (!mAzureScaledFont) { +void gfxFont::InitializeScaledFont( + const RefPtr& aScaledFont) { + if (!aScaledFont) { return; } float angle = AngleForSyntheticOblique(); if (angle != 0.0f) { - mAzureScaledFont->SetSyntheticObliqueAngle(angle); + aScaledFont->SetSyntheticObliqueAngle(angle); } } diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 8cb407592590..b7c69586bb08 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1901,7 +1901,12 @@ class gfxFont { already_AddRefed GetScaledFont( mozilla::gfx::DrawTarget* aDrawTarget); - void InitializeScaledFont(); + // gfxFont implementations may cache ScaledFont versions other than the + // default, so InitializeScaledFont must support explicitly specifying + // other ScaledFonts than the default to initialize. + void InitializeScaledFont( + const RefPtr& aScaledFont); + void InitializeScaledFont() { InitializeScaledFont(mAzureScaledFont); } bool KerningDisabled() { return mKerningSet && !mKerningEnabled; }