Bug 1471261 - Add global locking around FT_Load_Glyph to work around postscript hinter global data. r=lsalzman

MozReview-Commit-ID: 9ohfqUnPxMc

--HG--
extra : rebase_source : b4a0e02cd0685a1623cc2bd0ffdc34429f3b8729
This commit is contained in:
Ryan Hunt 2018-06-26 11:30:13 -04:00
Родитель 88dff8e479
Коммит 6497093aa2
7 изменённых файлов: 37 добавлений и 8 удалений

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

@ -52,6 +52,8 @@ typedef FT_LibraryRec_* FT_Library;
struct FT_FaceRec_;
typedef FT_FaceRec_* FT_Face;
typedef int FT_Error;
struct ID3D11Texture2D;
struct ID3D11Device;
struct ID2D1Device;
@ -1778,6 +1780,7 @@ public:
static FT_Face NewFTFace(FT_Library aFTLibrary, const char* aFileName, int aFaceIndex);
static FT_Face NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData, size_t aDataSize, int aFaceIndex);
static void ReleaseFTFace(FT_Face aFace);
static FT_Error LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
private:
static FT_Library mFTLibrary;

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

@ -189,6 +189,12 @@ mozilla_ReleaseFTFace(FT_Face aFace)
mozilla::gfx::Factory::ReleaseFTFace(aFace);
}
FT_Error
mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags)
{
return mozilla::gfx::Factory::LoadFTGlyph(aFace, aGlyphIndex, aFlags);
}
void
mozilla_LockFTLibrary(FT_Library aFTLibrary)
{
@ -779,6 +785,14 @@ Factory::ReleaseFTFace(FT_Face aFace)
mFTLock->Unlock();
}
}
FT_Error
Factory::LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags)
{
MOZ_ASSERT(mFTLock);
MutexAutoLock lock(*mFTLock);
return FT_Load_Glyph(aFace, aGlyphIndex, aFlags);
}
#endif
#ifdef WIN32

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

@ -108,6 +108,7 @@ static setLcdFilterFunc setLcdFilter;
extern FT_Face mozilla_NewFTFace(FT_Library aFTLibrary, const char* aFileName, int aFaceIndex);
extern FT_Face mozilla_NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData, size_t aDataSize, int aFaceIndex);
extern void mozilla_ReleaseFTFace(FT_Face aFace);
extern FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
extern void mozilla_LockFTLibrary(FT_Library aFTLibrary);
extern void mozilla_UnlockFTLibrary(FT_Library aFTLibrary);
@ -2344,7 +2345,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
load_flags |= FT_LOAD_COLOR;
#endif
error = FT_Load_Glyph (scaled_font->unscaled->face,
error = mozilla_LoadFTGlyph (scaled_font->unscaled->face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags);
/* XXX ignoring all other errors for now. They are not fatal, typically
@ -2498,7 +2499,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
* so reload it. This will probably never occur though
*/
if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
error = FT_Load_Glyph (face,
error = mozilla_LoadFTGlyph (face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags | FT_LOAD_NO_BITMAP);
/* XXX ignoring all other errors for now. They are not fatal, typically

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

@ -61,6 +61,8 @@
#include <ctype.h>
extern FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
typedef struct _cairo_type1_font_subset {
cairo_scaled_font_subset_t *scaled_font_subset;
@ -555,7 +557,7 @@ cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *f
if (font->glyphs[i].name != NULL)
continue;
error = FT_Load_Glyph (font->face, i,
error = mozilla_LoadFTGlyph (font->face, i,
FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING |
FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
if (error != FT_Err_Ok) {

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

@ -64,6 +64,13 @@ static bool gFontHintingEnabled = true;
static FT_Error (*gSetLcdFilter)(FT_Library, FT_LcdFilter) = nullptr;
static void (*gGlyphSlotEmbolden)(FT_GlyphSlot) = nullptr;
extern "C"
{
void mozilla_LockFTLibrary(FT_Library aLibrary);
void mozilla_UnlockFTLibrary(FT_Library aLibrary);
FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
}
void SkInitCairoFT(bool fontHintingEnabled)
{
gFontHintingEnabled = fontHintingEnabled;
@ -635,7 +642,7 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
CairoLockedFTFace faceLock(fScaledFont);
FT_Face face = faceLock.getFace();
FT_Error err = FT_Load_Glyph( face, glyph->getGlyphID(), fLoadGlyphFlags );
FT_Error err = mozilla_LoadFTGlyph( face, glyph->getGlyphID(), fLoadGlyphFlags );
if (err != 0) {
return;
}
@ -739,7 +746,7 @@ void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph)
CairoLockedFTFace faceLock(fScaledFont);
FT_Face face = faceLock.getFace();
FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(), fLoadGlyphFlags);
FT_Error err = mozilla_LoadFTGlyph(face, glyph.getGlyphID(), fLoadGlyphFlags);
if (err != 0) {
memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
@ -753,6 +760,7 @@ void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph)
isLCD(glyph) &&
gSetLcdFilter;
if (useLcdFilter) {
mozilla_LockFTLibrary(face->glyph->library);
gSetLcdFilter(face->glyph->library, fLcdFilter);
}
@ -767,6 +775,7 @@ void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph)
if (useLcdFilter) {
gSetLcdFilter(face->glyph->library, FT_LCD_FILTER_NONE);
mozilla_UnlockFTLibrary(face->glyph->library);
}
}
@ -782,7 +791,7 @@ void SkScalerContext_CairoFT::generatePath(const SkGlyphID glyphID, SkPath* path
flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
FT_Error err = FT_Load_Glyph(face, glyphID, flags);
FT_Error err = mozilla_LoadFTGlyph(face, glyphID, flags);
if (err != 0) {
path->reset();

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

@ -540,7 +540,7 @@ gfxFT2FontBase::GetFTGlyphAdvance(uint16_t aGID, int32_t* aAdvance)
int32_t flags =
hinting ? FT_LOAD_ADVANCE_ONLY
: FT_LOAD_ADVANCE_ONLY | FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING;
FT_Error ftError = FT_Load_Glyph(face.get(), aGID, flags);
FT_Error ftError = Factory::LoadFTGlyph(face.get(), aGID, flags);
if (ftError != FT_Err_Ok) {
// FT_Face was somehow broken/invalid? Don't try to access glyph slot.
// This probably shouldn't happen, but does: see bug 1440938.

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

@ -216,7 +216,7 @@ gfxFT2Font::FillGlyphDataForChar(FT_Face face, uint32_t ch, CachedGlyphData *gd)
FT_Int32 flags = gfxPlatform::GetPlatform()->FontHintingEnabled() ?
FT_LOAD_DEFAULT :
(FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
FT_Error err = FT_Load_Glyph(face, gid, flags);
FT_Error err = Factory::LoadFTGlyph(face, gid, flags);
if (err) {
// hmm, this is weird, we failed to load a glyph that we had?