[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.
This commit is contained in:
parent
2d0063948a
commit
15b5016ccd
136
src/fcfreetype.c
136
src/fcfreetype.c
|
@ -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,
|
||||||
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))
|
||||||
|
{
|
||||||
num_faces = face->num_faces;
|
FT_Get_MM_Var (face, &mm_var);
|
||||||
num_instances = face->style_flags >> 16;
|
assert (mm_var);
|
||||||
pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks);
|
}
|
||||||
|
|
||||||
if (pat)
|
|
||||||
{
|
|
||||||
/* Skip named-instance that coincides with base instance. */
|
|
||||||
if (!index_set && instance_num && instance_num != 0x8000)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
FT_MM_Var *mm_var = NULL;
|
|
||||||
FT_Fixed *coords = NULL;
|
|
||||||
|
|
||||||
if (FT_Get_MM_Var (face, &mm_var) ||
|
|
||||||
!(coords = (FT_Fixed *) calloc (mm_var->num_axis, sizeof (FT_Fixed))) ||
|
|
||||||
FT_Get_Var_Blend_Coordinates (face, mm_var->num_axis, coords))
|
|
||||||
{
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < mm_var->num_axis; i++)
|
|
||||||
if (coords[i])
|
|
||||||
goto good;
|
|
||||||
|
|
||||||
skip:
|
|
||||||
free (coords);
|
|
||||||
FcPatternDestroy (pat);
|
|
||||||
pat = NULL;
|
|
||||||
good:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pat)
|
|
||||||
{
|
|
||||||
ret++;
|
|
||||||
if (!set || ! FcFontSetAdd (set, pat))
|
|
||||||
FcPatternDestroy (pat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (instance_num != 0x8000)
|
|
||||||
err = 1;
|
|
||||||
|
|
||||||
FT_Done_Face (face);
|
|
||||||
face = NULL;
|
|
||||||
|
|
||||||
if (!set_instance_num && instance_num < num_instances)
|
|
||||||
instance_num++;
|
|
||||||
else if (!set_instance_num && instance_num == num_instances)
|
|
||||||
instance_num = 0x8000; /* variable font */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
face_num++;
|
|
||||||
instance_num = set_instance_num;
|
|
||||||
}
|
|
||||||
} while (!err && (!index_set || face_num == set_face_num) && face_num < num_faces);
|
|
||||||
|
|
||||||
if (count)
|
if (count)
|
||||||
*count = num_faces;
|
*count = num_faces;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
FT_Var_Named_Style *instance = &mm_var->namedstyle[instance_num - 1];
|
||||||
|
FT_Fixed *coords = instance->coords;
|
||||||
|
FcBool nonzero;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* Skip named-instance that coincides with base instance. */
|
||||||
|
nonzero = FcFalse;
|
||||||
|
for (i = 0; i < mm_var->num_axis; i++)
|
||||||
|
if (coords[i] != mm_var->axis[i].def)
|
||||||
|
{
|
||||||
|
nonzero = FcTrue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!nonzero)
|
||||||
|
goto skip;
|
||||||
|
|
||||||
|
FT_Set_Var_Design_Coordinates (face, mm_var->num_axis, coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
id = ((instance_num << 16) + face_num);
|
||||||
|
pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks);
|
||||||
|
|
||||||
|
if (pat)
|
||||||
|
{
|
||||||
|
|
||||||
|
ret++;
|
||||||
|
if (!set || ! FcFontSetAdd (set, pat))
|
||||||
|
FcPatternDestroy (pat);
|
||||||
|
}
|
||||||
|
else if (instance_num != 0x8000)
|
||||||
|
err = 1;
|
||||||
|
|
||||||
|
skip:
|
||||||
|
if (!index_set && instance_num < num_instances)
|
||||||
|
instance_num++;
|
||||||
|
else if (!index_set && instance_num == num_instances)
|
||||||
|
instance_num = 0x8000; /* variable font */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FT_Done_Face (face);
|
||||||
|
face = NULL;
|
||||||
|
|
||||||
|
face_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);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
if (face)
|
||||||
|
FT_Done_Face (face);
|
||||||
FT_Done_FreeType (ftLibrary);
|
FT_Done_FreeType (ftLibrary);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue