Use binary-search for finding name table entries
VotoSerifGX has over 500 named instances, which means it also has over a thousand name table entries. So we were looking for names for over 500 pattern, looking for some thirty different name-ids, and using linear search across the 1000 entries! Makes scanning VotoSerifGX three times faster. The rest is probably the lang matching, which can also be shared across named-instances. Upcoming.
This commit is contained in:
parent
261464e0e2
commit
161c738547
|
@ -1159,6 +1159,32 @@ static const FT_UShort nameid_order[] = {
|
|||
|
||||
#define NUM_NAMEID_ORDER (sizeof (nameid_order) / sizeof (nameid_order[0]))
|
||||
|
||||
static FcBool
|
||||
FcFreeTypeGetName (const FT_Face face,
|
||||
unsigned int platform,
|
||||
unsigned int nameid,
|
||||
FT_SfntName *sname)
|
||||
{
|
||||
int min = 0, max = (int) FT_Get_Sfnt_Name_Count (face) - 1;
|
||||
|
||||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
|
||||
if (FT_Get_Sfnt_Name (face, mid, sname) != 0)
|
||||
return FcFalse;
|
||||
|
||||
if (platform < sname->platform_id || (platform == sname->platform_id && nameid < sname->name_id))
|
||||
max = mid - 1;
|
||||
else if (platform > sname->platform_id || (platform == sname->platform_id && nameid > sname->name_id))
|
||||
min = mid + 1;
|
||||
else
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
static FcPattern *
|
||||
FcFreeTypeQueryFaceInternal (const FT_Face face,
|
||||
const FcChar8 *file,
|
||||
|
@ -1197,8 +1223,6 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
|
|||
#endif
|
||||
TT_Header *head;
|
||||
const FcChar8 *exclusiveLang = 0;
|
||||
FT_SfntName sname;
|
||||
FT_UInt snamei, snamec;
|
||||
|
||||
int nfamily = 0;
|
||||
int nfamily_lang = 0;
|
||||
|
@ -1207,7 +1231,6 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
|
|||
int nfullname = 0;
|
||||
int nfullname_lang = 0;
|
||||
unsigned int p, n;
|
||||
int platform, nameid;
|
||||
|
||||
FcChar8 *style = 0;
|
||||
int st;
|
||||
|
@ -1369,10 +1392,9 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
|
|||
* and style names. FreeType makes quite a hash
|
||||
* of them
|
||||
*/
|
||||
snamec = FT_Get_Sfnt_Name_Count (face);
|
||||
for (p = 0; p < NUM_PLATFORM_ORDER; p++)
|
||||
{
|
||||
platform = platform_order[p];
|
||||
int platform = platform_order[p];
|
||||
|
||||
/*
|
||||
* Order nameids so preferred names appear first
|
||||
|
@ -1380,38 +1402,32 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
|
|||
*/
|
||||
for (n = 0; n < NUM_NAMEID_ORDER; n++)
|
||||
{
|
||||
nameid = nameid_order[n];
|
||||
|
||||
for (snamei = 0; snamei < snamec; snamei++)
|
||||
{
|
||||
FT_SfntName sname;
|
||||
const FcChar8 *lang;
|
||||
const char *elt = 0, *eltlang = 0;
|
||||
int *np = 0, *nlangp = 0;
|
||||
size_t len;
|
||||
int nameid, lookupid;
|
||||
|
||||
if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0)
|
||||
continue;
|
||||
nameid = lookupid = nameid_order[n];
|
||||
|
||||
if (instance)
|
||||
{
|
||||
/* For named-instances, we skip regular style nameIDs,
|
||||
* and treat the instance's nameid as FONT_SUBFAMILY.
|
||||
* Postscript name is automatically handled by FreeType. */
|
||||
if (sname.name_id == TT_NAME_ID_WWS_SUBFAMILY ||
|
||||
sname.name_id == TT_NAME_ID_PREFERRED_SUBFAMILY ||
|
||||
sname.name_id == TT_NAME_ID_FONT_SUBFAMILY)
|
||||
if (nameid == TT_NAME_ID_WWS_SUBFAMILY ||
|
||||
nameid == TT_NAME_ID_PREFERRED_SUBFAMILY)
|
||||
continue;
|
||||
if (sname.name_id == instance->strid)
|
||||
sname.name_id = TT_NAME_ID_FONT_SUBFAMILY;
|
||||
|
||||
if (nameid == TT_NAME_ID_FONT_SUBFAMILY)
|
||||
lookupid = instance->strid;
|
||||
}
|
||||
|
||||
if (sname.name_id != nameid)
|
||||
if (!FcFreeTypeGetName (face, platform, lookupid, &sname))
|
||||
continue;
|
||||
|
||||
if (sname.platform_id != platform)
|
||||
continue;
|
||||
|
||||
switch (sname.name_id) {
|
||||
switch (nameid) {
|
||||
#ifdef TT_NAME_ID_WWS_FAMILY
|
||||
case TT_NAME_ID_WWS_FAMILY:
|
||||
#endif
|
||||
|
@ -1525,7 +1541,6 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!nfamily && face->family_name &&
|
||||
FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) face->family_name, (FcChar8 *) "") != 0)
|
||||
|
|
Loading…
Reference in New Issue