From 8328dfb25b5f2947cb12cb562866d4414bcaaa2d Mon Sep 17 00:00:00 2001 From: Idriss Fekir Date: Tue, 6 May 2025 01:49:34 +0200 Subject: [PATCH] GimpFontFactory: Move font loading to another thread This is to make sure than regardless of how many fonts there are, font loading won't delay startup. FontConfig if compiled against libxml2 might fail to parse huge xml configs. So instead of passing it a huge xml, pass the xml every MAX_NUM_FONTS_PER_CONFIG (currently 1000) fonts. Also made GimpFontFactory custom config strings private because there is no reason for them to be public. --- app/core/meson.build | 1 + app/pdb/fonts-cmds.c | 31 ++++--- app/pdb/meson.build | 2 +- app/text/gimpfont.c | 72 ++++++---------- app/text/gimpfontfactory.c | 165 +++++++++++++++++++++++-------------- app/text/gimpfontfactory.h | 8 +- libgimp/gimpfont.c | 10 +-- libgimp/gimpfonts_pdb.c | 6 +- libgimp/gimpfonts_pdb.h | 2 +- pdb/groups/fonts.pdb | 18 ++-- 10 files changed, 170 insertions(+), 145 deletions(-) diff --git a/app/core/meson.build b/app/core/meson.build index 36fead6b32..a7430dafc0 100644 --- a/app/core/meson.build +++ b/app/core/meson.build @@ -279,5 +279,6 @@ libappcore = static_library('appcore', math, dl, libunwind, + pango, ], ) diff --git a/app/pdb/fonts-cmds.c b/app/pdb/fonts-cmds.c index df27a74e77..a1378eace4 100644 --- a/app/pdb/fonts-cmds.c +++ b/app/pdb/fonts-cmds.c @@ -68,7 +68,7 @@ fonts_get_custom_configs_invoker (GimpProcedure *procedure, GimpValueArray *return_vals; gchar *config = NULL; gchar *sysconfig = NULL; - gchar *renaming_config = NULL; + gchar **renaming_config = NULL; gchar **dirs = NULL; if (! gimp_data_factory_data_wait (gimp->font_factory)) @@ -76,9 +76,10 @@ fonts_get_custom_configs_invoker (GimpProcedure *procedure, if (success) { - GList *list = gimp_font_factory_get_custom_fonts_dirs (GIMP_FONT_FACTORY (gimp->font_factory)); - guint length = g_list_length (list); - gint i; + GList *list = gimp_font_factory_get_custom_fonts_dirs (GIMP_FONT_FACTORY (gimp->font_factory)); + GSList *fonts_renaming_config = gimp_font_factory_get_fonts_renaming_config (GIMP_FONT_FACTORY (gimp->font_factory)); + guint length = g_list_length (list); + gint i; gimp_font_factory_get_custom_config_path (GIMP_FONT_FACTORY (gimp->font_factory), &config, @@ -86,14 +87,19 @@ fonts_get_custom_configs_invoker (GimpProcedure *procedure, config = g_strdup (config); sysconfig = g_strdup (sysconfig); - renaming_config = g_strdup (gimp_font_factory_get_fonts_renaming_config (GIMP_FONT_FACTORY (gimp->font_factory))); - dirs = g_new0 (gchar *, length + 1); for (i = 0; list; list = g_list_next (list), i++) dirs[i] = g_file_get_path (list->data); g_list_free_full (list, (GDestroyNotify) g_object_unref); + + length = g_slist_length (fonts_renaming_config); + + renaming_config = g_new0 (gchar *, length + 1); + + for (i = 0; fonts_renaming_config; fonts_renaming_config = g_slist_next (fonts_renaming_config), i++) + renaming_config[i] = g_strdup (fonts_renaming_config->data); } return_vals = gimp_procedure_get_return_values (procedure, success, @@ -103,7 +109,7 @@ fonts_get_custom_configs_invoker (GimpProcedure *procedure, { g_value_take_string (gimp_value_array_index (return_vals, 1), config); g_value_take_string (gimp_value_array_index (return_vals, 2), sysconfig); - g_value_take_string (gimp_value_array_index (return_vals, 3), renaming_config); + g_value_take_boxed (gimp_value_array_index (return_vals, 3), renaming_config); g_value_take_boxed (gimp_value_array_index (return_vals, 4), dirs); } @@ -195,12 +201,11 @@ register_fonts_procs (GimpPDB *pdb) NULL, GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, - gimp_param_spec_string ("renaming-config", - "renaming config", - "fonts renaming config", - FALSE, FALSE, FALSE, - NULL, - GIMP_PARAM_READWRITE)); + g_param_spec_boxed ("renaming-config", + "renaming config", + "fonts renaming config", + G_TYPE_STRV, + GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, g_param_spec_boxed ("dirs", "dirs", diff --git a/app/pdb/meson.build b/app/pdb/meson.build index 02a83d69d4..a02af884e1 100644 --- a/app/pdb/meson.build +++ b/app/pdb/meson.build @@ -83,7 +83,7 @@ libappinternalprocs = static_library('appinternalprocs', include_directories: [ rootInclude, rootAppInclude, ], c_args: '-DG_LOG_DOMAIN="Gimp-PDB"', dependencies: [ - cairo, gegl, gdk_pixbuf, pangocairo, + cairo, gegl, gdk_pixbuf, pangocairo, pango, ], sources: [ pdbgen diff --git a/app/text/gimpfont.c b/app/text/gimpfont.c index 2e509c0554..8400e1bc07 100644 --- a/app/text/gimpfont.c +++ b/app/text/gimpfont.c @@ -85,8 +85,6 @@ struct _GimpFont { GimpData parent_instance; - PangoContext *pango_context; - PangoLayout *popup_layout; gint popup_width; gint popup_height; @@ -112,17 +110,13 @@ struct _GimpFont struct _GimpFontClass { - GimpDataClass parent_class; + GimpDataClass parent_class; - GimpContainer *fonts_container; + GimpFontFactory *font_factory; }; static void gimp_font_finalize (GObject *object); -static void gimp_font_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); static void gimp_font_get_preview_size (GimpViewable *viewable, gint size, @@ -240,9 +234,9 @@ gimp_font_deserialize_create (GType type, gpointer data) { GimpFont *font = NULL; - GimpContainer *fonts_container = GIMP_FONT_CLASS (g_type_class_peek (GIMP_TYPE_FONT))->fonts_container; + GimpContainer *fonts_container; gint most_similar_font_index = -1; - gint font_count = gimp_container_get_n_children (fonts_container); + gint font_count; gint largest_similarity = 0; GList *similar_fonts = NULL; GList *iter; @@ -260,6 +254,8 @@ gimp_font_deserialize_create (GType type, guint scope_id; guint old_scope_id; + fonts_container = gimp_data_factory_get_container (GIMP_DATA_FACTORY (GIMP_FONT_CLASS (g_type_class_peek (GIMP_TYPE_FONT))->font_factory)); + font_count = gimp_container_get_n_children (fonts_container); /* This is for backward compatibility with older xcf files. * The font used to be serialized as a string containing * its name. @@ -540,7 +536,7 @@ gimp_font_class_set_font_factory (GimpFontFactory *factory) g_return_if_fail (GIMP_IS_FONT_FACTORY (factory)); - klass->fonts_container = gimp_data_factory_get_container (GIMP_DATA_FACTORY (factory)); + klass->font_factory = factory; } void @@ -596,7 +592,6 @@ gimp_font_class_init (GimpFontClass *klass) GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass); object_class->finalize = gimp_font_finalize; - object_class->set_property = gimp_font_set_property; gimp_object_class->get_memsize = gimp_font_get_memsize; viewable_class->get_preview_size = gimp_font_get_preview_size; @@ -604,12 +599,6 @@ gimp_font_class_init (GimpFontClass *klass) viewable_class->get_new_preview = gimp_font_get_new_preview; viewable_class->default_icon_name = "gtk-select-font"; - - g_object_class_install_property (object_class, PROP_PANGO_CONTEXT, - g_param_spec_object ("pango-context", - NULL, NULL, - PANGO_TYPE_CONTEXT, - GIMP_PARAM_WRITABLE)); } static void @@ -622,7 +611,6 @@ gimp_font_finalize (GObject *object) { GimpFont *font = GIMP_FONT (object); - g_clear_object (&font->pango_context); g_clear_object (&font->popup_layout); g_free (font->lookup_name); g_free (font->hash); @@ -637,28 +625,6 @@ gimp_font_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } -static void -gimp_font_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GimpFont *font = GIMP_FONT (object); - - switch (property_id) - { - case PROP_PANGO_CONTEXT: - if (font->pango_context) - g_object_unref (font->pango_context); - font->pango_context = g_value_dup_object (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - static gint64 gimp_font_get_memsize (GimpObject *object, gint64 *gui_size) @@ -701,12 +667,15 @@ gimp_font_get_popup_size (GimpViewable *viewable, gint *popup_height) { GimpFont *font = GIMP_FONT (viewable); + PangoContext *pango_context; PangoFontDescription *font_desc; PangoRectangle ink; PangoRectangle logical; const gchar *name; - if (! font->pango_context) + pango_context = gimp_font_factory_get_pango_context (GIMP_FONT_CLASS (g_type_class_peek (GIMP_TYPE_FONT))->font_factory); + + if (! pango_context) return FALSE; name = font->lookup_name; @@ -719,7 +688,7 @@ gimp_font_get_popup_size (GimpViewable *viewable, if (font->popup_layout) g_object_unref (font->popup_layout); - font->popup_layout = pango_layout_new (font->pango_context); + font->popup_layout = pango_layout_new (pango_context); pango_layout_set_font_description (font->popup_layout, font_desc); pango_font_description_free (font_desc); @@ -744,6 +713,7 @@ gimp_font_get_new_preview (GimpViewable *viewable, gint height) { GimpFont *font = GIMP_FONT (viewable); + PangoContext *pango_context; PangoLayout *layout; PangoRectangle ink; PangoRectangle logical; @@ -755,7 +725,9 @@ gimp_font_get_new_preview (GimpViewable *viewable, cairo_t *cr; cairo_surface_t *surface; - if (! font->pango_context) + pango_context = gimp_font_factory_get_pango_context (GIMP_FONT_CLASS (g_type_class_peek (GIMP_TYPE_FONT))->font_factory); + + if (! pango_context) return NULL; if (! font->popup_layout || @@ -774,11 +746,11 @@ gimp_font_get_new_preview (GimpViewable *viewable, pango_font_description_set_size (font_desc, PANGO_SCALE * height * 2.0 / 3.0); - layout = pango_layout_new (font->pango_context); + layout = pango_layout_new (pango_context); pango_layout_set_font_description (layout, font_desc); pango_layout_set_text (layout, - gimp_font_get_sample_string (font->pango_context, + gimp_font_get_sample_string (pango_context, font_desc), -1); @@ -1369,9 +1341,11 @@ gimp_font_get_hash (GimpFont *font) */ if (font->hash == NULL) { - PangoFontDescription *pfd = pango_font_description_from_string (font->lookup_name); - PangoFcFont *pango_font = PANGO_FC_FONT (pango_context_load_font (font->pango_context, pfd)); - GChecksum *checksum = g_checksum_new (G_CHECKSUM_SHA256); + PangoFontDescription *pfd = pango_font_description_from_string (font->lookup_name); + GimpFontFactory *font_factory = GIMP_FONT_CLASS (g_type_class_peek (GIMP_TYPE_FONT))->font_factory; + PangoContext *pango_context = gimp_font_factory_get_pango_context (font_factory); + PangoFcFont *pango_font = PANGO_FC_FONT (pango_context_load_font (pango_context, pfd)); + GChecksum *checksum = g_checksum_new (G_CHECKSUM_SHA256); gchar *file; hb_blob_t *hb_blob; guint length; diff --git a/app/text/gimpfontfactory.c b/app/text/gimpfontfactory.c index 3896f5619b..67d026cf14 100644 --- a/app/text/gimpfontfactory.c +++ b/app/text/gimpfontfactory.c @@ -55,7 +55,10 @@ struct _GimpFontFactoryPrivate { - gpointer foo; /* can't have an empty struct */ + GSList *fonts_renaming_config; + gchar *conf; + gchar *sysconf; + PangoContext *pango_context; }; #define GET_PRIVATE(obj) (((GimpFontFactory *) (obj))->priv) @@ -87,11 +90,10 @@ static void gimp_font_factory_recursive_add_fontdir (FcConfig *config, GFile *file, GError **error); -static void gimp_font_factory_load_names (GimpFontFactory *container, - PangoFontMap *fontmap, +static int gimp_font_factory_load_names (GimpFontFactory *container); +static void gimp_font_factory_load_aliases (GimpContainer *container, PangoContext *context); - G_DEFINE_TYPE_WITH_PRIVATE (GimpFontFactory, gimp_font_factory, GIMP_TYPE_DATA_FACTORY) @@ -207,9 +209,11 @@ gimp_font_factory_finalize (GObject *object) { GimpFontFactory *font_factory = GIMP_FONT_FACTORY(object); - g_free (font_factory->fonts_renaming_config); - g_free (font_factory->sysconf); - g_free (font_factory->conf); + g_slist_free_full (GET_PRIVATE (font_factory)->fonts_renaming_config, (GDestroyNotify) g_free); + g_free (GET_PRIVATE (font_factory)->sysconf); + g_free (GET_PRIVATE (font_factory)->conf); + g_object_unref (GET_PRIVATE (font_factory)->pango_context); + FcConfigDestroy (FcConfigGetCurrent ()); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -244,29 +248,35 @@ gimp_font_factory_get_custom_config_path (GimpFontFactory *factory, gchar **conf, gchar **sysconf) { - *conf = factory->conf; - *sysconf = factory->sysconf; + *conf = GET_PRIVATE (factory)->conf; + *sysconf = GET_PRIVATE (factory)->sysconf; } -gchar * +GSList * gimp_font_factory_get_fonts_renaming_config (GimpFontFactory *factory) { - return factory->fonts_renaming_config; + return (GET_PRIVATE (factory))->fonts_renaming_config; +} + +PangoContext * +gimp_font_factory_get_pango_context (GimpFontFactory *factory) +{ + return GET_PRIVATE (factory)->pango_context; } /* private functions */ static void -gimp_font_factory_load_async (GimpAsync *async, - FcConfig *config) +gimp_font_factory_load_async (GimpAsync *async, + GimpFontFactory *factory) { - if (FcConfigBuildFonts (config)) + if (FcConfigBuildFonts (NULL)) { - gimp_async_finish (async, config); + gimp_async_finish (async, GINT_TO_POINTER (gimp_font_factory_load_names (factory))); } else { - FcConfigDestroy (config); + FcConfigDestroy (FcConfigGetCurrent ()); gimp_async_abort (async); } @@ -288,12 +298,10 @@ gimp_font_factory_load_async_callback (GimpAsync *async, if (gimp_async_is_finished (async)) { - FcConfig *config = gimp_async_get_result (async); + gint num_fonts = GPOINTER_TO_INT (gimp_async_get_result (async)); PangoFontMap *fontmap; PangoContext *context; - FcConfigSetCurrent (config); - fontmap = pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT); if (! fontmap) g_error ("You are using a Pango that has been built against a cairo " @@ -302,11 +310,12 @@ gimp_font_factory_load_async_callback (GimpAsync *async, pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (fontmap), 72.0 /* FIXME */); context = pango_font_map_create_context (fontmap); + GET_PRIVATE (factory)->pango_context = context; g_object_unref (fontmap); - gimp_font_factory_load_names (factory, PANGO_FONT_MAP (fontmap), context); - g_object_unref (context); - FcConfigDestroy (config); + /* only create aliases if there is at least one font available */ + if (num_fonts > 0) + gimp_font_factory_load_aliases (container, context); } gimp_container_thaw (container); @@ -352,8 +361,8 @@ gimp_font_factory_load (GimpFontFactory *factory, } else { - g_free (factory->conf); - factory->conf = g_file_get_path (fonts_conf); + g_free (GET_PRIVATE (factory)->conf); + GET_PRIVATE (factory)->conf = g_file_get_path (fonts_conf); } g_object_unref (fonts_conf); @@ -366,8 +375,8 @@ gimp_font_factory_load (GimpFontFactory *factory, } else { - g_free (factory->sysconf); - factory->sysconf = g_file_get_path (fonts_conf); + g_free (GET_PRIVATE (factory)->sysconf); + GET_PRIVATE (factory)->sysconf = g_file_get_path (fonts_conf); } g_object_unref (fonts_conf); @@ -382,6 +391,7 @@ gimp_font_factory_load (GimpFontFactory *factory, gimp_font_factory_add_directories (factory, config, path, error); g_list_free_full (path, (GDestroyNotify) g_object_unref); + FcConfigSetCurrent (config); /* We perform font cache initialization in a separate thread, so * in the case a cache rebuild is to be done it will not block * the UI. @@ -389,7 +399,7 @@ gimp_font_factory_load (GimpFontFactory *factory, async = gimp_parallel_run_async_independent_full ( +10, (GimpRunAsyncFunc) gimp_font_factory_load_async, - config); + factory); gimp_async_add_callback_for_object ( async, @@ -591,7 +601,6 @@ gimp_font_factory_recursive_add_fontdir (FcConfig *config, static void gimp_font_factory_add_font (GimpContainer *container, - PangoContext *context, PangoFontDescription *desc, const gchar *full_name, const gchar *path, @@ -616,7 +625,6 @@ gimp_font_factory_add_font (GimpContainer *container, font = g_object_new (GIMP_TYPE_FONT, "name", name, - "pango-context", context, NULL); gimp_font_set_lookup_name (font, pango_font_description_to_string (desc)); @@ -717,7 +725,7 @@ gimp_font_factory_make_alias (GimpContainer *container, * are the best way to have differing text renders over time (and that's not * something to be wished for). XXX */ - gimp_font_factory_add_font (container, context, desc, NULL, NULL, font_info); + gimp_font_factory_add_font (container, desc, NULL, NULL, font_info); g_free (desc_str); pango_font_description_free (desc); @@ -743,10 +751,8 @@ gimp_font_factory_load_aliases (GimpContainer *container, } } -static void -gimp_font_factory_load_names (GimpFontFactory *factory, - PangoFontMap *fontmap, - PangoContext *context) +static gint +gimp_font_factory_load_names (GimpFontFactory *factory) { GimpContainer *container; FcObjectSet *os; @@ -761,6 +767,8 @@ gimp_font_factory_load_names (GimpFontFactory *factory, GString *ignored_fonts; gint n_ignored = 0; gint i; + gint num_fonts_in_current_config = 0; + gint n_loaded_fonts = 0; container = gimp_data_factory_get_container (GIMP_DATA_FACTORY (factory)); @@ -775,20 +783,20 @@ gimp_font_factory_load_names (GimpFontFactory *factory, FC_INDEX, FC_FONTVERSION, NULL); - g_return_if_fail (os); + g_return_val_if_fail (os, -1); pat = FcPatternCreate (); if (! pat) { FcObjectSetDestroy (os); g_critical ("%s: FcPatternCreate() returned NULL.", G_STRFUNC); - return; + return -1; } - if (FT_Init_FreeType(&ft)) + if (FT_Init_FreeType (&ft)) { - g_critical ("%s: FreeType Initialization Failed.", G_STRFUNC); - return -1; + g_critical ("%s: FreeType Initialization Failed.", G_STRFUNC); + return -1; } fontset = FcFontList (NULL, pat, os); @@ -796,7 +804,7 @@ gimp_font_factory_load_names (GimpFontFactory *factory, FcPatternDestroy (pat); FcObjectSetDestroy (os); - g_return_if_fail (fontset); + g_return_val_if_fail (fontset, -1); xml_configs_list = NULL; xml = g_string_new (NULL); @@ -805,6 +813,8 @@ gimp_font_factory_load_names (GimpFontFactory *factory, xml_bold_italic_variant_and_global = g_string_new (""); ignored_fonts = g_string_new (NULL); +#define MAX_NUM_FONTS_PER_CONFIG 1000 + for (i = 0; i < fontset->nfont; i++) { PangoFontDescription *pfd; @@ -836,7 +846,7 @@ gimp_font_factory_load_names (GimpFontFactory *factory, continue; } - if (FT_New_Face(ft, file, 0, &face)) + if (FT_New_Face (ft, file, 0, &face)) { g_string_append_printf (ignored_fonts, "- %s (Failed To Create A FreeType Face)\n", file); n_ignored++; @@ -852,8 +862,7 @@ gimp_font_factory_load_names (GimpFontFactory *factory, */ if (face->face_flags & FT_FACE_FLAG_SFNT) { - /* If this is an SFNT wrapper, try to sniff the SFNT tag which is the - * first 4 bytes, to see if it is a WOFF or WOFF2 wrapper. */ + /* If this is an SFNT wrapper, read the first 4 bytes to see if it is a WOFF[2] font. */ char buf[4] = {0}; int fd = g_open ((gchar *) file, O_RDONLY, 0); @@ -861,7 +870,7 @@ gimp_font_factory_load_names (GimpFontFactory *factory, g_close (fd, NULL); FT_Done_Face (face); - if (buf[0] == 'w' && buf[1] == 'O' && buf[2] == 'F') + if (buf[0] == 'w' && buf[1] == 'O' && buf[2] == 'F' && (buf[3] == 'F' || buf[3] == '2')) { g_string_append_printf (ignored_fonts, "- %s (WOFF[2] font)\n", file); n_ignored++; @@ -914,8 +923,31 @@ gimp_font_factory_load_names (GimpFontFactory *factory, newname = g_strdup_printf ("gimpfont%i", i); - xml = g_string_append (xml, ""); + if (num_fonts_in_current_config == MAX_NUM_FONTS_PER_CONFIG) + { + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, xml_italic_variant->str); + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, xml_bold_variant->str); + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, xml->str); + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, ""); + xml_configs_list = g_slist_append (xml_configs_list, xml_bold_italic_variant_and_global->str); + + FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), (const FcChar8 *) xml_bold_italic_variant_and_global->str, FcTrue); + + g_string_free (xml, TRUE); + g_string_free (xml_italic_variant, TRUE); + g_string_free (xml_bold_variant, TRUE); + g_string_free (xml_bold_italic_variant_and_global, FALSE); + + xml = g_string_new (NULL); + xml_italic_variant = g_string_new (NULL); + xml_bold_variant = g_string_new (NULL); + xml_bold_italic_variant_and_global = g_string_new (""); + + num_fonts_in_current_config = 0; + } + + xml = g_string_append (xml, ""); /*We can't use faux bold (sometimes real bold) unless it is specified in fontconfig*/ xml_bold_variant = g_string_append (xml_bold_variant, ""); xml_italic_variant = g_string_append (xml_italic_variant, ""); @@ -1072,34 +1104,43 @@ gimp_font_factory_load_names (GimpFontFactory *factory, if (display_name != NULL) { - gimp_font_factory_add_font (container, context, pfd, display_name, (const gchar *) file, font_info); + gimp_font_factory_add_font (container, pfd, display_name, (const gchar *) file, font_info); g_free (display_name); } else { - gimp_font_factory_add_font (container, context, pfd, fullname, (const gchar *) file, font_info); + gimp_font_factory_add_font (container, pfd, fullname, (const gchar *) file, font_info); } pango_font_description_free (pattern_pfd); g_free (pattern_pfd_desc); pango_font_description_free (pfd); g_free (newname); + num_fonts_in_current_config++; } - g_string_append (xml_bold_italic_variant_and_global, xml_italic_variant->str); - g_string_append (xml_bold_italic_variant_and_global, xml_bold_variant->str); - g_string_append (xml_bold_italic_variant_and_global, xml->str); - g_string_append (xml_bold_italic_variant_and_global, ""); +#undef MAX_NUM_FONTS_PER_CONFIG - g_free (factory->fonts_renaming_config); + if (num_fonts_in_current_config > 0) + { + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, xml_italic_variant->str); + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, xml_bold_variant->str); + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, xml->str); + xml_bold_italic_variant_and_global = g_string_append (xml_bold_italic_variant_and_global, ""); - FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), (const FcChar8 *) xml_bold_italic_variant_and_global->str, FcTrue); + xml_configs_list = g_slist_append (xml_configs_list, xml_bold_italic_variant_and_global->str); - factory->fonts_renaming_config = xml_bold_italic_variant_and_global->str; + FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), (const FcChar8 *) xml_bold_italic_variant_and_global->str, FcTrue); - /* only create aliases if there is at least one font available */ - if (fontset->nfont > 0) - gimp_font_factory_load_aliases (container, context); + g_string_free (xml, TRUE); + g_string_free (xml_italic_variant, TRUE); + g_string_free (xml_bold_variant, TRUE); + g_string_free (xml_bold_italic_variant_and_global, FALSE); + } + + g_slist_free_full (GET_PRIVATE (factory)->fonts_renaming_config, (GDestroyNotify) g_free); + + GET_PRIVATE (factory)->fonts_renaming_config = xml_configs_list; if (n_ignored > 0) { @@ -1111,11 +1152,11 @@ gimp_font_factory_load_names (GimpFontFactory *factory, #endif } + n_loaded_fonts = fontset->nfont - n_ignored; + g_string_free (ignored_fonts, TRUE); - g_string_free (xml, TRUE); - g_string_free (xml_italic_variant, TRUE); - g_string_free (xml_bold_variant, TRUE); - g_string_free (xml_bold_italic_variant_and_global, FALSE); - FT_Done_FreeType(ft); + FT_Done_FreeType (ft); FcFontSetDestroy (fontset); + + return n_loaded_fonts; } diff --git a/app/text/gimpfontfactory.h b/app/text/gimpfontfactory.h index b42df2ac4d..77a82ea79b 100644 --- a/app/text/gimpfontfactory.h +++ b/app/text/gimpfontfactory.h @@ -22,6 +22,7 @@ #define __GIMP_FONT_FACTORY_H__ +#include #include "core/gimpdatafactory.h" @@ -40,10 +41,6 @@ struct _GimpFontFactory { GimpDataFactory parent_instance; - gchar *fonts_renaming_config; - gchar *conf; - gchar *sysconf; - GimpFontFactoryPrivate *priv; }; @@ -61,7 +58,8 @@ GList * gimp_font_factory_get_custom_fonts_dirs (GimpFontFactory void gimp_font_factory_get_custom_config_path (GimpFontFactory *factory, gchar **conf, gchar **sysconf); -gchar * gimp_font_factory_get_fonts_renaming_config (GimpFontFactory *factory); +GSList * gimp_font_factory_get_fonts_renaming_config (GimpFontFactory *factory); +PangoContext * gimp_font_factory_get_pango_context (GimpFontFactory *factory); #endif /* __GIMP_FONT_FACTORY_H__ */ diff --git a/libgimp/gimpfont.c b/libgimp/gimpfont.c index b9a87fec6f..186a1a1c90 100644 --- a/libgimp/gimpfont.c +++ b/libgimp/gimpfont.c @@ -63,7 +63,7 @@ gimp_font_get_pango_font_description (GimpFont *font) { gchar *config; gchar *sysconfig; - gchar *fonts_renaming_config; + gchar **fonts_renaming_config; gchar **dirs; FcConfigSetCurrent (FcInitLoadConfig ()); @@ -82,11 +82,11 @@ gimp_font_get_pango_font_description (GimpFont *font) if (dirs[i]) FcConfigAppFontAddDir (FcConfigGetCurrent (), (const FcChar8 *)dirs[i]); - FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), - (const FcChar8 *) fonts_renaming_config, - FcTrue); + for (int i = 0; fonts_renaming_config[i] != NULL; ++i) + if (fonts_renaming_config[i]) + FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (), (const FcChar8 *)fonts_renaming_config[i], FcTrue); - g_free (fonts_renaming_config); + g_strfreev (fonts_renaming_config); g_free (sysconfig); g_free (config); g_strfreev (dirs); diff --git a/libgimp/gimpfonts_pdb.c b/libgimp/gimpfonts_pdb.c index d959731a15..ebf8b4136e 100644 --- a/libgimp/gimpfonts_pdb.c +++ b/libgimp/gimpfonts_pdb.c @@ -72,7 +72,7 @@ gimp_fonts_refresh (void) /** * _gimp_fonts_get_custom_configs: * @sysconfig: (out) (transfer full): sysconfig path. - * @renaming_config: (out) (transfer full): fonts renaming config. + * @renaming_config: (out) (array zero-terminated=1) (transfer full): fonts renaming config. * @dirs: (out) (array zero-terminated=1) (transfer full): custom fonts directories. * * Retrieve custom configs. @@ -87,7 +87,7 @@ gimp_fonts_refresh (void) **/ gchar * _gimp_fonts_get_custom_configs (gchar **sysconfig, - gchar **renaming_config, + gchar ***renaming_config, gchar ***dirs) { GimpValueArray *args; @@ -106,7 +106,7 @@ _gimp_fonts_get_custom_configs (gchar **sysconfig, { config = GIMP_VALUES_DUP_STRING (return_vals, 1); *sysconfig = GIMP_VALUES_DUP_STRING (return_vals, 2); - *renaming_config = GIMP_VALUES_DUP_STRING (return_vals, 3); + *renaming_config = GIMP_VALUES_DUP_STRV (return_vals, 3); *dirs = GIMP_VALUES_DUP_STRV (return_vals, 4); } diff --git a/libgimp/gimpfonts_pdb.h b/libgimp/gimpfonts_pdb.h index 2e3ccb20ad..5496525bf3 100644 --- a/libgimp/gimpfonts_pdb.h +++ b/libgimp/gimpfonts_pdb.h @@ -34,7 +34,7 @@ G_BEGIN_DECLS gboolean gimp_fonts_refresh (void); G_GNUC_INTERNAL gchar* _gimp_fonts_get_custom_configs (gchar **sysconfig, - gchar **renaming_config, + gchar ***renaming_config, gchar ***dirs); GimpFont** gimp_fonts_get_list (const gchar *filter); diff --git a/pdb/groups/fonts.pdb b/pdb/groups/fonts.pdb index a0c0487a45..57bdfe29b7 100644 --- a/pdb/groups/fonts.pdb +++ b/pdb/groups/fonts.pdb @@ -137,7 +137,7 @@ HELP desc => 'config path' }, { name => 'sysconfig', type => 'string', desc => 'sysconfig path' }, - { name => 'renaming_config', type => 'string', + { name => 'renaming_config', type => 'strv', desc => 'fonts renaming config' }, { name => 'dirs', type => 'strv', desc => 'custom fonts directories' } @@ -152,9 +152,10 @@ HELP if (success) { - GList *list = gimp_font_factory_get_custom_fonts_dirs (GIMP_FONT_FACTORY (gimp->font_factory)); - guint length = g_list_length (list); - gint i; + GList *list = gimp_font_factory_get_custom_fonts_dirs (GIMP_FONT_FACTORY (gimp->font_factory)); + GSList *fonts_renaming_config = gimp_font_factory_get_fonts_renaming_config (GIMP_FONT_FACTORY (gimp->font_factory)); + guint length = g_list_length (list); + gint i; gimp_font_factory_get_custom_config_path (GIMP_FONT_FACTORY (gimp->font_factory), @@ -163,14 +164,19 @@ HELP config = g_strdup (config); sysconfig = g_strdup (sysconfig); - renaming_config = g_strdup (gimp_font_factory_get_fonts_renaming_config (GIMP_FONT_FACTORY (gimp->font_factory))); - dirs = g_new0 (gchar *, length + 1); for (i = 0; list; list = g_list_next (list), i++) dirs[i] = g_file_get_path (list->data); g_list_free_full (list, (GDestroyNotify) g_object_unref); + + length = g_slist_length (fonts_renaming_config); + + renaming_config = g_new0 (gchar *, length + 1); + + for (i = 0; fonts_renaming_config; fonts_renaming_config = g_slist_next (fonts_renaming_config), i++) + renaming_config[i] = g_strdup (fonts_renaming_config->data); } } CODE