Bug 1547063 - Use SharedFTFace in thebes. r=jfkthame

Differential Revision: https://phabricator.services.mozilla.com/D44494

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Lee Salzman 2019-09-16 17:07:59 +00:00
Родитель 264178a181
Коммит 286a7bbfff
9 изменённых файлов: 358 добавлений и 522 удалений

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

@ -213,30 +213,6 @@ void gfxFT2FontBase::InitMetrics() {
return; return;
} }
if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
// Resolve variations from entry (descriptor) and style (property)
AutoTArray<gfxFontVariation, 8> settings;
mFontEntry->GetVariationsForStyle(settings, mStyle);
SetupVarCoords(mFontEntry->GetMMVar(), settings, &mCoords);
if (!mCoords.IsEmpty()) {
#if MOZ_TREE_FREETYPE
FT_Set_Var_Design_Coordinates(face, mCoords.Length(), mCoords.Elements());
#else
typedef FT_Error (*SetCoordsFunc)(FT_Face, FT_UInt, FT_Fixed*);
static SetCoordsFunc setCoords;
static bool firstTime = true;
if (firstTime) {
firstTime = false;
setCoords =
(SetCoordsFunc)dlsym(RTLD_DEFAULT, "FT_Set_Var_Design_Coordinates");
}
if (setCoords) {
(*setCoords)(face, mCoords.Length(), mCoords.Elements());
}
#endif
}
}
const FT_Size_Metrics& ftMetrics = face->size->metrics; const FT_Size_Metrics& ftMetrics = face->size->metrics;
mMetrics.maxAscent = FLOAT_FROM_26_6(ftMetrics.ascender); mMetrics.maxAscent = FLOAT_FROM_26_6(ftMetrics.ascender);
@ -607,22 +583,52 @@ bool gfxFT2FontBase::SetupCairoFont(DrawTarget* aDrawTarget) {
/*static*/ /*static*/
void gfxFT2FontBase::SetupVarCoords( void gfxFT2FontBase::SetupVarCoords(
FT_MM_Var* aMMVar, const nsTArray<gfxFontVariation>& aVariations, FT_MM_Var* aMMVar, const nsTArray<gfxFontVariation>& aVariations,
nsTArray<FT_Fixed>* aCoords) { FT_Face aFTFace) {
aCoords->TruncateLength(0);
if (!aMMVar) { if (!aMMVar) {
return; return;
} }
nsTArray<FT_Fixed> coords;
for (unsigned i = 0; i < aMMVar->num_axis; ++i) { for (unsigned i = 0; i < aMMVar->num_axis; ++i) {
aCoords->AppendElement(aMMVar->axis[i].def); coords.AppendElement(aMMVar->axis[i].def);
for (const auto& v : aVariations) { for (const auto& v : aVariations) {
if (aMMVar->axis[i].tag == v.mTag) { if (aMMVar->axis[i].tag == v.mTag) {
FT_Fixed val = v.mValue * 0x10000; FT_Fixed val = v.mValue * 0x10000;
val = std::min(val, aMMVar->axis[i].maximum); val = std::min(val, aMMVar->axis[i].maximum);
val = std::max(val, aMMVar->axis[i].minimum); val = std::max(val, aMMVar->axis[i].minimum);
(*aCoords)[i] = val; coords[i] = val;
break; break;
} }
} }
} }
if (!coords.IsEmpty()) {
#if MOZ_TREE_FREETYPE
FT_Set_Var_Design_Coordinates(aFTFace, coords.Length(), coords.Elements());
#else
typedef FT_Error (*SetCoordsFunc)(FT_Face, FT_UInt, FT_Fixed*);
static SetCoordsFunc setCoords;
static bool firstTime = true;
if (firstTime) {
firstTime = false;
setCoords =
(SetCoordsFunc)dlsym(RTLD_DEFAULT, "FT_Set_Var_Design_Coordinates");
}
if (setCoords) {
(*setCoords)(aFTFace, coords.Length(), coords.Elements());
}
#endif
}
}
already_AddRefed<SharedFTFace> FTUserFontData::CloneFace(int aFaceIndex) {
RefPtr<SharedFTFace> face = Factory::NewSharedFTFaceFromData(
nullptr, mFontData, mLength, aFaceIndex, this);
if (!face ||
(FT_Select_Charmap(face->GetFace(), FT_ENCODING_UNICODE) != FT_Err_Ok &&
FT_Select_Charmap(face->GetFace(), FT_ENCODING_MS_SYMBOL) !=
FT_Err_Ok)) {
return nullptr;
}
return face.forget();
} }

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

@ -37,7 +37,7 @@ class gfxFT2FontBase : public gfxFont {
static void SetupVarCoords(FT_MM_Var* aMMVar, static void SetupVarCoords(FT_MM_Var* aMMVar,
const nsTArray<gfxFontVariation>& aVariations, const nsTArray<gfxFontVariation>& aVariations,
nsTArray<FT_Fixed>* aCoords); FT_Face aFTFace);
private: private:
uint32_t GetCharExtents(char aChar, cairo_text_extents_t* aExtents); uint32_t GetCharExtents(char aChar, cairo_text_extents_t* aExtents);
@ -67,4 +67,35 @@ class gfxFT2FontBase : public gfxFont {
mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey, int32_t>> mGlyphWidths; mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey, int32_t>> mGlyphWidths;
}; };
// Helper classes used for clearing out user font data when FT font
// face is destroyed. Since multiple faces may use the same data, be
// careful to assure that the data is only cleared out when all uses
// expire. The font entry object contains a refptr to FTUserFontData and
// each FT face created from that font entry contains a refptr to that
// same FTUserFontData object.
class FTUserFontData final
: public mozilla::gfx::SharedFTFaceRefCountedData<FTUserFontData> {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData)
FTUserFontData(const uint8_t* aData, uint32_t aLength)
: mFontData(aData), mLength(aLength) {}
const uint8_t* FontData() const { return mFontData; }
already_AddRefed<mozilla::gfx::SharedFTFace> CloneFace(
int aFaceIndex = 0) override;
private:
~FTUserFontData() {
if (mFontData) {
free((void*)mFontData);
}
}
const uint8_t* mFontData;
uint32_t mLength;
};
#endif /* GFX_FT2FONTBASE_H */ #endif /* GFX_FT2FONTBASE_H */

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

