mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1432552 - patch 2 - Linux font back-end implementation of getVariationInstances. r=dholbert
This commit is contained in:
parent
9de316c207
commit
c70ab6cef4
@ -360,8 +360,37 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
|
||||
mIgnoreFcCharmap = true;
|
||||
}
|
||||
|
||||
typedef FT_Error (*GetVarFunc)(FT_Face, FT_MM_Var**);
|
||||
typedef FT_Error (*DoneVarFunc)(FT_Library, FT_MM_Var*);
|
||||
static GetVarFunc sGetVar;
|
||||
static DoneVarFunc sDoneVar;
|
||||
static bool sInitializedVarFuncs = false;
|
||||
|
||||
static void
|
||||
InitializeVarFuncs()
|
||||
{
|
||||
if (sInitializedVarFuncs) {
|
||||
return;
|
||||
}
|
||||
sInitializedVarFuncs = true;
|
||||
sGetVar = (GetVarFunc)dlsym(RTLD_DEFAULT, "FT_Get_MM_Var");
|
||||
sDoneVar = (DoneVarFunc)dlsym(RTLD_DEFAULT, "FT_Done_MM_Var");
|
||||
}
|
||||
|
||||
gfxFontconfigFontEntry::~gfxFontconfigFontEntry()
|
||||
{
|
||||
if (mMMVar) {
|
||||
// Prior to freetype 2.9, there was no specific function to free the
|
||||
// FT_MM_Var record, and the docs just said to use free().
|
||||
// InitializeVarFuncs must have been called in order for mMMVar to be
|
||||
// non-null here, so we don't need to do it again.
|
||||
if (sDoneVar) {
|
||||
MOZ_ASSERT(mFTFace, "How did mMMVar get set without a face?");
|
||||
(*sDoneVar)(mFTFace->glyph->library, mMMVar);
|
||||
} else {
|
||||
free(mMMVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -469,6 +498,14 @@ gfxFontconfigFontEntry::MaybeReleaseFTFace()
|
||||
// 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;
|
||||
}
|
||||
@ -1017,31 +1054,36 @@ gfxFontconfigFontEntry::HasVariations()
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_MM_Var*
|
||||
gfxFontconfigFontEntry::GetMMVar()
|
||||
{
|
||||
if (mMMVarInitialized) {
|
||||
return mMMVar;
|
||||
}
|
||||
mMMVarInitialized = true;
|
||||
InitializeVarFuncs();
|
||||
if (!sGetVar) {
|
||||
return nullptr;
|
||||
}
|
||||
FT_Face face = GetFTFace();
|
||||
if (!face) {
|
||||
return nullptr;
|
||||
}
|
||||
if (FT_Err_Ok != (*sGetVar)(face, &mMMVar)) {
|
||||
mMMVar = nullptr;
|
||||
}
|
||||
return mMMVar;
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontconfigFontEntry::GetVariationAxes(nsTArray<gfxFontVariationAxis>& aAxes)
|
||||
{
|
||||
MOZ_ASSERT(aAxes.IsEmpty());
|
||||
FT_Face face = GetFTFace();
|
||||
if (!face) {
|
||||
return;
|
||||
}
|
||||
typedef FT_Error (*GetVarFunc)(FT_Face, FT_MM_Var**);
|
||||
static GetVarFunc getVar;
|
||||
typedef FT_Error (*DoneVarFunc)(FT_Library, FT_MM_Var*);
|
||||
static DoneVarFunc doneVar;
|
||||
static bool firstTime = true;
|
||||
if (firstTime) {
|
||||
firstTime = false;
|
||||
getVar = (GetVarFunc)dlsym(RTLD_DEFAULT, "FT_Get_MM_Var");
|
||||
doneVar = (DoneVarFunc)dlsym(RTLD_DEFAULT, "FT_Done_MM_Var");
|
||||
}
|
||||
if (!getVar) {
|
||||
return;
|
||||
}
|
||||
FT_MM_Var* mmVar;
|
||||
if (FT_Err_Ok != (*getVar)(face, &mmVar)) {
|
||||
FT_MM_Var* mmVar = GetMMVar();
|
||||
if (!mmVar) {
|
||||
return;
|
||||
}
|
||||
aAxes.SetCapacity(mmVar->num_axis);
|
||||
for (unsigned i = 0; i < mmVar->num_axis; i++) {
|
||||
const auto& a = mmVar->axis[i];
|
||||
gfxFontVariationAxis axis;
|
||||
@ -1052,13 +1094,40 @@ gfxFontconfigFontEntry::GetVariationAxes(nsTArray<gfxFontVariationAxis>& aAxes)
|
||||
axis.mName.Assign(NS_ConvertUTF8toUTF16(a.name));
|
||||
aAxes.AppendElement(axis);
|
||||
}
|
||||
// Prior to freetype 2.9, there was no specific function to free the FT_MM_Var,
|
||||
// and the docs just said to use free().
|
||||
if (doneVar) {
|
||||
(*doneVar)(face->glyph->library, mmVar);
|
||||
} else {
|
||||
free(mmVar);
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontconfigFontEntry::GetVariationInstances(
|
||||
nsTArray<gfxFontVariationInstance>& aInstances)
|
||||
{
|
||||
MOZ_ASSERT(aInstances.IsEmpty());
|
||||
FT_MM_Var* mmVar = GetMMVar();
|
||||
if (!mmVar) {
|
||||
return;
|
||||
}
|
||||
hb_blob_t* nameTable = GetFontTable(TRUETYPE_TAG('n','a','m','e'));
|
||||
if (!nameTable) {
|
||||
return;
|
||||
}
|
||||
aInstances.SetCapacity(mmVar->num_namedstyles);
|
||||
for (unsigned i = 0; i < mmVar->num_namedstyles; i++) {
|
||||
const auto& ns = mmVar->namedstyle[i];
|
||||
gfxFontVariationInstance inst;
|
||||
nsresult rv =
|
||||
gfxFontUtils::ReadCanonicalName(nameTable, ns.strid, inst.mName);
|
||||
if (NS_FAILED(rv)) {
|
||||
continue;
|
||||
}
|
||||
inst.mValues.SetCapacity(mmVar->num_axis);
|
||||
for (unsigned j = 0; j < mmVar->num_axis; j++) {
|
||||
gfxFontVariationValue value;
|
||||
value.mAxis = mmVar->axis[j].tag;
|
||||
value.mValue = ns.coords[j] / 65536.0;
|
||||
inst.mValues.AppendElement(value);
|
||||
}
|
||||
aInstances.AppendElement(inst);
|
||||
}
|
||||
hb_blob_destroy(nameTable);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ft2build.h"
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
#include <cairo.h>
|
||||
#include <cairo-ft.h>
|
||||
|
||||
@ -115,8 +116,11 @@ public:
|
||||
|
||||
FT_Face GetFTFace();
|
||||
|
||||
FT_MM_Var* GetMMVar();
|
||||
|
||||
bool HasVariations() override;
|
||||
void GetVariationAxes(nsTArray<gfxFontVariationAxis>& aAxes) override;
|
||||
void GetVariationInstances(nsTArray<gfxFontVariationInstance>& aInstances) override;
|
||||
|
||||
hb_blob_t* GetFontTable(uint32_t aTableTag) override;
|
||||
|
||||
@ -188,6 +192,11 @@ protected:
|
||||
};
|
||||
|
||||
UnscaledFontCache mUnscaledFontCache;
|
||||
|
||||
// Because of FreeType bug 52955, we keep the FT_MM_Var struct when it is
|
||||
// first loaded, rather than releasing it and re-fetching it as needed.
|
||||
FT_MM_Var* mMMVar = nullptr;
|
||||
bool mMMVarInitialized = false;
|
||||
};
|
||||
|
||||
class gfxFontconfigFontFamily : public gfxFontFamily {
|
||||
|
Loading…
Reference in New Issue
Block a user