From 15b5016ccdf236e51caf2480749d534a7f4b9eda Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 20 Sep 2017 19:39:59 -0700 Subject: [PATCH] [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. --- src/fcfreetype.c | 100 ++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/src/fcfreetype.c b/src/fcfreetype.c index ed9ebb1f..d8aab731 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -2082,8 +2082,9 @@ FcFreeTypeQueryAll(const FcChar8 *file, int *count, FcFontSet *set) { - FT_Face face; + FT_Face face = NULL; FT_Library ftLibrary = NULL; + FT_MM_Var *mm_var = NULL; FcBool index_set = id != (unsigned int) -1; unsigned int set_face_num = index_set ? id & 0xFFFF : 0; unsigned int set_instance_num = index_set ? id >> 16 : 0; @@ -2094,75 +2095,86 @@ FcFreeTypeQueryAll(const FcChar8 *file, unsigned int ret = 0; int err = 0; + if (count) + *count = 0; + if (FT_Init_FreeType (&ftLibrary)) return 0; - do { - FcPattern *pat; + if (FT_New_Face (ftLibrary, (const char *) file, face_num, &face)) + goto bail; - id = ((instance_num << 16) + face_num); - if (FT_New_Face (ftLibrary, (const char *) file, id & 0x7FFFFFFF, &face)) - break; + num_faces = face->num_faces; + num_instances = face->style_flags >> 16; + if (num_instances && (!index_set || instance_num)) + { + FT_Get_MM_Var (face, &mm_var); + assert (mm_var); + } - num_faces = face->num_faces; - num_instances = face->style_flags >> 16; - pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks); + if (count) + *count = num_faces; - 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. */ - if (!index_set && instance_num && instance_num != 0x8000) - { - unsigned int i; - FT_MM_Var *mm_var = NULL; - FT_Fixed *coords = NULL; + FT_Var_Named_Style *instance = &mm_var->namedstyle[instance_num - 1]; + FT_Fixed *coords = instance->coords; + FcBool nonzero; + unsigned int i; - 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)) + /* 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) { - goto skip; + nonzero = FcTrue; + break; } + if (!nonzero) + goto skip; - for (i = 0; i < mm_var->num_axis; i++) - if (coords[i]) - goto good; + FT_Set_Var_Design_Coordinates (face, mm_var->num_axis, coords); + } -skip: - free (coords); - FcPatternDestroy (pat); - pat = NULL; -good: - ; - } + id = ((instance_num << 16) + face_num); + pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks); - if (pat) - { - ret++; - if (!set || ! FcFontSetAdd (set, pat)) - FcPatternDestroy (pat); - } + 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) +skip: + if (!index_set && instance_num < num_instances) instance_num++; - else if (!set_instance_num && instance_num == num_instances) + 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); - if (count) - *count = num_faces; - +bail: + if (face) + FT_Done_Face (face); FT_Done_FreeType (ftLibrary); return ret; -- GitLab