Bug 1362117 - keep NativeFontResourceFontconfig alive while its associated cairo_font_face_t is alive. r=jrmuizel

MozReview-Commit-ID: HxeOQPTP6WL
This commit is contained in:
Lee Salzman 2017-05-04 14:05:01 -04:00
Родитель 34a146fb9b
Коммит 744c16f40b
4 изменённых файлов: 39 добавлений и 4 удалений

Просмотреть файл

@ -53,7 +53,7 @@ already_AddRefed<UnscaledFont>
NativeFontResourceFontconfig::CreateUnscaledFont(uint32_t aIndex,
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
{
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontFontconfig(mFace);
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontFontconfig(mFace, this);
return unscaledFont.forget();
}

Просмотреть файл

@ -242,13 +242,23 @@ UnscaledFontFontconfig::CreateScaledFont(Float aGlyphSize,
}
const ScaledFontFontconfig::InstanceData *instanceData =
reinterpret_cast<const ScaledFontFontconfig::InstanceData*>(aInstanceData);
return ScaledFontFontconfig::CreateFromInstanceData(*instanceData, this, aGlyphSize);
return ScaledFontFontconfig::CreateFromInstanceData(*instanceData, this, aGlyphSize,
mNativeFontResource.get());
}
static cairo_user_data_key_t sNativeFontResourceKey;
static void
ReleaseNativeFontResource(void* aData)
{
static_cast<NativeFontResource*>(aData)->Release();
}
already_AddRefed<ScaledFont>
ScaledFontFontconfig::CreateFromInstanceData(const InstanceData& aInstanceData,
UnscaledFontFontconfig* aUnscaledFont,
Float aSize)
Float aSize,
NativeFontResource* aNativeFontResource)
{
FcPattern* pattern = FcPatternCreate();
if (!pattern) {
@ -271,6 +281,22 @@ ScaledFontFontconfig::CreateFromInstanceData(const InstanceData& aInstanceData,
return nullptr;
}
if (aNativeFontResource) {
// Bug 1362117 - Cairo may keep the font face alive after the owning NativeFontResource
// was freed. To prevent this, we must bind the NativeFontResource to the font face so that
// it stays alive at least as long as the font face.
if (cairo_font_face_set_user_data(font,
&sNativeFontResourceKey,
aNativeFontResource,
ReleaseNativeFontResource) != CAIRO_STATUS_SUCCESS) {
gfxWarning() << "Failed binding NativeFontResource to Cairo font face";
cairo_font_face_destroy(font);
FcPatternDestroy(pattern);
return nullptr;
}
aNativeFontResource->AddRef();
}
cairo_matrix_t sizeMatrix;
aInstanceData.SetupFontMatrix(&sizeMatrix);

Просмотреть файл

@ -66,7 +66,8 @@ private:
static already_AddRefed<ScaledFont>
CreateFromInstanceData(const InstanceData& aInstanceData,
UnscaledFontFontconfig* aUnscaledFont,
Float aSize);
Float aSize,
NativeFontResource* aNativeFontResource = nullptr);
FcPattern* mPattern;
};

Просмотреть файл

@ -73,6 +73,11 @@ public:
uint32_t aIndex = 0)
: UnscaledFontFreeType(aFile, aIndex)
{}
UnscaledFontFontconfig(FT_Face aFace,
NativeFontResource* aNativeFontResource)
: UnscaledFontFreeType(aFace, false)
, mNativeFontResource(aNativeFontResource)
{}
FontType GetType() const override { return FontType::FONTCONFIG; }
@ -83,6 +88,9 @@ public:
CreateScaledFont(Float aGlyphSize,
const uint8_t* aInstanceData,
uint32_t aInstanceDataLength) override;
private:
RefPtr<NativeFontResource> mNativeFontResource;
};
#endif