зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
264178a181
Коммит
286a7bbfff
|
@ -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"))) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче