Commit 15b5016c authored by Behdad Esfahbod's avatar Behdad Esfahbod

[varfonts] Don't reopen face for each named instance

Makes scanning of Voto (over 500 named instaces) twice faster.

Next, avoid charset / lang recalculation for each of those.
parent 2d006394
...@@ -2082,8 +2082,9 @@ FcFreeTypeQueryAll(const FcChar8 *file, ...@@ -2082,8 +2082,9 @@ FcFreeTypeQueryAll(const FcChar8 *file,
int *count, int *count,
FcFontSet *set) FcFontSet *set)
{ {
FT_Face face; FT_Face face = NULL;
FT_Library ftLibrary = NULL; FT_Library ftLibrary = NULL;
FT_MM_Var *mm_var = NULL;
FcBool index_set = id != (unsigned int) -1; FcBool index_set = id != (unsigned int) -1;
unsigned int set_face_num = index_set ? id & 0xFFFF : 0; unsigned int set_face_num = index_set ? id & 0xFFFF : 0;
unsigned int set_instance_num = index_set ? id >> 16 : 0; unsigned int set_instance_num = index_set ? id >> 16 : 0;
...@@ -2094,75 +2095,86 @@ FcFreeTypeQueryAll(const FcChar8 *file, ...@@ -2094,75 +2095,86 @@ FcFreeTypeQueryAll(const FcChar8 *file,
unsigned int ret = 0; unsigned int ret = 0;
int err = 0; int err = 0;
if (count)
*count = 0;
if (FT_Init_FreeType (&ftLibrary)) if (FT_Init_FreeType (&ftLibrary))
return 0; return 0;
do { if (FT_New_Face (ftLibrary, (const char *) file, face_num, &face))
FcPattern *pat; goto bail;
id = ((instance_num << 16) + face_num); num_faces = face->num_faces;
if (FT_New_Face (ftLibrary, (const char *) file, id & 0x7FFFFFFF, &face)) num_instances = face->style_flags >> 16;
break; if (num_instances && (!index_set || instance_num))
{
FT_Get_MM_Var (face, &mm_var);
assert (mm_var);
}
num_faces = face->num_faces; if (count)
num_instances = face->style_flags >> 16; *count = num_faces;
pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks);
if (pat) do {
FcPattern *pat = NULL;
if (instance_num == 0x8000 || instance_num > num_instances)
FT_Set_Var_Design_Coordinates (face, 0, NULL); /* Reset variations. */
else if (instance_num)
{ {
/* Skip named-instance that coincides with base instance. */ FT_Var_Named_Style *instance = &mm_var->namedstyle[instance_num - 1];
if (!index_set && instance_num && instance_num != 0x8000) FT_Fixed *coords = instance->coords;
{ FcBool nonzero;
unsigned int i; unsigned int i;
FT_MM_Var *mm_var = NULL;
FT_Fixed *coords = NULL;
if (FT_Get_MM_Var (face, &mm_var) || /* Skip named-instance that coincides with base instance. */
!(coords = (FT_Fixed *) calloc (mm_var->num_axis, sizeof (FT_Fixed))) || nonzero = FcFalse;
FT_Get_Var_Blend_Coordinates (face, mm_var->num_axis, coords)) for (i = 0; i < mm_var->num_axis; i++)
if (coords[i] != mm_var->axis[i].def)
{ {
goto skip; nonzero = FcTrue;
break;
} }
if (!nonzero)
goto skip;
for (i = 0; i < mm_var->num_axis; i++) FT_Set_Var_Design_Coordinates (face, mm_var->num_axis, coords);
if (coords[i]) }
goto good;
skip: id = ((instance_num << 16) + face_num);
free (coords); pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks);
FcPatternDestroy (pat);
pat = NULL;
good:
;
}
if (pat) if (pat)
{ {
ret++;
if (!set || ! FcFontSetAdd (set, pat)) ret++;
FcPatternDestroy (pat); if (!set || ! FcFontSetAdd (set, pat))
} FcPatternDestroy (pat);
} }
else if (instance_num != 0x8000) else if (instance_num != 0x8000)
err = 1; err = 1;
FT_Done_Face (face); skip:
face = NULL; if (!index_set && instance_num < num_instances)
if (!set_instance_num && instance_num < num_instances)
instance_num++; instance_num++;
else if (!set_instance_num && instance_num == num_instances) else if (!index_set && instance_num == num_instances)
instance_num = 0x8000; /* variable font */ instance_num = 0x8000; /* variable font */
else else
{ {
FT_Done_Face (face);
face = NULL;
face_num++; face_num++;
instance_num = set_instance_num; instance_num = set_instance_num;
if (FT_New_Face (ftLibrary, (const char *) file, face_num, &face))
break;
} }
} while (!err && (!index_set || face_num == set_face_num) && face_num < num_faces); } while (!err && (!index_set || face_num == set_face_num) && face_num < num_faces);
if (count) bail:
*count = num_faces; if (face)
FT_Done_Face (face);
FT_Done_FreeType (ftLibrary); FT_Done_FreeType (ftLibrary);
return ret; return ret;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment