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.
This commit is contained in:
Idriss Fekir 2025-05-06 01:49:34 +02:00 committed by Jehan
parent f63e8afe60
commit 8328dfb25b
10 changed files with 170 additions and 145 deletions

View file

@ -279,5 +279,6 @@ libappcore = static_library('appcore',
math,
dl,
libunwind,
pango,
],
)

View file

@ -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",

View file

@ -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

View file

@ -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;

View file

@ -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 ("<fontconfig>");
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, "<match>");
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, "</fontconfig>");
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 ("<fontconfig>");
num_fonts_in_current_config = 0;
}
xml = g_string_append (xml, "<match>");
/*We can't use faux bold (sometimes real bold) unless it is specified in fontconfig*/
xml_bold_variant = g_string_append (xml_bold_variant, "<match>");
xml_italic_variant = g_string_append (xml_italic_variant, "<match>");
@ -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, "</fontconfig>");
#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, "</fontconfig>");
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;
}

View file

@ -22,6 +22,7 @@
#define __GIMP_FONT_FACTORY_H__
#include <pango/pango.h>
#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__ */

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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