[gimp] Issue #4425: Saving to PDF changes text's font and size.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Issue #4425: Saving to PDF changes text's font and size.
- Date: Wed, 1 Jan 2020 17:09:32 +0000 (UTC)
commit 1b0606716488dfd8839396fecd7e1f5c95cb95b7
Author: Jehan <jehan girinstud io>
Date: Wed Jan 1 17:53:02 2020 +0100
Issue #4425: Saving to PDF changes text's font and size.
Adds a new PDF export option "Convert text layers to image", which
defaults to FALSE (because text staying text is obviously usually
prefered).
Also loop through text layers to detect missing fonts. In case any are
found, add a warning in the export dialog, below the new option,
advising to enable this option if design matters (if fonts are missing,
PangoCairo seems to select any other random font and embed it into the
PDF instead of the expected one).
plug-ins/common/file-pdf-save.c | 137 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 134 insertions(+), 3 deletions(-)
---
diff --git a/plug-ins/common/file-pdf-save.c b/plug-ins/common/file-pdf-save.c
index 276d4dad86..088c4fa81e 100644
--- a/plug-ins/common/file-pdf-save.c
+++ b/plug-ins/common/file-pdf-save.c
@@ -144,7 +144,8 @@ typedef enum
SA_IGNORE_HIDDEN,
SA_APPLY_MASKS,
SA_LAYERS_AS_PAGES,
- SA_REVERSE_ORDER
+ SA_REVERSE_ORDER,
+ SA_CONVERT_TEXT
} SaveArgs;
typedef enum
@@ -165,6 +166,7 @@ typedef struct
gboolean apply_masks;
gboolean layers_as_pages;
gboolean reverse_order;
+ gboolean convert_text;
} PdfOptimize;
typedef struct
@@ -297,7 +299,8 @@ static PdfOptimize optimize =
TRUE, /* ignore_hidden */
TRUE, /* apply_masks */
FALSE, /* layers_as_pages */
- FALSE /* reverse_order */
+ FALSE, /* reverse_order */
+ FALSE /* convert text layers to raster */
};
static GtkTreeModel *model;
@@ -396,6 +399,12 @@ pdf_create_procedure (GimpPlugIn *plug_in,
"Reverse the pages order (top layers first).",
FALSE,
G_PARAM_READWRITE);
+
+ GIMP_PROC_ARG_BOOLEAN (procedure, "convert-text-layers",
+ "Convert text layers to image",
+ "Convert text layers to raster graphics",
+ FALSE,
+ G_PARAM_READWRITE);
}
else if (! strcmp (name, SAVE_MULTI_PROC))
{
@@ -499,6 +508,7 @@ pdf_save (GimpProcedure *procedure,
optimize.ignore_hidden = GIMP_VALUES_GET_BOOLEAN (args, SA_IGNORE_HIDDEN);
optimize.layers_as_pages = GIMP_VALUES_GET_BOOLEAN (args, SA_LAYERS_AS_PAGES);
optimize.reverse_order = GIMP_VALUES_GET_BOOLEAN (args, SA_REVERSE_ORDER);
+ optimize.convert_text = GIMP_VALUES_GET_BOOLEAN (args, SA_CONVERT_TEXT);
}
else
defaults = TRUE;
@@ -631,6 +641,62 @@ write_func (void *fp,
: CAIRO_STATUS_WRITE_ERROR;
}
+static GList *
+get_missing_fonts (GList *layers)
+{
+ GList *missing_fonts = NULL;
+ GList *iter;
+
+ for (iter = layers; iter; iter = iter->next)
+ {
+ GimpLayer *layer = iter->data;
+
+ if (gimp_item_is_group (GIMP_ITEM (layer)))
+ {
+ missing_fonts = g_list_concat (missing_fonts,
+ get_missing_fonts (gimp_item_list_children (GIMP_ITEM (layer))));
+ }
+ else if (gimp_item_is_text_layer (GIMP_ITEM (layer)))
+ {
+ gchar *font_family;
+ PangoFontDescription *font_description;
+ PangoFontDescription *font_description2;
+ PangoFontMap *fontmap;
+ PangoFont *font;
+ PangoContext *context;
+
+ fontmap = pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT);
+ context = pango_font_map_create_context (fontmap);
+
+ font_family = gimp_text_layer_get_font (layer);
+ font_description = pango_font_description_from_string (font_family);
+
+ font = pango_font_map_load_font (fontmap, context, font_description);
+ font_description2 = pango_font_describe (font);
+ if (g_strcmp0 (pango_font_description_get_family (font_description),
+ pango_font_description_get_family (font_description2)) != 0)
+ {
+ const gchar *missing = pango_font_description_get_family (font_description);
+
+ if (g_list_find_custom (missing_fonts, missing, (GCompareFunc) g_strcmp0) == NULL)
+ missing_fonts = g_list_prepend (missing_fonts,
+ g_strdup (missing));
+ }
+
+ g_object_unref (font);
+ pango_font_description_free (font_description);
+ pango_font_description_free (font_description2);
+ g_free (font_family);
+ g_object_unref (context);
+ g_object_unref (fontmap);
+ }
+ }
+
+ g_list_free (layers);
+
+ return missing_fonts;
+}
+
static GimpValueArray *
pdf_save_image (GimpProcedure *procedure,
gboolean single_image,
@@ -864,11 +930,13 @@ gui_single (void)
GtkWidget *vbox;
GtkWidget *vectorize_c;
GtkWidget *ignore_hidden_c;
+ GtkWidget *convert_text_c;
GtkWidget *apply_c;
GtkWidget *layers_as_pages_c;
GtkWidget *reverse_order_c;
GtkWidget *frame;
gchar *text;
+ GList *missing_fonts;
gboolean run;
gint32 n_layers;
@@ -882,6 +950,67 @@ gui_single (void)
gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+ convert_text_c = gtk_check_button_new_with_mnemonic (_("_Convert text layers to image"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (convert_text_c),
+ optimize.convert_text);
+ missing_fonts = get_missing_fonts (gimp_image_list_layers (multi_page.images[0]));
+ if (missing_fonts != NULL)
+ {
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *warn_box;
+ GList *iter;
+ gchar *font_list = NULL;
+
+ frame = gtk_frame_new (NULL);
+ gtk_box_pack_end (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
+
+ /* Checkbox is frame label. */
+ gtk_frame_set_label_widget (GTK_FRAME (frame), convert_text_c);
+
+ /* Show warning inside the frame. */
+ warn_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
+ gtk_container_add (GTK_CONTAINER (frame), warn_box);
+
+ image = gtk_image_new_from_icon_name (GIMP_ICON_WILBER_EEK,
+ GTK_ICON_SIZE_BUTTON);
+ gtk_box_pack_start (GTK_BOX (warn_box), image, FALSE, FALSE, 0);
+ gtk_widget_show (image);
+
+ for (iter = missing_fonts; iter; iter = iter->next)
+ {
+ gchar *fontname = iter->data;
+
+ if (font_list == NULL)
+ {
+ font_list = g_strdup (fontname);
+ }
+ else
+ {
+ gchar *tmp = font_list;
+
+ font_list = g_strjoin (", ", tmp, fontname, NULL);
+ g_free (tmp);
+ }
+ }
+
+ text = g_strdup_printf (_("The following fonts cannot be found: %s.\n"
+ "It is recommended to convert your text layers to image "
+ "or to install the missing fonts before exporting, "
+ "otherwise your design may not look right."),
+ font_list);
+ label = gtk_label_new (text);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ g_free (text);
+ gtk_box_pack_start (GTK_BOX (warn_box), label, TRUE, TRUE, 0);
+
+ g_list_free_full (missing_fonts, g_free);
+ }
+ else
+ {
+ gtk_box_pack_end (GTK_BOX (vbox), convert_text_c, TRUE, TRUE, 0);
+ }
+
ignore_hidden_c = gtk_check_button_new_with_mnemonic (_("_Omit hidden layers and layers with zero
opacity"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ignore_hidden_c),
optimize.ignore_hidden);
@@ -935,6 +1064,8 @@ gui_single (void)
run = gtk_dialog_run (GTK_DIALOG (window)) == GTK_RESPONSE_OK;
+ optimize.convert_text =
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (convert_text_c));
optimize.ignore_hidden =
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ignore_hidden_c));
optimize.vectorize =
@@ -1802,7 +1933,7 @@ draw_layer (GimpLayer **layers,
gimp_drawable_offsets (GIMP_DRAWABLE (layer), &x, &y);
- if (! gimp_item_is_text_layer (GIMP_ITEM (layer)))
+ if (! gimp_item_is_text_layer (GIMP_ITEM (layer)) || optimize.convert_text)
{
/* For raster layers */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]