Fix fonts when exporting to pdf

This commit is contained in:
Idriss Fekir 2023-11-11 13:29:06 +01:00 committed by Jehan
parent 588c98eb3f
commit e8ad8af0f7
12 changed files with 469 additions and 51 deletions

View File

@ -39,6 +39,35 @@
#include "internal-procs.h"
static GimpValueArray *
font_get_lookup_name_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpValueArray *return_vals;
GimpFont *font;
gchar *lookup_name = NULL;
font = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
lookup_name = g_strdup (gimp_font_get_lookup_name (font));
}
return_vals = gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
if (success)
g_value_take_string (gimp_value_array_index (return_vals, 1), lookup_name);
return return_vals;
}
static GimpValueArray *
font_get_by_name_invoker (GimpProcedure *procedure,
Gimp *gimp,
@ -127,6 +156,36 @@ register_font_procs (GimpPDB *pdb)
{
GimpProcedure *procedure;
/*
* gimp-font-get-lookup-name
*/
procedure = gimp_procedure_new (font_get_lookup_name_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-font-get-lookup-name");
gimp_procedure_set_static_help (procedure,
"Retrieve the font lookup name.",
"Retrieve the font lookup name.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"",
"",
"");
gimp_procedure_add_argument (procedure,
gimp_param_spec_font ("font",
"font",
"GimpFont object",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("lookup-name",
"lookup name",
"font lookup name",
FALSE, FALSE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-font-get-by-name
*/

View File

@ -34,6 +34,7 @@
#include "core/gimpcontainer.h"
#include "core/gimpdatafactory.h"
#include "core/gimpparamspecs.h"
#include "text/gimpfontfactory.h"
#include "gimppdb.h"
#include "gimpprocedure.h"
@ -54,6 +55,60 @@ fonts_refresh_invoker (GimpProcedure *procedure,
return gimp_procedure_get_return_values (procedure, TRUE, NULL);
}
static GimpValueArray *
fonts_get_custom_configs_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpValueArray *return_vals;
gchar *config = NULL;
gchar *sysconfig = NULL;
gchar *renaming_config = NULL;
gchar **dirs = NULL;
if (! gimp_data_factory_data_wait (gimp->font_factory))
success = FALSE;
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;
gimp_font_factory_get_custom_config_path (GIMP_FONT_FACTORY (gimp->font_factory),
&config,
&sysconfig);
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);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
if (success)
{
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, 4), dirs);
}
return return_vals;
}
static GimpValueArray *
fonts_get_list_invoker (GimpProcedure *procedure,
Gimp *gimp,
@ -112,6 +167,50 @@ register_fonts_procs (GimpPDB *pdb)
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-fonts-get-custom-configs
*/
procedure = gimp_procedure_new (fonts_get_custom_configs_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-fonts-get-custom-configs");
gimp_procedure_set_static_help (procedure,
"Retrieve custom configs.",
"This procedure returns custom FontConfig configs along with the fonts renaming config.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"",
"",
"");
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("config",
"config",
"config path",
FALSE, FALSE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("sysconfig",
"sysconfig",
"sysconfig path",
FALSE, FALSE, FALSE,
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));
gimp_procedure_add_return_value (procedure,
g_param_spec_boxed ("dirs",
"dirs",
"custom fonts directories",
G_TYPE_STRV,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-fonts-get-list
*/

View File

@ -30,7 +30,7 @@
#include "internal-procs.h"
/* 779 procedures registered total */
/* 781 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)

View File

@ -71,19 +71,21 @@ static gboolean gimp_font_factory_data_delete (GimpDataFactory *factory,
GimpData *data,
gboolean delete_from_disk,
GError **error);
static void gimp_font_factory_finalize (GObject *object);
static void gimp_font_factory_load (GimpFontFactory *factory,
GError **error);
static gboolean gimp_font_factory_load_fonts_conf (FcConfig *config,
GFile *fonts_conf);
static void gimp_font_factory_add_directories (FcConfig *config,
static void gimp_font_factory_add_directories (GimpFontFactory *factory,
FcConfig *config,
GList *path,
GError **error);
static void gimp_font_factory_recursive_add_fontdir
(FcConfig *config,
GFile *file,
GError **error);
static void gimp_font_factory_load_names (GimpContainer *container,
static void gimp_font_factory_load_names (GimpFontFactory *container,
PangoFontMap *fontmap,
PangoContext *context);
@ -97,8 +99,11 @@ G_DEFINE_TYPE_WITH_PRIVATE (GimpFontFactory, gimp_font_factory,
static void
gimp_font_factory_class_init (GimpFontFactoryClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpDataFactoryClass *factory_class = GIMP_DATA_FACTORY_CLASS (klass);
object_class->finalize = gimp_font_factory_finalize;
factory_class->data_init = gimp_font_factory_data_init;
factory_class->data_refresh = gimp_font_factory_data_refresh;
factory_class->data_save = gimp_font_factory_data_save;
@ -195,6 +200,18 @@ gimp_font_factory_data_delete (GimpDataFactory *factory,
return TRUE;
}
static void
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_OBJECT_CLASS (parent_class)->finalize (object);
}
/* public functions */
@ -214,6 +231,26 @@ gimp_font_factory_new (Gimp *gimp,
NULL);
}
GList *
gimp_font_factory_get_custom_fonts_dirs (GimpFontFactory *factory)
{
return gimp_data_factory_get_data_path (GIMP_DATA_FACTORY (factory));
}
void
gimp_font_factory_get_custom_config_path (GimpFontFactory *factory,
gchar **conf,
gchar **sysconf)
{
*conf = factory->conf;
*sysconf = factory->sysconf;
}
gchar *
gimp_font_factory_get_fonts_renaming_config (GimpFontFactory *factory)
{
return factory->fonts_renaming_config;
}
/* private functions */
@ -265,7 +302,7 @@ gimp_font_factory_load_async_callback (GimpAsync *async,
context = pango_font_map_create_context (fontmap);
g_object_unref (fontmap);
gimp_font_factory_load_names (container, PANGO_FONT_MAP (fontmap), context);
gimp_font_factory_load_names (factory, PANGO_FONT_MAP (fontmap), context);
g_object_unref (context);
FcConfigDestroy (config);
}
@ -307,14 +344,30 @@ gimp_font_factory_load (GimpFontFactory *factory,
fonts_conf = gimp_directory_file (CONF_FNAME, NULL);
if (! gimp_font_factory_load_fonts_conf (config, fonts_conf))
g_printerr ("%s: failed to read '%s'.\n",
G_STRFUNC, g_file_peek_path (fonts_conf));
{
g_printerr ("%s: failed to read '%s'.\n",
G_STRFUNC, g_file_peek_path (fonts_conf));
}
else
{
g_free (factory->conf);
factory->conf = g_file_get_path (fonts_conf);
}
g_object_unref (fonts_conf);
fonts_conf = gimp_sysconf_directory_file (CONF_FNAME, NULL);
if (! gimp_font_factory_load_fonts_conf (config, fonts_conf))
g_printerr ("%s: failed to read '%s'.\n",
G_STRFUNC, g_file_peek_path (fonts_conf));
{
g_printerr ("%s: failed to read '%s'.\n",
G_STRFUNC, g_file_peek_path (fonts_conf));
}
else
{
g_free (factory->sysconf);
factory->sysconf = g_file_get_path (fonts_conf);
}
g_object_unref (fonts_conf);
path = gimp_data_factory_get_data_path (GIMP_DATA_FACTORY (factory));
@ -324,7 +377,7 @@ gimp_font_factory_load (GimpFontFactory *factory,
gimp_container_freeze (container);
gimp_container_clear (container);
gimp_font_factory_add_directories (config, path, error);
gimp_font_factory_add_directories (factory, config, path, error);
g_list_free_full (path, (GDestroyNotify) g_object_unref);
/* We perform font cache initialization in a separate thread, so
@ -363,9 +416,10 @@ gimp_font_factory_load_fonts_conf (FcConfig *config,
}
static void
gimp_font_factory_add_directories (FcConfig *config,
GList *path,
GError **error)
gimp_font_factory_add_directories (GimpFontFactory *factory,
FcConfig *config,
GList *path,
GError **error)
{
GList *list;
@ -655,16 +709,20 @@ gimp_font_factory_load_aliases (GimpContainer *container,
}
static void
gimp_font_factory_load_names (GimpContainer *container,
PangoFontMap *fontmap,
PangoContext *context)
gimp_font_factory_load_names (GimpFontFactory *factory,
PangoFontMap *fontmap,
PangoContext *context)
{
FcObjectSet *os;
FcPattern *pat;
FcFontSet *fontset;
GString *ignored_fonts;
gint n_ignored = 0;
gint i;
GimpContainer *container;
FcObjectSet *os;
FcPattern *pat;
FcFontSet *fontset;
GString *ignored_fonts;
GString *global_xml = g_string_new ("<fontconfig>\n");
gint n_ignored = 0;
gint i;
container = gimp_data_factory_get_container (GIMP_DATA_FACTORY (factory));
os = FcObjectSetBuild (FC_FAMILY,
FC_STYLE,
@ -791,7 +849,7 @@ gimp_font_factory_load_names (GimpContainer *container,
newname = g_strdup_printf ("gimpfont%i", i);
xml = g_string_new ("<?xml version=\"1.0\"?>\n<match>");
xml = g_string_new ("<match>");
/*We can't use faux bold (sometimes real bold) unless it is specified in fontconfig*/
xml_bold_variant = g_string_new ("<?xml version=\"1.0\"?>\n<match>");
@ -917,6 +975,8 @@ gimp_font_factory_load_names (GimpContainer *container,
gimp_font_factory_add_font (container, context, pfd, fullname, (const gchar *) file, font_info);
g_string_append (global_xml, xml->str);
pango_font_description_free (pattern_pfd);
g_free (pattern_pfd_desc);
pango_font_description_free (pfd);
@ -925,6 +985,11 @@ gimp_font_factory_load_names (GimpContainer *container,
g_string_free (xml_bold_variant, TRUE);
}
g_string_append (global_xml, "</fontconfig>");
g_free (factory->fonts_renaming_config);
factory->fonts_renaming_config = g_strdup (global_xml->str);
if (n_ignored > 0)
{
if (g_getenv ("GIMP_DEBUG_FONTS") == NULL)
@ -934,6 +999,7 @@ gimp_font_factory_load_names (GimpContainer *container,
}
g_string_free (ignored_fonts, TRUE);
g_string_free (global_xml, TRUE);
/* only create aliases if there is at least one font available */
if (fontset->nfont > 0)

View File

@ -40,6 +40,10 @@ struct _GimpFontFactory
{
GimpDataFactory parent_instance;
gchar *fonts_renaming_config;
gchar *conf;
gchar *sysconf;
GimpFontFactoryPrivate *priv;
};
@ -51,8 +55,13 @@ struct _GimpFontFactoryClass
GType gimp_font_factory_get_type (void) G_GNUC_CONST;
GimpDataFactory * gimp_font_factory_new (Gimp *gimp,
const gchar *path_property_name);
GimpDataFactory * gimp_font_factory_new (Gimp *gimp,
const gchar *path_property_name);
GList * gimp_font_factory_get_custom_fonts_dirs (GimpFontFactory *factory);
void gimp_font_factory_get_custom_config_path (GimpFontFactory *factory,
gchar **conf,
gchar **sysconf);
gchar * gimp_font_factory_get_fonts_renaming_config (GimpFontFactory *factory);
#endif /* __GIMP_FONT_FACTORY_H__ */

View File

@ -56,31 +56,45 @@ static void gimp_font_init (GimpFont *font)
PangoFontDescription *
gimp_font_get_pango_font_description (GimpFont *font)
{
PangoFontDescription *desc = NULL;
gchar *name = NULL;
gchar *collection_id = NULL;
gboolean is_internal;
static gboolean fc_configs_loaded = FALSE;
PangoFontDescription *desc = NULL;
is_internal = _gimp_resource_get_identifiers (GIMP_RESOURCE (font),
&name, &collection_id);
/* TODO: we can't create fonts from internal fonts right now, but it should
* actually be possible because these are in fact alias to non-internal fonts.
* See #9985.
*/
if (! is_internal)
if (!fc_configs_loaded)
{
gchar *expanded_path;
gchar *config;
gchar *sysconfig;
gchar *fonts_renaming_config;
gchar **dirs;
expanded_path = gimp_config_path_expand (collection_id, FALSE, NULL);
if (expanded_path != NULL &&
FcConfigAppFontAddFile (FcConfigGetCurrent (), (const FcChar8 *) expanded_path))
desc = pango_font_description_from_string (name);
FcConfigSetCurrent (FcInitLoadConfig ());
g_free (expanded_path);
config = _gimp_fonts_get_custom_configs (&sysconfig, &fonts_renaming_config, &dirs);
FcConfigParseAndLoad (FcConfigGetCurrent (),
(const guchar *)config ,
FcFalse);
FcConfigParseAndLoad (FcConfigGetCurrent (),
(const guchar *)sysconfig ,
FcFalse);
for (int i = 0; dirs[i] != NULL; ++i)
if (dirs[i])
FcConfigAppFontAddDir (FcConfigGetCurrent (), (const FcChar8 *)dirs[i]);
FcConfigParseAndLoadFromMemory (FcConfigGetCurrent (),
(const FcChar8 *) fonts_renaming_config,
FcTrue);
g_free (fonts_renaming_config);
g_free (sysconfig);
g_free (config);
g_strfreev (dirs);
fc_configs_loaded = TRUE;
}
g_free (name);
g_free (collection_id);
desc = pango_font_description_from_string (_gimp_font_get_lookup_name (font));
return desc;
}

View File

@ -36,6 +36,41 @@
**/
/**
* _gimp_font_get_lookup_name:
* @font: GimpFont object.
*
* Retrieve the font lookup name.
*
* Retrieve the font lookup name.
*
* Returns: (transfer full): font lookup name.
* The returned value must be freed with g_free().
**/
gchar *
_gimp_font_get_lookup_name (GimpFont *font)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gchar *lookup_name = NULL;
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_FONT, font,
G_TYPE_NONE);
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-font-get-lookup-name",
args);
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
lookup_name = GIMP_VALUES_DUP_STRING (return_vals, 1);
gimp_value_array_unref (return_vals);
return lookup_name;
}
/**
* gimp_font_get_by_name:
* @name: The name of the font.

View File

@ -32,9 +32,10 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
GimpFont* gimp_font_get_by_name (const gchar *name);
GimpFont** gimp_fonts_get_by_name (const gchar *name,
gint *num_fonts);
G_GNUC_INTERNAL gchar* _gimp_font_get_lookup_name (GimpFont *font);
GimpFont* gimp_font_get_by_name (const gchar *name);
GimpFont** gimp_fonts_get_by_name (const gchar *name,
gint *num_fonts);
G_END_DECLS

View File

@ -69,6 +69,50 @@ gimp_fonts_refresh (void)
return success;
}
/**
* _gimp_fonts_get_custom_configs:
* @sysconfig: (out) (transfer full): sysconfig path.
* @renaming_config: (out) (transfer full): fonts renaming config.
* @dirs: (out) (array zero-terminated=1) (transfer full): custom fonts directories.
*
* Retrieve custom configs.
*
* This procedure returns custom FontConfig configs along with the
* fonts renaming config.
*
* Returns: (transfer full): config path.
* The returned value must be freed with g_free().
**/
gchar *
_gimp_fonts_get_custom_configs (gchar **sysconfig,
gchar **renaming_config,
gchar ***dirs)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gchar *config = NULL;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_NONE);
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-fonts-get-custom-configs",
args);
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
{
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);
*dirs = GIMP_VALUES_DUP_STRV (return_vals, 4);
}
gimp_value_array_unref (return_vals);
return config;
}
/**
* gimp_fonts_get_list:
* @filter: An optional regular expression used to filter the list.

View File

@ -32,8 +32,11 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gboolean gimp_fonts_refresh (void);
gchar** gimp_fonts_get_list (const gchar *filter);
gboolean gimp_fonts_refresh (void);
G_GNUC_INTERNAL gchar* _gimp_fonts_get_custom_configs (gchar **sysconfig,
gchar **renaming_config,
gchar ***dirs);
gchar** gimp_fonts_get_list (const gchar *filter);
G_END_DECLS

View File

@ -99,10 +99,39 @@ CODE
);
}
sub font_get_lookup_name {
$blurb = 'Retrieve the font lookup name.';
$help = <<'HELP';
Retrieve the font lookup name.
HELP
$lib_private = 1;
@inargs = (
{ name => 'font', type => 'font',
desc => 'GimpFont object' }
);
@outargs = (
{ name => 'lookup_name', type => 'string',
desc => 'font lookup name' }
);
%invoke = (
code => <<'CODE'
{
lookup_name = g_strdup (gimp_font_get_lookup_name (font));
}
CODE
);
}
@headers = qw("core/gimp.h"
"text/gimpfont.h"
"gimppdb-utils.h");
@procs = qw(font_get_by_name fonts_get_by_name);
@procs = qw(font_get_lookup_name font_get_by_name fonts_get_by_name);
%exports = (app => [@procs], lib => [@procs]);

View File

@ -73,13 +73,72 @@ CODE
);
}
sub fonts_get_custom_configs {
$blurb = 'Retrieve custom configs.';
$help = <<'HELP';
This procedure returns custom FontConfig configs along with the fonts renaming config.
HELP
$lib_private = 1;
@inargs = (
);
@outargs = (
{ name => 'config', type => 'string',
desc => 'config path' },
{ name => 'sysconfig', type => 'string',
desc => 'sysconfig path' },
{ name => 'renaming_config', type => 'string',
desc => 'fonts renaming config' },
{ name => 'dirs', type => 'strv',
desc => 'custom fonts directories' }
);
%invoke = (
code => <<'CODE'
{
if (! gimp_data_factory_data_wait (gimp->font_factory))
success = FALSE;
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;
gimp_font_factory_get_custom_config_path (GIMP_FONT_FACTORY (gimp->font_factory),
&config,
&sysconfig);
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);
}
}
CODE
);
}
@headers = qw("core/gimp.h"
"core/gimpcontainer.h"
"core/gimpdatafactory.h");
"core/gimpdatafactory.h"
"text/gimpfontfactory.h");
@procs = qw(fonts_refresh
fonts_get_list);
fonts_get_custom_configs
fonts_get_list
);
%exports = (app => [@procs], lib => [@procs]);