From 7a6a908ad25414cbd55e41267bd06687bb28f918 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Tue, 24 Jun 2003 19:45:55 +0000 Subject: [PATCH] added new function gimp_config_serialize_to_fd() for the sake of 2003-06-24 Sven Neumann * app/config/gimpconfig.[ch]: added new function gimp_config_serialize_to_fd() for the sake of completeness and since it's a nice way to generate debugging output. * app/text/Makefile.am * app/text/gimptext-xlfd.[ch]: new files with routines to handle X Logical Font Descriptions in an attempt to improve backwards compatibility. * app/text/gimptext-parasite.[ch] * app/xcf/xcf-load.c: promote layers with GDynText parasite to GimpTextLayer. Work in progress, we need to improve font matching. --- ChangeLog | 15 +++ app/config/gimpconfig.c | 23 +++++ app/config/gimpconfig.h | 3 + app/text/Makefile.am | 2 + app/text/gimptext-parasite.c | 124 +++++++++++++++++++++- app/text/gimptext-parasite.h | 8 +- app/text/gimptext-xlfd.c | 171 +++++++++++++++++++++++++++++++ app/text/gimptext-xlfd.h | 35 +++++++ app/xcf/xcf-load.c | 22 ++++ libgimpconfig/gimpconfig-iface.c | 23 +++++ libgimpconfig/gimpconfig-iface.h | 3 + 11 files changed, 424 insertions(+), 5 deletions(-) create mode 100644 app/text/gimptext-xlfd.c create mode 100644 app/text/gimptext-xlfd.h diff --git a/ChangeLog b/ChangeLog index dc329d5770..1a415c51fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2003-06-24 Sven Neumann + + * app/config/gimpconfig.[ch]: added new function + gimp_config_serialize_to_fd() for the sake of completeness and + since it's a nice way to generate debugging output. + + * app/text/Makefile.am + * app/text/gimptext-xlfd.[ch]: new files with routines to handle X + Logical Font Descriptions in an attempt to improve backwards + compatibility. + + * app/text/gimptext-parasite.[ch] + * app/xcf/xcf-load.c: promote layers with GDynText parasite to + GimpTextLayer. Work in progress, we need to improve font matching. + 2003-06-24 Michael Natterer * app/widgets/gimpcontainertreeview.c diff --git a/app/config/gimpconfig.c b/app/config/gimpconfig.c index ced32b0b61..ea76c1fae9 100644 --- a/app/config/gimpconfig.c +++ b/app/config/gimpconfig.c @@ -213,6 +213,29 @@ gimp_config_serialize_to_file (GObject *object, return gimp_config_writer_finish (writer, footer, error); } +gboolean +gimp_config_serialize_to_fd (GObject *object, + gint fd, + gpointer data) +{ + GimpConfigInterface *gimp_config_iface; + GimpConfigWriter *writer; + + g_return_val_if_fail (G_IS_OBJECT (object), FALSE); + g_return_val_if_fail (fd > 0, FALSE); + + gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); + g_return_val_if_fail (gimp_config_iface != NULL, FALSE); + + writer = gimp_config_writer_new_fd (fd); + if (!writer) + return FALSE; + + gimp_config_iface->serialize (object, writer, data); + + return gimp_config_writer_finish (writer, NULL, NULL); +} + /** * gimp_config_serialize_to_string: * @object: a #GObject that implements the #GimpConfigInterface. diff --git a/app/config/gimpconfig.h b/app/config/gimpconfig.h index cc14848adb..b6538fff1b 100644 --- a/app/config/gimpconfig.h +++ b/app/config/gimpconfig.h @@ -77,6 +77,9 @@ gboolean gimp_config_serialize_to_file (GObject *object, const gchar *footer, gpointer data, GError **error); +gboolean gimp_config_serialize_to_fd (GObject *object, + gint fd, + gpointer data); gchar * gimp_config_serialize_to_string (GObject *object, gpointer data); gboolean gimp_config_deserialize_file (GObject *object, diff --git a/app/text/Makefile.am b/app/text/Makefile.am index b74aff9a47..72171c3d40 100644 --- a/app/text/Makefile.am +++ b/app/text/Makefile.am @@ -27,6 +27,8 @@ libapptext_a_sources = \ gimptext-compat.h \ gimptext-parasite.c \ gimptext-parasite.h \ + gimptext-xlfd.c \ + gimptext-xlfd.h \ gimptextlayer.c \ gimptextlayer.h \ gimptextlayout.c \ diff --git a/app/text/gimptext-parasite.c b/app/text/gimptext-parasite.c index 7d042b7a0b..afc96d92d1 100644 --- a/app/text/gimptext-parasite.c +++ b/app/text/gimptext-parasite.c @@ -22,10 +22,12 @@ #include "config.h" #include +#include #include #include "libgimpbase/gimpbase.h" +#include "libgimpcolor/gimpcolor.h" #include "text/text-types.h" @@ -33,7 +35,20 @@ #include "gimptext.h" #include "gimptext-parasite.h" +#include "gimptext-xlfd.h" +#include "gimp-intl.h" + + +/****************************************/ +/* The native GimpTextLayer parasite. */ +/****************************************/ + +const gchar * +gimp_text_parasite_name (void) +{ + return "gimp-text-layer"; +} GimpParasite * gimp_text_to_parasite (const GimpText *text) @@ -83,8 +98,113 @@ gimp_text_from_parasite (const GimpParasite *parasite) return text; } + +/****************************************************************/ +/* Compatibility to plug-in GDynText 1.4.4 and later versions */ +/* GDynText was written by Marco Lamberto */ +/****************************************************************/ + const gchar * -gimp_text_parasite_name (void) +gimp_text_gdyntext_parasite_name (void) { - return "gimp-text-layer"; + return "plug_in_gdyntext/data"; +} + +enum +{ + TEXT = 0, + ANTIALIAS = 1, + ALIGNMENT = 2, + ROTATION = 3, + LINE_SPACING = 4, + COLOR = 5, + LAYER_ALIGNMENT = 6, + XLFD = 7, + NUM_PARAMS +}; + +GimpText * +gimp_text_from_gdyntext_parasite (const GimpParasite *parasite) +{ + GimpText *retval = NULL; + GimpTextJustification justify; + const gchar *str; + gchar *text = NULL; + gchar *font = NULL; + gchar **params; + gboolean antialias; + gdouble spacing; + gdouble size; + GimpUnit unit; + GimpRGB rgb; + glong color; + gint i; + + g_return_val_if_fail (parasite != NULL, NULL); + g_return_val_if_fail (strcmp (gimp_parasite_name (parasite), + gimp_text_gdyntext_parasite_name ()) == 0, + NULL); + + str = gimp_parasite_data (parasite); + g_return_val_if_fail (str != NULL, NULL); + + if (strncmp (str, "GDT10{", 6) != 0) /* magic value */ + return NULL; + + params = g_strsplit (str + 6, "}{", -1); + + /* first check that we have the required number of parameters */ + for (i = 0; i < NUM_PARAMS; i++) + if (!params[i]) + goto cleanup; + + text = g_strcompress (params[TEXT]); + + if (! g_utf8_validate (text, -1, NULL)) + { + g_message (_("Can not convert GDynText layer because it " + "contains text that is not UTF-8 encoded.")); + goto cleanup; + } + + antialias = atoi (params[ANTIALIAS]) ? TRUE : FALSE; + + switch (atoi (params[ALIGNMENT])) + { + default: + case 0: justify = GIMP_TEXT_JUSTIFY_LEFT; break; + case 1: justify = GIMP_TEXT_JUSTIFY_CENTER; break; + case 2: justify = GIMP_TEXT_JUSTIFY_RIGHT; break; + } + + spacing = atof (params[LINE_SPACING]); + + color = strtol (params[COLOR], NULL, 16); + gimp_rgba_set_uchar (&rgb, color >> 16, color >> 8, color, 255); + + font = gimp_text_font_name_from_xlfd (params[XLFD]); + + retval = g_object_new (GIMP_TYPE_TEXT, + "text", text, + "antialias", antialias, + "justify", justify, + "line-spacing", spacing, + "color", &rgb, + "font", font, + NULL); + + if (gimp_text_font_size_from_xlfd (params[XLFD], &size, &unit)) + { + g_object_set (retval, + "font-size", size, + "font-size-unit", unit, + NULL); + } + + cleanup: + g_free (font); + g_free (text); + g_strfreev (params); + + return retval; } diff --git a/app/text/gimptext-parasite.h b/app/text/gimptext-parasite.h index 037f610413..bcfcf01a91 100644 --- a/app/text/gimptext-parasite.h +++ b/app/text/gimptext-parasite.h @@ -23,10 +23,12 @@ #define __GIMP_TEXT_PARASITE_H__ -GimpParasite * gimp_text_to_parasite (const GimpText *text); -GimpText * gimp_text_from_parasite (const GimpParasite *parasite); +const gchar * gimp_text_parasite_name (void) G_GNUC_CONST; +GimpParasite * gimp_text_to_parasite (const GimpText *text); +GimpText * gimp_text_from_parasite (const GimpParasite *parasite); -const gchar * gimp_text_parasite_name (void) G_GNUC_CONST; +const gchar * gimp_text_gdyntext_parasite_name (void) G_GNUC_CONST; +GimpText * gimp_text_from_gdyntext_parasite (const GimpParasite *parasite); #endif /* __GIMP_TEXT_PARASITE_H__ */ diff --git a/app/text/gimptext-xlfd.c b/app/text/gimptext-xlfd.c new file mode 100644 index 0000000000..494e548ae6 --- /dev/null +++ b/app/text/gimptext-xlfd.c @@ -0,0 +1,171 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpText + * Copyright (C) 2002-2003 Sven Neumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "libgimpbase/gimpbase.h" + +#include "gimptext-xlfd.h" + + +/* Most of this code was copied from pangox-fontmap.c */ + + +#define XLFD_MAX_FIELD_LEN 64 + +/* These are the field numbers in the X Logical Font Description fontnames, + e.g. -adobe-courier-bold-o-normal--25-180-100-100-m-150-iso8859-1 */ +enum +{ + XLFD_FOUNDRY = 0, + XLFD_FAMILY = 1, + XLFD_WEIGHT = 2, + XLFD_SLANT = 3, + XLFD_SET_WIDTH = 4, + XLFD_ADD_STYLE = 5, + XLFD_PIXELS = 6, + XLFD_POINTS = 7, + XLFD_RESOLUTION_X = 8, + XLFD_RESOLUTION_Y = 9, + XLFD_SPACING = 10, + XLFD_AVERAGE_WIDTH = 11, + XLFD_CHARSET = 12, + XLFD_NUM_FIELDS +}; + + +/** gimp_text_get_xlfd_field() + * @fontname: an XLFD fontname + * @field_num: field index + * @buffer: buffer of at least XLFD_MAX_FIELD_LEN chars + * + * Fills the buffer with the specified field from the X Logical Font + * Description name, and returns it. Note: For the charset field, we + * also return the encoding, e.g. 'iso8859-1'. + * + * This function is basically copied from pangox-fontmap.c. + * + * Returns: a pointer to the filled buffer or %NULL if fontname is + * %NULL or the field is longer than XFLD_MAX_FIELD_LEN. + **/ +static gchar * +gimp_text_get_xlfd_field (const gchar *fontname, + gint field_num, + gchar *buffer) +{ + const gchar *t1, *t2; + gchar *p; + gint countdown, len, num_dashes; + + if (!fontname) + return NULL; + + /* we assume this is a valid fontname...that is, it has 14 fields */ + + countdown = field_num; + t1 = fontname; + while (*t1 && (countdown >= 0)) + if (*t1++ == '-') + countdown--; + + num_dashes = (field_num == XLFD_CHARSET) ? 2 : 1; + for (t2 = t1; *t2; t2++) + { + if (*t2 == '-' && --num_dashes == 0) + break; + } + + if (t1 != t2) + { + /* Check we don't overflow the buffer */ + len = (long) t2 - (long) t1; + if (len > XLFD_MAX_FIELD_LEN - 1) + return NULL; + strncpy (buffer, t1, len); + buffer[len] = 0; + /* Convert to lower case. */ + for (p = buffer; *p; p++) + *p = g_ascii_tolower (*p); + } + else + strcpy(buffer, "(nil)"); + + return buffer; +} + +gchar * +gimp_text_font_name_from_xlfd (const gchar *xlfd) +{ + gchar *fields[4]; + gchar buffers[4][XLFD_MAX_FIELD_LEN]; + gint i, j; + + for (i = 0, j = 0; i < 4; i++) + { + fields[j] = gimp_text_get_xlfd_field (xlfd, XLFD_FAMILY + i, buffers[i]); + + if (fields[j] && *fields[j] == '*') + fields[j] = NULL; + + if (fields[j]) + j++; + } + + return g_strconcat (fields[0], " ", + fields[1], " ", + fields[2], " ", + fields[3], NULL); +} + +gboolean +gimp_text_font_size_from_xlfd (const gchar *xlfd, + gdouble *size, + GimpUnit *size_unit) +{ + gchar buffer[XLFD_MAX_FIELD_LEN]; + gchar *field; + + if (!xlfd) + return FALSE; + + field = gimp_text_get_xlfd_field (xlfd, XLFD_PIXELS, buffer); + if (field && *field != '*') + { + *size = atoi (field); + *size_unit = GIMP_UNIT_PIXEL; + return TRUE; + } + + field = gimp_text_get_xlfd_field (xlfd, XLFD_POINTS, buffer); + if (field && *field != '*') + { + *size = atoi (field); + *size_unit = GIMP_UNIT_POINT; + return TRUE; + } + + return FALSE; +} diff --git a/app/text/gimptext-xlfd.h b/app/text/gimptext-xlfd.h new file mode 100644 index 0000000000..c4e10487d6 --- /dev/null +++ b/app/text/gimptext-xlfd.h @@ -0,0 +1,35 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpText + * Copyright (C) 2002-2003 Sven Neumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_TEXT_XLFD_H__ +#define __GIMP_TEXT_XLFD_H__ + + +/* handle X Logical Font Descriptions for compat */ + +gchar * gimp_text_font_name_from_xlfd (const gchar *xlfd); +gboolean gimp_text_font_size_from_xlfd (const gchar *xlfd, + gdouble *size, + GimpUnit *size_unit); + + + +#endif /* __GIMP_TEXT_COMPAT_H__ */ diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index ed7b5c25bf..73f22527e8 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -786,6 +786,28 @@ xcf_load_layer (XcfInfo *info, info->active_layer = layer; } } + else + { + /* check for a GDynText parasite */ + parasite = gimp_item_parasite_find (GIMP_ITEM (layer), + gimp_text_gdyntext_parasite_name ()); + + if (parasite) + { + GimpText *text = gimp_text_from_gdyntext_parasite (parasite); + + if (text) + { + gboolean active = (info->active_layer == layer); + + /* convert the layer to a text layer */ + layer = gimp_text_layer_from_layer (layer, text); + + if (active) + info->active_layer = layer; + } + } + } /* read the hierarchy and layer mask offsets */ info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1); diff --git a/libgimpconfig/gimpconfig-iface.c b/libgimpconfig/gimpconfig-iface.c index ced32b0b61..ea76c1fae9 100644 --- a/libgimpconfig/gimpconfig-iface.c +++ b/libgimpconfig/gimpconfig-iface.c @@ -213,6 +213,29 @@ gimp_config_serialize_to_file (GObject *object, return gimp_config_writer_finish (writer, footer, error); } +gboolean +gimp_config_serialize_to_fd (GObject *object, + gint fd, + gpointer data) +{ + GimpConfigInterface *gimp_config_iface; + GimpConfigWriter *writer; + + g_return_val_if_fail (G_IS_OBJECT (object), FALSE); + g_return_val_if_fail (fd > 0, FALSE); + + gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (object); + g_return_val_if_fail (gimp_config_iface != NULL, FALSE); + + writer = gimp_config_writer_new_fd (fd); + if (!writer) + return FALSE; + + gimp_config_iface->serialize (object, writer, data); + + return gimp_config_writer_finish (writer, NULL, NULL); +} + /** * gimp_config_serialize_to_string: * @object: a #GObject that implements the #GimpConfigInterface. diff --git a/libgimpconfig/gimpconfig-iface.h b/libgimpconfig/gimpconfig-iface.h index cc14848adb..b6538fff1b 100644 --- a/libgimpconfig/gimpconfig-iface.h +++ b/libgimpconfig/gimpconfig-iface.h @@ -77,6 +77,9 @@ gboolean gimp_config_serialize_to_file (GObject *object, const gchar *footer, gpointer data, GError **error); +gboolean gimp_config_serialize_to_fd (GObject *object, + gint fd, + gpointer data); gchar * gimp_config_serialize_to_string (GObject *object, gpointer data); gboolean gimp_config_deserialize_file (GObject *object,