@ -63,8 +63,6 @@ static LazyLogModule sFontInfoLog("fontInfoLog");
#define LOG(args) MOZ_LOG(sFontInfoLog, mozilla::LogLevel::Debug, args) #define LOG(args) MOZ_LOG(sFontInfoLog, mozilla::LogLevel::Debug, args)
#define LOG_ENABLED() MOZ_LOG_TEST(sFontInfoLog, mozilla::LogLevel::Debug) #define LOG_ENABLED() MOZ_LOG_TEST(sFontInfoLog, mozilla::LogLevel::Debug)
static cairo_user_data_key_t sFTUserFontDataKey;
static __inline void BuildKeyNameFromFontName(nsACString& aName) { static __inline void BuildKeyNameFromFontName(nsACString& aName) {
ToLowerCase(aName); ToLowerCase(aName);
} }
@ -76,91 +74,65 @@ static __inline void BuildKeyNameFromFontName(nsACString& aName) {
// memory long-term. // memory long-term.
// This may fail (resulting in a null FT_Face), e.g. if it fails to // This may fail (resulting in a null FT_Face), e.g. if it fails to
// allocate memory to uncompress a font from omnijar. // allocate memory to uncompress a font from omnijar.
class AutoFTFace { already_AddRefed<SharedFTFace> FT2FontEntry::GetFTFace(bool aCommit) {
public: if (mFTFace) {
explicit AutoFTFace(FT2FontEntry* aFontEntry) return do_AddRef(mFTFace);
: mFace(nullptr), }
mFontDataBuf(nullptr),
mDataLength(0),
mOwnsFace(false) {
if (aFontEntry->mFTFace) {
mFace = aFontEntry->mFTFace;
return;
}
NS_ASSERTION(!aFontEntry->mFilename.IsEmpty(), NS_ASSERTION(!mFilename.IsEmpty(),
"can't use AutoFTFace for fonts without a filename"); "can't use GetFTFace for fonts without a filename");
// A relative path (no initial "/") means this is a resource in // A relative path (no initial "/") means this is a resource in
// omnijar, not an installed font on the device. // omnijar, not an installed font on the device.
// The NS_ASSERTIONs here should never fail, as the resource must have // The NS_ASSERTIONs here should never fail, as the resource must have
// been read successfully during font-list initialization or we'd never // been read successfully during font-list initialization or we'd never
// have created the font entry. The only legitimate runtime failure // have created the font entry. The only legitimate runtime failure
// here would be memory allocation, in which case mFace remains null. // here would be memory allocation, in which case mFace remains null.
if (aFontEntry->mFilename[0] != '/') { RefPtr<SharedFTFace> face;
RefPtr<nsZipArchive> reader = Omnijar::GetReader(Omnijar::Type::GRE); if (mFilename[0] != '/') {
nsZipItem* item = reader->GetItem(aFontEntry->mFilename.get()); RefPtr<nsZipArchive> reader = Omnijar::GetReader(Omnijar::Type::GRE);
NS_ASSERTION(item, "failed to find zip entry"); nsZipItem* item = reader->GetItem(mFilename.get());
NS_ASSERTION(item, "failed to find zip entry");
uint32_t bufSize = item->RealSize(); uint32_t bufSize = item->RealSize();
mFontDataBuf = static_cast<uint8_t*>(malloc(bufSize)); uint8_t* fontDataBuf = static_cast<uint8_t*>(malloc(bufSize));
if (mFontDataBuf) { if (fontDataBuf) {
nsZipCursor cursor(item, reader, mFontDataBuf, bufSize); nsZipCursor cursor(item, reader, fontDataBuf, bufSize);
cursor.Copy(&bufSize); cursor.Copy(&bufSize);
NS_ASSERTION(bufSize == item->RealSize(), "error reading bundled font"); NS_ASSERTION(bufSize == item->RealSize(), "error reading bundled font");
mDataLength = bufSize; RefPtr<FTUserFontData> ufd = new FTUserFontData(fontDataBuf, bufSize);
mFace = Factory::NewFTFaceFromData(nullptr, mFontDataBuf, bufSize, face = ufd->CloneFace(mFTFontIndex);
aFontEntry->mFTFontIndex); if (!face) {
if (!mFace) {
NS_WARNING("failed to create freetype face");
}
}
} else {
mFace = Factory::NewFTFace(nullptr, aFontEntry->mFilename.get(),
aFontEntry->mFTFontIndex);
if (!mFace) {
NS_WARNING("failed to create freetype face"); NS_WARNING("failed to create freetype face");
return nullptr;
} }
} }
if (FT_Err_Ok != FT_Select_Charmap(mFace, FT_ENCODING_UNICODE) && } else {
FT_Err_Ok != FT_Select_Charmap(mFace, FT_ENCODING_MS_SYMBOL)) { face = Factory::NewSharedFTFace(nullptr, mFilename.get(), mFTFontIndex);
if (!face) {
NS_WARNING("failed to create freetype face");
return nullptr;
}
if (FT_Err_Ok != FT_Select_Charmap(face->GetFace(), FT_ENCODING_UNICODE) &&
FT_Err_Ok !=
FT_Select_Charmap(face->GetFace(), FT_ENCODING_MS_SYMBOL)) {
NS_WARNING("failed to select Unicode or symbol charmap"); NS_WARNING("failed to select Unicode or symbol charmap");
} }
mOwnsFace = true;
} }
~AutoFTFace() { if (aCommit) {
if (mFace && mOwnsFace) { mFTFace = face;
Factory::ReleaseFTFace(mFace);
if (mFontDataBuf) {
free(mFontDataBuf);
}
}
} }
operator FT_Face() { return mFace; } return face.forget();
}
// If we 'forget' the FT_Face (used when ownership is handed over to Cairo), FTUserFontData* FT2FontEntry::GetUserFontData() {
// we do -not- free the mFontDataBuf (if used); that also becomes the if (mFTFace && mFTFace->GetData()) {
// responsibility of the new owner of the face. return static_cast<FTUserFontData*>(mFTFace->GetData());
FT_Face forget() {
NS_ASSERTION(mOwnsFace, "can't forget() when we didn't own the face");
mOwnsFace = false;
return mFace;
} }
return nullptr;
const uint8_t* FontData() const { return mFontDataBuf; } }
uint32_t DataLength() const { return mDataLength; }
private:
FT_Face mFace;
uint8_t* mFontDataBuf; // Uncompressed data (for fonts stored in a JAR),
// or null for fonts instantiated from a file.
// If non-null, this must survive as long as the
// FT_Face.
uint32_t mDataLength; // Size of mFontDataBuf, if present.
bool mOwnsFace;
};
/* /*
* FT2FontEntry * FT2FontEntry
@ -173,8 +145,15 @@ class AutoFTFace {
*/ */
cairo_scaled_font_t* FT2FontEntry::CreateScaledFont( cairo_scaled_font_t* FT2FontEntry::CreateScaledFont(
const gfxFontStyle* aStyle) { const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFace) {
cairo_font_face_t* cairoFace = CairoFontFace(aStyle); int flags = gfxPlatform::GetPlatform()->FontHintingEnabled()
? FT_LOAD_DEFAULT
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
if (aFace->GetFace()->face_flags & FT_FACE_FLAG_TRICKY) {
flags &= ~FT_LOAD_NO_AUTOHINT;
}
cairo_font_face_t* cairoFace = cairo_ft_font_face_create_for_ft_face(
aFace->GetFace(), flags, 0, aFace.get());
if (!cairoFace) { if (!cairoFace) {
return nullptr; return nullptr;
} }
@ -206,18 +185,8 @@ cairo_scaled_font_t* FT2FontEntry::CreateScaledFont(
FT2FontEntry::~FT2FontEntry() { FT2FontEntry::~FT2FontEntry() {
if (mMMVar) { if (mMMVar) {
FT_Done_MM_Var(mFTFace->glyph->library, mMMVar); FT_Done_MM_Var(mFTFace->GetFace()->glyph->library, mMMVar);
} }
// Do nothing for mFTFace here since FTFontDestroyFunc is called by cairo.
mFTFace = nullptr;
#ifndef ANDROID
if (mFontFace) {
cairo_font_face_destroy(mFontFace);
mFontFace = nullptr;
}
#endif
} }
gfxFontEntry* FT2FontEntry::Clone() const { gfxFontEntry* FT2FontEntry::Clone() const {
@ -231,29 +200,52 @@ gfxFontEntry* FT2FontEntry::Clone() const {
return fe; return fe;
} }
static cairo_user_data_key_t sFTFaceKey; gfxFont* FT2FontEntry::CreateFontInstance(const gfxFontStyle* aStyle) {
RefPtr<SharedFTFace> face = GetFTFace(true);
if (!face) {
return nullptr;
}
gfxFont* FT2FontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle) { // If variations are present, we will not use our cached mFTFace
cairo_scaled_font_t* scaledFont = CreateScaledFont(aFontStyle); // but always create a new one as it will have custom variation
// coordinates applied.
if ((!mVariationSettings.IsEmpty() ||
(aStyle && !aStyle->variationSettings.IsEmpty())) &&
(face->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
// Create a separate FT_Face because we need to apply custom
// variation settings to it.
RefPtr<SharedFTFace> varFace;
if (!mFilename.IsEmpty() && mFilename[0] == '/') {
varFace =
Factory::NewSharedFTFace(nullptr, mFilename.get(), mFTFontIndex);
} else {
varFace = face->GetData()->CloneFace(mFTFontIndex);
}
if (varFace) {
// Resolve variations from entry (descriptor) and style (property)
AutoTArray<gfxFontVariation, 8> settings;
GetVariationsForStyle(settings, aStyle ? *aStyle : gfxFontStyle());
gfxFT2FontBase::SetupVarCoords(GetMMVar(), settings, varFace->GetFace());
face = std::move(varFace);
}
}
cairo_scaled_font_t* scaledFont = CreateScaledFont(aStyle, face);
if (!scaledFont) { if (!scaledFont) {
return nullptr; return nullptr;
} }
RefPtr<UnscaledFontFreeType> unscaledFont(mUnscaledFont); RefPtr<UnscaledFontFreeType> unscaledFont(mUnscaledFont);
if (!unscaledFont) { if (!unscaledFont) {
unscaledFont = unscaledFont = !mFilename.IsEmpty() && mFilename[0] == '/'
!mFilename.IsEmpty() && mFilename[0] == '/' ? new UnscaledFontFreeType(mFilename.BeginReading(),
? new UnscaledFontFreeType(mFilename.BeginReading(), mFTFontIndex) mFTFontIndex, mFTFace)
: new UnscaledFontFreeType(mFTFace); : new UnscaledFontFreeType(mFTFace);
mUnscaledFont = unscaledFont; mUnscaledFont = unscaledFont;
} }
cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaledFont); gfxFont* font =
FT_Face ftFace = new gfxFT2Font(unscaledFont, scaledFont, std::move(face), this, aStyle);
static_cast<FT_Face>(cairo_font_face_get_user_data(face, &sFTFaceKey));
gfxFont* font = new gfxFT2Font(unscaledFont, scaledFont,
ftFace ? ftFace : mFTFace, this, aFontStyle);
cairo_scaled_font_destroy(scaledFont); cairo_scaled_font_destroy(scaledFont);
return font; return font;
} }
@ -265,22 +257,17 @@ FT2FontEntry* FT2FontEntry::CreateFontEntry(
// Ownership of aFontData is passed in here; the fontEntry must // Ownership of aFontData is passed in here; the fontEntry must
// retain it as long as the FT_Face needs it, and ensure it is // retain it as long as the FT_Face needs it, and ensure it is
// eventually deleted. // eventually deleted.
FT_Face face = Factory::NewFTFaceFromData(nullptr, aFontData, aLength, 0); RefPtr<FTUserFontData> ufd = new FTUserFontData(aFontData, aLength);
RefPtr<SharedFTFace> face = ufd->CloneFace();
if (!face) { if (!face) {
free((void*)aFontData);
return nullptr;
}
if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE) &&
FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL)) {
Factory::ReleaseFTFace(face);
free((void*)aFontData);
return nullptr; return nullptr;
} }
// Create our FT2FontEntry, which inherits the name of the userfont entry // Create our FT2FontEntry, which inherits the name of the userfont entry
// as it's not guaranteed that the face has valid names (bug 737315) // as it's not guaranteed that the face has valid names (bug 737315)
FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(face, nullptr, 0, aFontName, FT2FontEntry* fe =
aFontData, aLength); FT2FontEntry::CreateFontEntry(face->GetFace(), nullptr, 0, aFontName);
if (fe) { if (fe) {
fe->mFTFace = face;
fe->mStyleRange = aStyle; fe->mStyleRange = aStyle;
fe->mWeightRange = aWeight; fe->mWeightRange = aWeight;
fe->mStretchRange = aStretch; fe->mStretchRange = aStretch;
@ -289,32 +276,6 @@ FT2FontEntry* FT2FontEntry::CreateFontEntry(
return fe; return fe;
} }
class FTUserFontData {
public:
FTUserFontData(FT_Face aFace, const uint8_t* aData, uint32_t aLength)
: mFace(aFace), mFontData(aData), mLength(aLength) {}
~FTUserFontData() {
Factory::ReleaseFTFace(mFace);
if (mFontData) {
free((void*)mFontData);
}
}
const uint8_t* FontData() const { return mFontData; }
uint32_t Length() const { return mLength; }
private:
FT_Face mFace;
const uint8_t* mFontData;
uint32_t mLength;
};
static void FTFontDestroyFunc(void* data) {
FTUserFontData* userFontData = static_cast<FTUserFontData*>(data);
delete userFontData;
}
/* static */ /* static */
FT2FontEntry* FT2FontEntry::CreateFontEntry(const FontListEntry& aFLE) { FT2FontEntry* FT2FontEntry::CreateFontEntry(const FontListEntry& aFLE) {
FT2FontEntry* fe = new FT2FontEntry(aFLE.faceName()); FT2FontEntry* fe = new FT2FontEntry(aFLE.faceName());
@ -368,9 +329,10 @@ static FontWeight FTFaceGetWeight(FT_Face aFace) {
// as we don't want to keep a freetype face for every installed font // as we don't want to keep a freetype face for every installed font
// permanently in memory. // permanently in memory.
/* static */ /* static */
FT2FontEntry* FT2FontEntry::CreateFontEntry( FT2FontEntry* FT2FontEntry::CreateFontEntry(FT_Face aFace,
FT_Face aFace, const char* aFilename, uint8_t aIndex, const char* aFilename,
const nsACString& aName, const uint8_t* aFontData, uint32_t aLength) { uint8_t aIndex,
const nsACString& aName) {
FT2FontEntry* fe = new FT2FontEntry(aName); FT2FontEntry* fe = new FT2FontEntry(aName);
fe->mStyleRange = fe->mStyleRange =
SlantStyleRange(FTFaceIsItalic(aFace) ? FontSlantStyle::Italic() SlantStyleRange(FTFaceIsItalic(aFace) ? FontSlantStyle::Italic()
@ -379,22 +341,6 @@ FT2FontEntry* FT2FontEntry::CreateFontEntry(
fe->mFilename = aFilename; fe->mFilename = aFilename;
fe->mFTFontIndex = aIndex; fe->mFTFontIndex = aIndex;
if (aFontData) {
fe->mFTFace = aFace;
int flags = gfxPlatform::GetPlatform()->FontHintingEnabled()
? FT_LOAD_DEFAULT
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
if (aFace->face_flags & FT_FACE_FLAG_TRICKY) {
flags &= ~FT_LOAD_NO_AUTOHINT;
}
fe->mFontFace =
cairo_ft_font_face_create_for_ft_face(aFace, flags, nullptr, 0);
FTUserFontData* userFontData =
new FTUserFontData(aFace, aFontData, aLength);
cairo_font_face_set_user_data(fe->mFontFace, &sFTUserFontDataKey,
userFontData, FTFontDestroyFunc);
}
return fe; return fe;
} }
@ -417,76 +363,6 @@ FT2FontEntry* gfxFT2Font::GetFontEntry() {
return static_cast<FT2FontEntry*>(mFontEntry.get()); return static_cast<FT2FontEntry*>(mFontEntry.get());
} }
cairo_font_face_t* FT2FontEntry::CairoFontFace(const gfxFontStyle* aStyle) {
// Create our basic (no-variations) mFontFace if not already present;
// this also ensures we have mFTFace available.
if (!mFontFace) {
AutoFTFace face(this);
if (!face) {
return nullptr;
}
int flags = gfxPlatform::GetPlatform()->FontHintingEnabled()
? FT_LOAD_DEFAULT
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
if (FT_Face(face)->face_flags & FT_FACE_FLAG_TRICKY) {
flags &= ~FT_LOAD_NO_AUTOHINT;
}
mFontFace = cairo_ft_font_face_create_for_ft_face(face, flags, nullptr, 0);
auto userFontData =
new FTUserFontData(face, face.FontData(), face.DataLength());
cairo_font_face_set_user_data(mFontFace, &sFTUserFontDataKey, userFontData,
FTFontDestroyFunc);
mFTFace = face.forget();
}
// If variations are present, we will not use our cached mFontFace
// but always create a new cairo_font_face_t because its FT_Face will
// have custom variation coordinates applied.
if ((!mVariationSettings.IsEmpty() ||
(aStyle && !aStyle->variationSettings.IsEmpty())) &&
(mFTFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
int flags = gfxPlatform::GetPlatform()->FontHintingEnabled()
? FT_LOAD_DEFAULT
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
if (mFTFace->face_flags & FT_FACE_FLAG_TRICKY) {
flags &= ~FT_LOAD_NO_AUTOHINT;
}
// Resolve variations from entry (descriptor) and style (property)
AutoTArray<gfxFontVariation, 8> settings;
GetVariationsForStyle(settings, aStyle ? *aStyle : gfxFontStyle());
AutoTArray<FT_Fixed, 8> coords;
gfxFT2FontBase::SetupVarCoords(GetMMVar(), settings, &coords);
// Create a separate FT_Face because we need to apply custom
// variation settings to it.
FT_Face ftFace;
if (!mFilename.IsEmpty() && mFilename[0] == '/') {
ftFace = Factory::NewFTFace(nullptr, mFilename.get(), mFTFontIndex);
} else {
auto ufd = reinterpret_cast<FTUserFontData*>(
cairo_font_face_get_user_data(mFontFace, &sFTUserFontDataKey));
ftFace = Factory::NewFTFaceFromData(nullptr, ufd->FontData(),
ufd->Length(), mFTFontIndex);
}
// The variation coordinates will actually be applied to ftFace by
// gfxFT2FontBase::InitMetrics, so we don't need to do it here.
cairo_font_face_t* cairoFace = cairo_ft_font_face_create_for_ft_face(
ftFace, flags, coords.Elements(), coords.Length());
// Set up user data to properly release the FT_Face when the cairo face
// is deleted.
if (cairo_font_face_set_user_data(
cairoFace, &sFTFaceKey, ftFace,
(cairo_destroy_func_t)&Factory::ReleaseFTFace)) {
// set_user_data failed! discard, and fall back to default face
cairo_font_face_destroy(cairoFace);
FT_Done_Face(ftFace);
} else {
return cairoFace;
}
}
return mFontFace;
}
// Copied/modified from similar code in gfxMacPlatformFontList.mm: // Copied/modified from similar code in gfxMacPlatformFontList.mm:
// Complex scripts will not render correctly unless Graphite or OT // Complex scripts will not render correctly unless Graphite or OT
// layout tables are present. // layout tables are present.
@ -560,14 +436,14 @@ nsresult FT2FontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
nsresult FT2FontEntry::CopyFontTable(uint32_t aTableTag, nsresult FT2FontEntry::CopyFontTable(uint32_t aTableTag,
nsTArray<uint8_t>& aBuffer) { nsTArray<uint8_t>& aBuffer) {
AutoFTFace face(this); RefPtr<SharedFTFace> face = GetFTFace();
if (!face) { if (!face) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
FT_Error status; FT_Error status;
FT_ULong len = 0; FT_ULong len = 0;
status = FT_Load_Sfnt_Table(face, aTableTag, 0, nullptr, &len); status = FT_Load_Sfnt_Table(face->GetFace(), aTableTag, 0, nullptr, &len);
if (status != FT_Err_Ok || len == 0) { if (status != FT_Err_Ok || len == 0) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -576,19 +452,17 @@ nsresult FT2FontEntry::CopyFontTable(uint32_t aTableTag,
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
uint8_t* buf = aBuffer.Elements(); uint8_t* buf = aBuffer.Elements();
status = FT_Load_Sfnt_Table(face, aTableTag, 0, buf, &len); status = FT_Load_Sfnt_Table(face->GetFace(), aTableTag, 0, buf, &len);
NS_ENSURE_TRUE(status == FT_Err_Ok, NS_ERROR_FAILURE); NS_ENSURE_TRUE(status == FT_Err_Ok, NS_ERROR_FAILURE);
return NS_OK; return NS_OK;
} }
hb_blob_t* FT2FontEntry::GetFontTable(uint32_t aTableTag) { hb_blob_t* FT2FontEntry::GetFontTable(uint32_t aTableTag) {
if (mFontFace) { if (FTUserFontData* userFontData = GetUserFontData()) {
// if there's a cairo font face, we may be able to return a blob // if there's a cairo font face, we may be able to return a blob
// that just wraps a range of the attached user font data // that just wraps a range of the attached user font data
FTUserFontData* userFontData = static_cast<FTUserFontData*>( if (userFontData->FontData()) {
cairo_font_face_get_user_data(mFontFace, &sFTUserFontDataKey));
if (userFontData && userFontData->FontData()) {
return gfxFontUtils::GetTableFromFontData(userFontData->FontData(), return gfxFontUtils::GetTableFromFontData(userFontData->FontData(),
aTableTag); aTableTag);
} }
@ -605,9 +479,10 @@ bool FT2FontEntry::HasVariations() {
} }
mHasVariationsInitialized = true; mHasVariationsInitialized = true;
AutoFTFace face(this); RefPtr<SharedFTFace> face = GetFTFace();
if (face) { if (face) {
mHasVariations = FT_Face(face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS; mHasVariations =
face->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
} }
return mHasVariations; return mHasVariations;
@ -641,11 +516,11 @@ FT_MM_Var* FT2FontEntry::GetMMVar() {
return mMMVar; return mMMVar;
} }
mMMVarInitialized = true; mMMVarInitialized = true;
AutoFTFace face(this); RefPtr<SharedFTFace> face = GetFTFace(true);
if (!face) { if (!face) {
return nullptr; return nullptr;
} }
if (FT_Err_Ok != FT_Get_MM_Var(face, &mMMVar)) { if (FT_Err_Ok != FT_Get_MM_Var(face->GetFace(), &mMMVar)) {
mMMVar = nullptr; mMMVar = nullptr;
} }
return mMMVar; return mMMVar;
@ -1162,10 +1037,10 @@ void FT2FontEntry::CheckForBrokenFont(const nsACString& aFamilyKey) {
// Droid Sans Arabic from certain phones, as identified by the // Droid Sans Arabic from certain phones, as identified by the
// font checksum in the 'head' table // font checksum in the 'head' table
if (aFamilyKey.EqualsLiteral("droid sans arabic")) { if (aFamilyKey.EqualsLiteral("droid sans arabic")) {
AutoFTFace face(this); RefPtr<SharedFTFace> face = GetFTFace();
if (face) { if (face) {
const TT_Header* head = const TT_Header* head = static_cast<const TT_Header*>(
static_cast<const TT_Header*>(FT_Get_Sfnt_Table(face, ft_sfnt_head)); FT_Get_Sfnt_Table(face->GetFace(), ft_sfnt_head));
if (head && head->CheckSum_Adjust == 0xe445242) { if (head && head->CheckSum_Adjust == 0xe445242) {
mIgnoreGSUB = true; mIgnoreGSUB = true;
} }
@ -1739,14 +1614,14 @@ searchDone:
// from the userfont entry rather than the actual font. // from the userfont entry rather than the actual font.
// Ensure existence of mFTFace in the original entry // Ensure existence of mFTFace in the original entry
fontEntry->CairoFontFace(); RefPtr<SharedFTFace> face = fontEntry->GetFTFace(true);
if (!fontEntry->mFTFace) { if (!face) {
return nullptr; return nullptr;
} }
FT2FontEntry* fe = FT2FontEntry::CreateFontEntry( FT2FontEntry* fe =
fontEntry->mFTFace, fontEntry->mFilename.get(), fontEntry->mFTFontIndex, FT2FontEntry::CreateFontEntry(face->GetFace(), fontEntry->mFilename.get(),
fontEntry->Name(), nullptr); fontEntry->mFTFontIndex, fontEntry->Name());
if (fe) { if (fe) {
fe->mStyleRange = aStyleForEntry; fe->mStyleRange = aStyleForEntry;
fe->mWeightRange = aWeightForEntry; fe->mWeightRange = aWeightForEntry;

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

@ -21,14 +21,12 @@ class FontNameCache;
typedef struct FT_FaceRec_* FT_Face; typedef struct FT_FaceRec_* FT_Face;
class nsZipArchive; class nsZipArchive;
class WillShutdownObserver; class WillShutdownObserver;
class FTUserFontData;
class FT2FontEntry : public gfxFontEntry { class FT2FontEntry : public gfxFontEntry {
public: public:
explicit FT2FontEntry(const nsACString& aFaceName) explicit FT2FontEntry(const nsACString& aFaceName)
: gfxFontEntry(aFaceName), : gfxFontEntry(aFaceName), mFTFontIndex(0) {}
mFTFace(nullptr),
mFontFace(nullptr),
mFTFontIndex(0) {}
~FT2FontEntry(); ~FT2FontEntry();
@ -51,22 +49,15 @@ class FT2FontEntry : public gfxFontEntry {
// aFontData (if non-nullptr) is NS_Malloc'ed data that aFace depends on, // aFontData (if non-nullptr) is NS_Malloc'ed data that aFace depends on,
// to be freed after the face is destroyed. // to be freed after the face is destroyed.
// aLength is the length of aFontData. // aLength is the length of aFontData.
static FT2FontEntry* CreateFontEntry(FT_Face aFace, const char* aFilename, static FT2FontEntry* CreateFontEntry(FT_Face, const char* aFilename,
uint8_t aIndex, const nsACString& aName, uint8_t aIndex, const nsACString& aName);
const uint8_t* aFontData = nullptr,
uint32_t aLength = 0);
gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override; gfxFont* CreateFontInstance(const gfxFontStyle* aStyle) override;
// Create (if necessary) and return the cairo_font_face for this font.
// This may fail and return null, so caller must be prepared to handle this.
// If a style is passed, any variationSettings in the style will be applied
// to the resulting font face.
cairo_font_face_t* CairoFontFace(const gfxFontStyle* aStyle = nullptr);
// Create a cairo_scaled_font for this face, with the given style. // Create a cairo_scaled_font for this face, with the given style.
// This may fail and return null, so caller must be prepared to handle this. // This may fail and return null, so caller must be prepared to handle this.
cairo_scaled_font_t* CreateScaledFont(const gfxFontStyle* aStyle); cairo_scaled_font_t* CreateScaledFont(
const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFace);
nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override; nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
@ -86,6 +77,9 @@ class FT2FontEntry : public gfxFontEntry {
void CheckForBrokenFont(gfxFontFamily* aFamily); void CheckForBrokenFont(gfxFontFamily* aFamily);
void CheckForBrokenFont(const nsACString& aFamilyKey); void CheckForBrokenFont(const nsACString& aFamilyKey);
already_AddRefed<mozilla::gfx::SharedFTFace> GetFTFace(bool aCommit = false);
FTUserFontData* GetUserFontData();
FT_MM_Var* GetMMVar() override; FT_MM_Var* GetMMVar() override;
/** /**
@ -103,8 +97,7 @@ class FT2FontEntry : public gfxFontEntry {
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
FontListSizes* aSizes) const override; FontListSizes* aSizes) const override;
FT_Face mFTFace; RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
cairo_font_face_t* mFontFace;
FT_MM_Var* mMMVar = nullptr; FT_MM_Var* mMMVar = nullptr;

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

@ -153,11 +153,12 @@ void gfxFT2Font::AddRange(const char16_t* aText, uint32_t aOffset,
} }
gfxFT2Font::gfxFT2Font(const RefPtr<UnscaledFontFreeType>& aUnscaledFont, gfxFT2Font::gfxFT2Font(const RefPtr<UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t* aCairoFont, FT_Face aFTFace, cairo_scaled_font_t* aCairoFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace,
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle) FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle)
: gfxFT2FontBase(aUnscaledFont, aCairoFont, aFontEntry, aFontStyle), : gfxFT2FontBase(aUnscaledFont, aCairoFont, aFontEntry, aFontStyle),
mCharGlyphCache(32), mCharGlyphCache(32),
mFTFace(aFTFace) { mFTFace(std::move(aFTFace)) {
NS_ASSERTION(mFontEntry, NS_ASSERTION(mFontEntry,
"Unable to find font entry for font. Something is whack."); "Unable to find font entry for font. Something is whack.");
// TODO: use FreeType emboldening instead of multi-strike? // TODO: use FreeType emboldening instead of multi-strike?
@ -168,12 +169,8 @@ gfxFT2Font::~gfxFT2Font() {}
already_AddRefed<ScaledFont> gfxFT2Font::GetScaledFont(DrawTarget* aTarget) { already_AddRefed<ScaledFont> gfxFT2Font::GetScaledFont(DrawTarget* aTarget) {
if (!mAzureScaledFont) { if (!mAzureScaledFont) {
NativeFont nativeFont; mAzureScaledFont = Factory::CreateScaledFontForFreeTypeFont(
nativeFont.mType = NativeFontType::FREETYPE_FACE; GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont(), mFTFace);
nativeFont.mFont = mFTFace;
mAzureScaledFont = Factory::CreateScaledFontForNativeFont(
nativeFont, GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont());
InitializeScaledFont(); InitializeScaledFont();
} }

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

@ -20,7 +20,8 @@ class FT2FontEntry;
class gfxFT2Font : public gfxFT2FontBase { class gfxFT2Font : public gfxFT2FontBase {
public: // new functions public: // new functions
gfxFT2Font(const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont, gfxFT2Font(const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t* aCairoFont, FT_Face aFTFace, cairo_scaled_font_t* aCairoFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace,
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle); FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle);
virtual ~gfxFT2Font(); virtual ~gfxFT2Font();
@ -73,7 +74,7 @@ class gfxFT2Font : public gfxFT2FontBase {
CharGlyphMapEntryType; CharGlyphMapEntryType;
typedef nsTHashtable<CharGlyphMapEntryType> CharGlyphMap; typedef nsTHashtable<CharGlyphMapEntryType> CharGlyphMap;
CharGlyphMap mCharGlyphCache; CharGlyphMap mCharGlyphCache;
FT_Face mFTFace; RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
}; };
#endif /* GFX_FT2FONTS_H */ #endif /* GFX_FT2FONTS_H */

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

@ -93,8 +93,6 @@ static const char* ToCharPtr(const FcChar8* aStr) {
FT_Library gfxFcPlatformFontList::sCairoFTLibrary = nullptr; FT_Library gfxFcPlatformFontList::sCairoFTLibrary = nullptr;
static cairo_user_data_key_t sFcFontlistUserFontDataKey;
// canonical name ==> first en name or first name if no en name // canonical name ==> first en name or first name if no en name
// This is the required logic for fullname lookups as per CSS3 Fonts spec. // This is the required logic for fullname lookups as per CSS3 Fonts spec.
static uint32_t FindCanonicalNameIndex(FcPattern* aFont, static uint32_t FindCanonicalNameIndex(FcPattern* aFont,
@ -251,13 +249,10 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
bool aIgnoreFcCharmap) bool aIgnoreFcCharmap)
: gfxFontEntry(aFaceName), : gfxFontEntry(aFaceName),
mFontPattern(aFontPattern), mFontPattern(aFontPattern),
mFTFace(nullptr),
mFTFaceInitialized(false), mFTFaceInitialized(false),
mIgnoreFcCharmap(aIgnoreFcCharmap), mIgnoreFcCharmap(aIgnoreFcCharmap),
mHasVariationsInitialized(false), mHasVariationsInitialized(false),
mAspect(0.0), mAspect(0.0) {
mFontData(nullptr),
mLength(0) {
GetFontProperties(aFontPattern, &mWeightRange, &mStretchRange, &mStyleRange); GetFontProperties(aFontPattern, &mWeightRange, &mStretchRange, &mStyleRange);
} }
@ -292,7 +287,8 @@ static FcPattern* CreatePatternForFace(FT_Face aFace) {
return pattern; return pattern;
} }
static FT_Face CreateFaceForPattern(FcPattern* aPattern) { static already_AddRefed<SharedFTFace> CreateFaceForPattern(
FcPattern* aPattern) {
FcChar8* filename; FcChar8* filename;
if (FcPatternGetString(aPattern, FC_FILE, 0, &filename) != FcResultMatch) { if (FcPatternGetString(aPattern, FC_FILE, 0, &filename) != FcResultMatch) {
return nullptr; return nullptr;
@ -301,31 +297,26 @@ static FT_Face CreateFaceForPattern(FcPattern* aPattern) {
if (FcPatternGetInteger(aPattern, FC_INDEX, 0, &index) != FcResultMatch) { if (FcPatternGetInteger(aPattern, FC_INDEX, 0, &index) != FcResultMatch) {
index = 0; // default to 0 if not found in pattern index = 0; // default to 0 if not found in pattern
} }
return Factory::NewFTFace(nullptr, ToCharPtr(filename), index); return Factory::NewSharedFTFace(nullptr, ToCharPtr(filename), index);
} }
gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName, gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
WeightRange aWeight, WeightRange aWeight,
StretchRange aStretch, StretchRange aStretch,
SlantStyleRange aStyle, SlantStyleRange aStyle,
const uint8_t* aData, RefPtr<SharedFTFace>&& aFace)
uint32_t aLength, FT_Face aFace)
: gfxFontEntry(aFaceName), : gfxFontEntry(aFaceName),
mFTFace(aFace), mFTFace(std::move(aFace)),
mFTFaceInitialized(true), mFTFaceInitialized(true),
mIgnoreFcCharmap(true), mIgnoreFcCharmap(true),
mHasVariationsInitialized(false), mHasVariationsInitialized(false),
mAspect(0.0), mAspect(0.0) {
mFontData(aData),
mLength(aLength) {
mWeightRange = aWeight; mWeightRange = aWeight;
mStyleRange = aStyle; mStyleRange = aStyle;
mStretchRange = aStretch; mStretchRange = aStretch;
mIsDataUserFont = true; mIsDataUserFont = true;
mFontPattern = CreatePatternForFace(mFTFace); mFontPattern = CreatePatternForFace(mFTFace->GetFace());
mUserFontData = new FTUserFontData(mFTFace, mFontData);
} }
gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName, gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
@ -335,12 +326,9 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
SlantStyleRange aStyle) SlantStyleRange aStyle)
: gfxFontEntry(aFaceName), : gfxFontEntry(aFaceName),
mFontPattern(aFontPattern), mFontPattern(aFontPattern),
mFTFace(nullptr),
mFTFaceInitialized(false), mFTFaceInitialized(false),
mHasVariationsInitialized(false), mHasVariationsInitialized(false),
mAspect(0.0), mAspect(0.0) {
mFontData(nullptr),
mLength(0) {
mWeightRange = aWeight; mWeightRange = aWeight;
mStyleRange = aStyle; mStyleRange = aStyle;
mStretchRange = aStretch; mStretchRange = aStretch;
@ -388,7 +376,7 @@ gfxFontconfigFontEntry::~gfxFontconfigFontEntry() {
// non-null here, so we don't need to do it again. // non-null here, so we don't need to do it again.
if (sDoneVar) { if (sDoneVar) {
MOZ_ASSERT(mFTFace, "How did mMMVar get set without a face?"); MOZ_ASSERT(mFTFace, "How did mMMVar get set without a face?");
(*sDoneVar)(mFTFace->glyph->library, mMMVar); (*sDoneVar)(mFTFace->GetFace()->glyph->library, mMMVar);
} else { } else {
free(mMMVar); free(mMMVar);
} }
@ -481,44 +469,17 @@ bool gfxFontconfigFontEntry::TestCharacterMap(uint32_t aCh) {
hb_blob_t* gfxFontconfigFontEntry::GetFontTable(uint32_t aTableTag) { hb_blob_t* gfxFontconfigFontEntry::GetFontTable(uint32_t aTableTag) {
// for data fonts, read directly from the font data // for data fonts, read directly from the font data
if (mFontData) { if (FTUserFontData* ufd = GetUserFontData()) {
return gfxFontUtils::GetTableFromFontData(mFontData, aTableTag); return gfxFontUtils::GetTableFromFontData(ufd->FontData(), aTableTag);
} }
return gfxFontEntry::GetFontTable(aTableTag); return gfxFontEntry::GetFontTable(aTableTag);
} }
void gfxFontconfigFontEntry::MaybeReleaseFTFace() { void gfxFontconfigFontEntry::ForgetHBFace() { gfxFontEntry::ForgetHBFace(); }
// don't release if either HB or Gr face still exists
if (mHBFace || mGrFace) {
return;
}
// only close out FT_Face for system fonts, not for data fonts
if (!mIsDataUserFont) {
if (mFTFace) {
if (mMMVar) {
if (sDoneVar) {
(*sDoneVar)(mFTFace->glyph->library, mMMVar);
} else {
free(mMMVar);
}
mMMVar = nullptr;
}
Factory::ReleaseFTFace(mFTFace);
mFTFace = nullptr;
}
mFTFaceInitialized = false;
}
}
void gfxFontconfigFontEntry::ForgetHBFace() {
gfxFontEntry::ForgetHBFace();
MaybeReleaseFTFace();
}
void gfxFontconfigFontEntry::ReleaseGrFace(gr_face* aFace) { void gfxFontconfigFontEntry::ReleaseGrFace(gr_face* aFace) {
gfxFontEntry::ReleaseGrFace(aFace); gfxFontEntry::ReleaseGrFace(aFace);
MaybeReleaseFTFace();
} }
double gfxFontconfigFontEntry::GetAspect() { double gfxFontconfigFontEntry::GetAspect() {
@ -567,9 +528,14 @@ double gfxFontconfigFontEntry::GetAspect() {
} }
static void PrepareFontOptions(FcPattern* aPattern, static void PrepareFontOptions(FcPattern* aPattern,
cairo_font_options_t* aFontOptions) { cairo_font_options_t* aFontOptions,
int* aOutLoadFlags,
unsigned int* aOutSynthFlags) {
NS_ASSERTION(aFontOptions, "null font options passed to PrepareFontOptions"); NS_ASSERTION(aFontOptions, "null font options passed to PrepareFontOptions");
int loadFlags = FT_LOAD_DEFAULT;
unsigned int synthFlags = 0;
// xxx - taken from the gfxFontconfigFonts code, needs to be reviewed // xxx - taken from the gfxFontconfigFonts code, needs to be reviewed
FcBool printing; FcBool printing;
@ -718,21 +684,63 @@ static void PrepareFontOptions(FcPattern* aPattern,
antialias = CAIRO_ANTIALIAS_SUBPIXEL; antialias = CAIRO_ANTIALIAS_SUBPIXEL;
} }
cairo_font_options_set_antialias(aFontOptions, antialias); cairo_font_options_set_antialias(aFontOptions, antialias);
}
static void ReleaseFTUserFontData(void* aData) { FcBool bitmap;
static_cast<FTUserFontData*>(aData)->Release(); if (FcPatternGetBool(aPattern, FC_EMBEDDED_BITMAP, 0, &bitmap) !=
} FcResultMatch) {
bitmap = FcFalse;
}
if (fc_antialias && (hint_style == CAIRO_HINT_STYLE_NONE || !bitmap)) {
loadFlags |= FT_LOAD_NO_BITMAP;
}
static cairo_user_data_key_t sFcFontlistFTFaceKey; int fc_lcd_filter;
if (FcPatternGetInteger(aPattern, FC_LCD_FILTER, 0, &fc_lcd_filter) ==
FcResultMatch) {
cairo_lcd_filter_t lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
switch (fc_lcd_filter) {
case FC_LCD_NONE:
lcd_filter = CAIRO_LCD_FILTER_NONE;
break;
case FC_LCD_DEFAULT:
lcd_filter = CAIRO_LCD_FILTER_FIR5;
break;
case FC_LCD_LIGHT:
lcd_filter = CAIRO_LCD_FILTER_FIR3;
break;
case FC_LCD_LEGACY:
lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL;
break;
}
cairo_font_options_set_lcd_filter(aFontOptions, lcd_filter);
}
static void ReleaseFTFace(void* aData) { FcBool autohint;
Factory::ReleaseFTFace(static_cast<FT_Face>(aData)); if (FcPatternGetBool(aPattern, FC_AUTOHINT, 0, &autohint) == FcResultMatch &&
autohint) {
loadFlags |= FT_LOAD_FORCE_AUTOHINT;
}
FcBool vertical;
if (FcPatternGetBool(aPattern, FC_VERTICAL_LAYOUT, 0, &vertical) ==
FcResultMatch &&
vertical) {
loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
}
FcBool embolden;
if (FcPatternGetBool(aPattern, FC_EMBOLDEN, 0, &embolden) == FcResultMatch &&
embolden) {
synthFlags |= CAIRO_FT_SYNTHESIZE_BOLD;
}
*aOutLoadFlags = loadFlags;
*aOutSynthFlags = synthFlags;
} }
cairo_scaled_font_t* gfxFontconfigFontEntry::CreateScaledFont( cairo_scaled_font_t* gfxFontconfigFontEntry::CreateScaledFont(
FcPattern* aRenderPattern, gfxFloat aAdjustedSize, FcPattern* aRenderPattern, gfxFloat aAdjustedSize,
const gfxFontStyle* aStyle, FT_Face aFTFace) { const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFTFace) {
if (aStyle->NeedsSyntheticBold(this)) { if (aStyle->NeedsSyntheticBold(this)) {
FcPatternAddBool(aRenderPattern, FC_EMBOLDEN, FcTrue); FcPatternAddBool(aRenderPattern, FC_EMBOLDEN, FcTrue);
} }
@ -748,45 +756,19 @@ cairo_scaled_font_t* gfxFontconfigFontEntry::CreateScaledFont(
FcPatternAddBool(aRenderPattern, FC_EMBEDDED_BITMAP, FcFalse); FcPatternAddBool(aRenderPattern, FC_EMBEDDED_BITMAP, FcFalse);
} }
AutoTArray<FT_Fixed, 8> coords; if (HasVariations() && aFTFace != mFTFace) {
if (HasVariations()) { AutoTArray<gfxFontVariation, 8> settings;
FT_Face ftFace = GetFTFace(); GetVariationsForStyle(settings, *aStyle);
if (ftFace) { gfxFT2FontBase::SetupVarCoords(GetMMVar(), settings, aFTFace->GetFace());
AutoTArray<gfxFontVariation, 8> settings;
GetVariationsForStyle(settings, *aStyle);
gfxFT2FontBase::SetupVarCoords(GetMMVar(), settings, &coords);
}
} }
cairo_font_face_t* face = cairo_ft_font_face_create_for_pattern( cairo_font_options_t* fontOptions = cairo_font_options_create();
aRenderPattern, coords.Elements(), coords.Length()); int loadFlags;
unsigned int synthFlags;
PrepareFontOptions(aRenderPattern, fontOptions, &loadFlags, &synthFlags);
if (aFTFace) { cairo_font_face_t* face = cairo_ft_font_face_create_for_ft_face(
if (cairo_font_face_set_user_data(face, &sFcFontlistFTFaceKey, aFTFace, aFTFace->GetFace(), loadFlags, synthFlags, aFTFace.get());
ReleaseFTFace) != CAIRO_STATUS_SUCCESS) {
NS_WARNING("Failed binding FT_Face to Cairo font face");
cairo_font_face_destroy(face);
Factory::ReleaseFTFace(aFTFace);
return nullptr;
}
}
if (mFontData) {
// for data fonts, add the face/data pointer to the cairo font face
// so that it ges deleted whenever cairo decides
NS_ASSERTION(mFTFace, "FT_Face is null when setting user data");
NS_ASSERTION(mUserFontData,
"user font data is null when setting user data");
mUserFontData.get()->AddRef();
if (cairo_font_face_set_user_data(face, &sFcFontlistUserFontDataKey,
mUserFontData, ReleaseFTUserFontData) !=
CAIRO_STATUS_SUCCESS) {
NS_WARNING("Failed binding FTUserFontData to Cairo font face");
mUserFontData.get()->Release();
cairo_font_face_destroy(face);
return nullptr;
}
}
cairo_scaled_font_t* scaledFont = nullptr; cairo_scaled_font_t* scaledFont = nullptr;
@ -796,9 +778,6 @@ cairo_scaled_font_t* gfxFontconfigFontEntry::CreateScaledFont(
cairo_matrix_init_scale(&sizeMatrix, aAdjustedSize, aAdjustedSize); cairo_matrix_init_scale(&sizeMatrix, aAdjustedSize, aAdjustedSize);
cairo_matrix_init_identity(&identityMatrix); cairo_matrix_init_identity(&identityMatrix);
cairo_font_options_t* fontOptions = cairo_font_options_create();
PrepareFontOptions(aRenderPattern, fontOptions);
scaledFont = scaledFont =
cairo_scaled_font_create(face, &sizeMatrix, &identityMatrix, fontOptions); cairo_scaled_font_create(face, &sizeMatrix, &identityMatrix, fontOptions);
cairo_font_options_destroy(fontOptions); cairo_font_options_destroy(fontOptions);
@ -892,12 +871,11 @@ void gfxFontconfigFontEntry::UnscaledFontCache::MoveToFront(size_t aIndex) {
} }
already_AddRefed<UnscaledFontFontconfig> already_AddRefed<UnscaledFontFontconfig>
gfxFontconfigFontEntry::UnscaledFontCache::Lookup(const char* aFile, gfxFontconfigFontEntry::UnscaledFontCache::Lookup(const std::string& aFile,
uint32_t aIndex) { uint32_t aIndex) {
for (size_t i = 0; i < kNumEntries; i++) { for (size_t i = 0; i < kNumEntries; i++) {
RefPtr<UnscaledFontFontconfig> entry(mUnscaledFonts[i]); RefPtr<UnscaledFontFontconfig> entry(mUnscaledFonts[i]);
if (entry && !strcmp(entry->GetFile(), aFile) && if (entry && entry->GetFile() == aFile && entry->GetIndex() == aIndex) {
entry->GetIndex() == aIndex) {
MoveToFront(i); MoveToFront(i);
return entry.forget(); return entry.forget();
} }
@ -941,11 +919,6 @@ static double ChooseFontSize(gfxFontconfigFontEntry* aEntry,
gfxFont* gfxFontconfigFontEntry::CreateFontInstance( gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
const gfxFontStyle* aFontStyle) { const gfxFontStyle* aFontStyle) {
FcPattern* fontPattern = mFontPattern;
if (!fontPattern) {
return nullptr;
}
nsAutoRef<FcPattern> pattern(FcPatternCreate()); nsAutoRef<FcPattern> pattern(FcPatternCreate());
if (!pattern) { if (!pattern) {
NS_WARNING("Failed to create Fontconfig pattern for font instance"); NS_WARNING("Failed to create Fontconfig pattern for font instance");
@ -955,25 +928,25 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
double size = ChooseFontSize(this, *aFontStyle); double size = ChooseFontSize(this, *aFontStyle);
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size); FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size);
FT_Face face = mFTFace; RefPtr<SharedFTFace> face = GetFTFace();
if (face && face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) { if (!face) {
// For variation fonts, we create a new FT_Face and FcPattern here NS_WARNING("Failed to get FreeType face for pattern");
// so that variation coordinates from the style can be applied return nullptr;
// without affecting other font instances created from the same }
// entry (font resource). if (face->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
if (mFontData) { // For variation fonts, we create a new FT_Face here so that
// variation coordinates from the style can be applied without
// affecting other font instances created from the same entry
// (font resource).
if (face->GetData()) {
// For user fonts: create a new FT_Face from the font data, and then // For user fonts: create a new FT_Face from the font data, and then
// make a pattern from that. // make a pattern from that.
face = Factory::NewFTFaceFromData(nullptr, mFontData, mLength, 0); face = face->GetData()->CloneFace();
fontPattern = CreatePatternForFace(face);
} else { } else {
// For system fonts: create a new FT_Face and store it in a copy of // For system fonts: create a new FT_Face and store it in a copy of
// the original mFontPattern. // the original mFontPattern.
fontPattern = FcPatternDuplicate(mFontPattern); face = CreateFaceForPattern(mFontPattern);
face = CreateFaceForPattern(fontPattern); if (!face) {
if (face) {
FcPatternAddFTFace(fontPattern, FC_FT_FACE, face);
} else {
// I don't think CreateFaceForPattern above should ever fail, // I don't think CreateFaceForPattern above should ever fail,
// but just in case let's fall back here. // but just in case let's fall back here.
face = mFTFace; face = mFTFace;
@ -983,51 +956,47 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
PreparePattern(pattern, aFontStyle->printerFont); PreparePattern(pattern, aFontStyle->printerFont);
nsAutoRef<FcPattern> renderPattern( nsAutoRef<FcPattern> renderPattern(
FcFontRenderPrepare(nullptr, pattern, fontPattern)); FcFontRenderPrepare(nullptr, pattern, mFontPattern));
if (fontPattern != mFontPattern) {
// Discard temporary pattern used for variation support
FcPatternDestroy(fontPattern);
}
if (!renderPattern) { if (!renderPattern) {
NS_WARNING("Failed to prepare Fontconfig pattern for font instance"); NS_WARNING("Failed to prepare Fontconfig pattern for font instance");
if (face != mFTFace) {
Factory::ReleaseFTFace(face);
}
return nullptr; return nullptr;
} }
cairo_scaled_font_t* scaledFont = CreateScaledFont( cairo_scaled_font_t* scaledFont =
renderPattern, size, aFontStyle, face != mFTFace ? face : nullptr); CreateScaledFont(renderPattern, size, aFontStyle, face);
const FcChar8* file = ToFcChar8Ptr(""); std::string file;
int index = 0; int index = 0;
if (!mFontData) { if (!face->GetData()) {
const FcChar8* fcFile;
if (FcPatternGetString(renderPattern, FC_FILE, 0, if (FcPatternGetString(renderPattern, FC_FILE, 0,
const_cast<FcChar8**>(&file)) != FcResultMatch || const_cast<FcChar8**>(&fcFile)) != FcResultMatch ||
FcPatternGetInteger(renderPattern, FC_INDEX, 0, &index) != FcPatternGetInteger(renderPattern, FC_INDEX, 0, &index) !=
FcResultMatch) { FcResultMatch) {
NS_WARNING("No file in Fontconfig pattern for font instance"); NS_WARNING("No file in Fontconfig pattern for font instance");
return nullptr; return nullptr;
} }
file = ToCharPtr(fcFile);
} }
RefPtr<UnscaledFontFontconfig> unscaledFont = RefPtr<UnscaledFontFontconfig> unscaledFont =
mUnscaledFontCache.Lookup(ToCharPtr(file), index); mUnscaledFontCache.Lookup(file, index);
if (!unscaledFont) { if (!unscaledFont) {
unscaledFont = mFontData unscaledFont = mFTFace->GetData() ? new UnscaledFontFontconfig(mFTFace)
? new UnscaledFontFontconfig(mFTFace) : new UnscaledFontFontconfig(
: new UnscaledFontFontconfig(ToCharPtr(file), index); std::move(file), index, mFTFace);
mUnscaledFontCache.Add(unscaledFont); mUnscaledFontCache.Add(unscaledFont);
} }
gfxFont* newFont = new gfxFontconfigFont( gfxFont* newFont =
unscaledFont, scaledFont, renderPattern, size, this, aFontStyle); new gfxFontconfigFont(unscaledFont, scaledFont, std::move(face),
renderPattern, size, this, aFontStyle);
cairo_scaled_font_destroy(scaledFont); cairo_scaled_font_destroy(scaledFont);
return newFont; return newFont;
} }
FT_Face gfxFontconfigFontEntry::GetFTFace() { const RefPtr<SharedFTFace>& gfxFontconfigFontEntry::GetFTFace() {
if (!mFTFaceInitialized) { if (!mFTFaceInitialized) {
mFTFaceInitialized = true; mFTFaceInitialized = true;
mFTFace = CreateFaceForPattern(mFontPattern); mFTFace = CreateFaceForPattern(mFontPattern);
@ -1035,6 +1004,13 @@ FT_Face gfxFontconfigFontEntry::GetFTFace() {
return mFTFace; return mFTFace;
} }
FTUserFontData* gfxFontconfigFontEntry::GetUserFontData() {
if (mFTFace && mFTFace->GetData()) {
return static_cast<FTUserFontData*>(mFTFace->GetData());
}
return nullptr;
}
bool gfxFontconfigFontEntry::HasVariations() { bool gfxFontconfigFontEntry::HasVariations() {
if (mHasVariationsInitialized) { if (mHasVariationsInitialized) {
return mHasVariations; return mHasVariations;
@ -1056,9 +1032,9 @@ bool gfxFontconfigFontEntry::HasVariations() {
mHasVariations = true; mHasVariations = true;
} }
} else { } else {
FT_Face face = GetFTFace(); if (GetFTFace()) {
if (face) { mHasVariations =
mHasVariations = face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS; mFTFace->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
} }
} }
@ -1074,11 +1050,10 @@ FT_MM_Var* gfxFontconfigFontEntry::GetMMVar() {
if (!sGetVar) { if (!sGetVar) {
return nullptr; return nullptr;
} }
FT_Face face = GetFTFace(); if (!GetFTFace()) {
if (!face) {
return nullptr; return nullptr;
} }
if (FT_Err_Ok != (*sGetVar)(face, &mMMVar)) { if (FT_Err_Ok != (*sGetVar)(mFTFace->GetFace(), &mMMVar)) {
mMMVar = nullptr; mMMVar = nullptr;
} }
return mMMVar; return mMMVar;
@ -1105,20 +1080,20 @@ nsresult gfxFontconfigFontEntry::CopyFontTable(uint32_t aTableTag,
NS_ASSERTION(!mIsDataUserFont, NS_ASSERTION(!mIsDataUserFont,
"data fonts should be reading tables directly from memory"); "data fonts should be reading tables directly from memory");
FT_Face face = GetFTFace(); if (!GetFTFace()) {
if (!face) {
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
FT_ULong length = 0; FT_ULong length = 0;
if (FT_Load_Sfnt_Table(face, aTableTag, 0, nullptr, &length) != 0) { if (FT_Load_Sfnt_Table(mFTFace->GetFace(), aTableTag, 0, nullptr, &length) !=
0) {
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
if (!aBuffer.SetLength(length, fallible)) { if (!aBuffer.SetLength(length, fallible)) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
if (FT_Load_Sfnt_Table(face, aTableTag, 0, aBuffer.Elements(), &length) != if (FT_Load_Sfnt_Table(mFTFace->GetFace(), aTableTag, 0, aBuffer.Elements(),
0) { &length) != 0) {
aBuffer.Clear(); aBuffer.Clear();
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -1370,10 +1345,11 @@ void gfxFontconfigFontFamily::AddFacesToFontList(Func aAddPatternFunc) {
gfxFontconfigFont::gfxFontconfigFont( gfxFontconfigFont::gfxFontconfigFont(
const RefPtr<UnscaledFontFontconfig>& aUnscaledFont, const RefPtr<UnscaledFontFontconfig>& aUnscaledFont,
cairo_scaled_font_t* aScaledFont, FcPattern* aPattern, cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace>&& aFTFace,
gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry, FcPattern* aPattern, gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
const gfxFontStyle* aFontStyle) const gfxFontStyle* aFontStyle)
: gfxFT2FontBase(aUnscaledFont, aScaledFont, aFontEntry, aFontStyle), : gfxFT2FontBase(aUnscaledFont, aScaledFont, aFontEntry, aFontStyle),
mFTFace(std::move(aFTFace)),
mPattern(aPattern) { mPattern(aPattern) {
mAdjustedSize = aAdjustedSize; mAdjustedSize = aAdjustedSize;
} }
@ -1383,12 +1359,9 @@ gfxFontconfigFont::~gfxFontconfigFont() {}
already_AddRefed<ScaledFont> gfxFontconfigFont::GetScaledFont( already_AddRefed<ScaledFont> gfxFontconfigFont::GetScaledFont(
mozilla::gfx::DrawTarget* aTarget) { mozilla::gfx::DrawTarget* aTarget) {
if (!mAzureScaledFont) { if (!mAzureScaledFont) {
NativeFont nativeFont; mAzureScaledFont = Factory::CreateScaledFontForFontconfigFont(
nativeFont.mType = NativeFontType::FONTCONFIG_PATTERN; GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont(), mFTFace,
nativeFont.mFont = GetPattern(); GetPattern());
mAzureScaledFont = Factory::CreateScaledFontForNativeFont(
nativeFont, GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont());
InitializeScaledFont(); InitializeScaledFont();
} }
@ -1984,21 +1957,14 @@ gfxFontEntry* gfxFcPlatformFontList::MakePlatformFont(
const nsACString& aFontName, WeightRange aWeightForEntry, const nsACString& aFontName, WeightRange aWeightForEntry,
StretchRange aStretchForEntry, SlantStyleRange aStyleForEntry, StretchRange aStretchForEntry, SlantStyleRange aStyleForEntry,
const uint8_t* aFontData, uint32_t aLength) { const uint8_t* aFontData, uint32_t aLength) {
FT_Face face = Factory::NewFTFaceFromData(nullptr, aFontData, aLength, 0); RefPtr<FTUserFontData> ufd = new FTUserFontData(aFontData, aLength);
RefPtr<SharedFTFace> face = ufd->CloneFace();
if (!face) { if (!face) {
free((void*)aFontData);
return nullptr; return nullptr;
} }
if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE) &&
FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL)) {
Factory::ReleaseFTFace(face);
free((void*)aFontData);
return nullptr;
}
return new gfxFontconfigFontEntry(aFontName, aWeightForEntry, return new gfxFontconfigFontEntry(aFontName, aWeightForEntry,
aStretchForEntry, aStyleForEntry, aFontData, aStretchForEntry, aStyleForEntry,
aLength, face); std::move(face));
} }
bool gfxFcPlatformFontList::FindAndAddFamilies( bool gfxFcPlatformFontList::FindAndAddFamilies(
@ -2267,8 +2233,7 @@ FT_Library gfxFcPlatformFontList::GetFTLibrary() {
FcPattern* pat = FcPattern* pat =
FcPatternBuild(0, FC_FAMILY, FcTypeString, "serif", (char*)0); FcPatternBuild(0, FC_FAMILY, FcTypeString, "serif", (char*)0);
cairo_font_face_t* face = cairo_font_face_t* face = cairo_ft_font_face_create_for_pattern(pat);
cairo_ft_font_face_create_for_pattern(pat, nullptr, 0);
FcPatternDestroy(pat); FcPatternDestroy(pat);
cairo_matrix_t identity; cairo_matrix_t identity;

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

@ -47,34 +47,6 @@ class nsAutoRefTraits<FcConfig> : public nsPointerRefTraits<FcConfig> {
static void AddRef(FcConfig* ptr) { FcConfigReference(ptr); } static void AddRef(FcConfig* ptr) { FcConfigReference(ptr); }
}; };
// Helper classes used for clearning out user font data when cairo font
// face is destroyed. Since multiple faces may use the same data, be
// careful to assure that the data is only cleared out when all uses
// expire. The font entry object contains a refptr to FTUserFontData and
// each cairo font created from that font entry contains a
// FTUserFontDataRef with a refptr to that same FTUserFontData object.
class FTUserFontData final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData)
explicit FTUserFontData(FT_Face aFace, const uint8_t* aData)
: mFace(aFace), mFontData(aData) {}
const uint8_t* FontData() const { return mFontData; }
private:
~FTUserFontData() {
mozilla::gfx::Factory::ReleaseFTFace(mFace);
if (mFontData) {
free((void*)mFontData);
}
}
FT_Face mFace;
const uint8_t* mFontData;
};
// The names for the font entry and font classes should really // The names for the font entry and font classes should really
// the common 'Fc' abbreviation but the gfxPangoFontGroup code already // the common 'Fc' abbreviation but the gfxPangoFontGroup code already
// defines versions of these, so use the verbose name for now. // defines versions of these, so use the verbose name for now.
@ -90,8 +62,8 @@ class gfxFontconfigFontEntry : public gfxFontEntry {
// of the font data and the FT_Face // of the font data and the FT_Face
explicit gfxFontconfigFontEntry(const nsACString& aFaceName, explicit gfxFontconfigFontEntry(const nsACString& aFaceName,
WeightRange aWeight, StretchRange aStretch, WeightRange aWeight, StretchRange aStretch,
SlantStyleRange aStyle, const uint8_t* aData, SlantStyleRange aStyle,
uint32_t aLength, FT_Face aFace); RefPtr<mozilla::gfx::SharedFTFace>&& aFace);
// used for @font-face local system fonts with explicit patterns // used for @font-face local system fonts with explicit patterns
explicit gfxFontconfigFontEntry(const nsACString& aFaceName, explicit gfxFontconfigFontEntry(const nsACString& aFaceName,
@ -106,7 +78,8 @@ class gfxFontconfigFontEntry : public gfxFontEntry {
nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override; nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
bool TestCharacterMap(uint32_t aCh) override; bool TestCharacterMap(uint32_t aCh) override;
FT_Face GetFTFace(); const RefPtr<mozilla::gfx::SharedFTFace>& GetFTFace();
FTUserFontData* GetUserFontData();
FT_MM_Var* GetMMVar() override; FT_MM_Var* GetMMVar() override;
@ -128,26 +101,19 @@ class gfxFontconfigFontEntry : public gfxFontEntry {
gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override; gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;
// helper method for creating cairo font from pattern // helper method for creating cairo font from pattern
cairo_scaled_font_t* CreateScaledFont(FcPattern* aRenderPattern, cairo_scaled_font_t* CreateScaledFont(
gfxFloat aAdjustedSize, FcPattern* aRenderPattern, gfxFloat aAdjustedSize,
const gfxFontStyle* aStyle, const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFTFace);
FT_Face aFTFace);
// override to pull data from FTFace // override to pull data from FTFace
virtual nsresult CopyFontTable(uint32_t aTableTag, virtual nsresult CopyFontTable(uint32_t aTableTag,
nsTArray<uint8_t>& aBuffer) override; nsTArray<uint8_t>& aBuffer) override;
// if HB or GR faces are gone, close down the FT_Face
void MaybeReleaseFTFace();
// pattern for a single face of a family // pattern for a single face of a family
nsCountedRef<FcPattern> mFontPattern; nsCountedRef<FcPattern> mFontPattern;
// user font data, when needed
RefPtr<FTUserFontData> mUserFontData;
// FTFace - initialized when needed // FTFace - initialized when needed
FT_Face mFTFace; RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
bool mFTFaceInitialized; bool mFTFaceInitialized;
// Whether TestCharacterMap should check the actual cmap rather than asking // Whether TestCharacterMap should check the actual cmap rather than asking
@ -166,14 +132,10 @@ class gfxFontconfigFontEntry : public gfxFontEntry {
double mAspect; double mAspect;
// data font
const uint8_t* mFontData;
uint32_t mLength;
class UnscaledFontCache { class UnscaledFontCache {
public: public:
already_AddRefed<mozilla::gfx::UnscaledFontFontconfig> Lookup( already_AddRefed<mozilla::gfx::UnscaledFontFontconfig> Lookup(
const char* aFile, uint32_t aIndex); const std::string& aFile, uint32_t aIndex);
void Add( void Add(
const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont) { const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont) {
@ -244,7 +206,8 @@ class gfxFontconfigFont : public gfxFT2FontBase {
public: public:
gfxFontconfigFont( gfxFontconfigFont(
const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont, const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont,
cairo_scaled_font_t* aScaledFont, FcPattern* aPattern, cairo_scaled_font_t* aScaledFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, FcPattern* aPattern,
gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry, gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
const gfxFontStyle* aFontStyle); const gfxFontStyle* aFontStyle);
@ -257,6 +220,7 @@ class gfxFontconfigFont : public gfxFT2FontBase {
private: private:
virtual ~gfxFontconfigFont(); virtual ~gfxFontconfigFont();
RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
nsCountedRef<FcPattern> mPattern; nsCountedRef<FcPattern> mPattern;
}; };

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

@ -789,6 +789,10 @@ gfxFont::gfxFont(const RefPtr<UnscaledFont>& aUnscaledFont,
++gFontCount; ++gFontCount;
#endif #endif
if (MOZ_UNLIKELY(StaticPrefs::gfx_text_disable_aa_AtStartup())) {
mAntialiasOption = kAntialiasNone;
}
// Turn off AA for Ahem for testing purposes when requested. // Turn off AA for Ahem for testing purposes when requested.
if (MOZ_UNLIKELY(StaticPrefs::gfx_font_rendering_ahem_antialias_none() && if (MOZ_UNLIKELY(StaticPrefs::gfx_font_rendering_ahem_antialias_none() &&
mFontEntry->FamilyName().EqualsLiteral("Ahem"))) { mFontEntry->FamilyName().EqualsLiteral("Ahem"))) {