Added persistent storage of text layers in XCF files. We use a parasite in

2003-06-24  Sven Neumann  <sven@gimp.org>

        Added persistent storage of text layers in XCF files. We use a
	parasite in order to keep the file format backwards compatible.
	Fixes bug #111781.

	* app/text/Makefile.am
	* app/text/gimptext-parasite.[ch]: new files that hold functions
	to convert a GimpText object to a GimpParasite and back.

	* app/text/gimptextlayer.[ch]: added an ugly hack that allows to
	convert a normal layer to a text layer.

	* app/xcf/xcf-save.c: when saving a text layer, store an extra
	parasite that holds all information about the text.

	* app/xcf/xcf-load.c: if a "gimp-text-layer" parasite is found and
	it can be successfully deserialized to a GimpText object, convert
	the layer to a text layer and remove the parasite.

	* app/Makefile.am: had to change linkage order.

	* devel-docs/parasites.txt: documented the new "gimp-text-layer"
	parasite.

	* app/text/gimptext-parasite.[ch]
	* app/gui/session.c (session_save): plugged minor memory leaks.
This commit is contained in:
Sven Neumann 2003-06-24 13:58:34 +00:00 committed by Sven Neumann
parent 82bb65c3cb
commit 6b5e42def3
8 changed files with 244 additions and 9 deletions

View File

@ -1,3 +1,31 @@
2003-06-24 Sven Neumann <sven@gimp.org>
Added persistent storage of text layers in XCF files. We use a
parasite in order to keep the file format backwards compatible.
Fixes bug #111781.
* app/text/Makefile.am
* app/text/gimptext-parasite.[ch]: new files that hold functions
to convert a GimpText object to a GimpParasite and back.
* app/text/gimptextlayer.[ch]: added an ugly hack that allows to
convert a normal layer to a text layer.
* app/xcf/xcf-save.c: when saving a text layer, store an extra
parasite that holds all information about the text.
* app/xcf/xcf-load.c: if a "gimp-text-layer" parasite is found and
it can be successfully deserialized to a GimpText object, convert
the layer to a text layer and remove the parasite.
* app/Makefile.am: had to change linkage order.
* devel-docs/parasites.txt: documented the new "gimp-text-layer"
parasite.
* app/text/gimptext-parasite.[ch]
* app/gui/session.c (session_save): plugged minor memory leaks.
2003-06-24 Sven Neumann <sven@gimp.org> 2003-06-24 Sven Neumann <sven@gimp.org>
* app/config/gimpscanner.c: store file descriptor and filename in * app/config/gimpscanner.c: store file descriptor and filename in

View File

@ -73,8 +73,8 @@ gimp_1_3_LDADD = \
core/libappcore.a \ core/libappcore.a \
pdb/libapppdb.a \ pdb/libapppdb.a \
paint/libapppaint.a \ paint/libapppaint.a \
text/libapptext.a \
xcf/libappxcf.a \ xcf/libappxcf.a \
text/libapptext.a \
vectors/libappvectors.a \ vectors/libappvectors.a \
file/libappfile.a \ file/libappfile.a \
plug-in/libappplug-in.a \ plug-in/libappplug-in.a \

View File

@ -218,6 +218,7 @@ session_save (Gimp *gimp)
"every time you quit the gimp. If this " "every time you quit the gimp. If this "
"file isn't found, defaults are used.", "file isn't found, defaults are used.",
NULL); NULL);
g_free (filename);
if (!writer) if (!writer)
return; return;

View File

@ -25,6 +25,8 @@ libapptext_a_sources = \
gimptext.h \ gimptext.h \
gimptext-compat.c \ gimptext-compat.c \
gimptext-compat.h \ gimptext-compat.h \
gimptext-parasite.c \
gimptext-parasite.h \
gimptextlayer.c \ gimptextlayer.c \
gimptextlayer.h \ gimptextlayer.h \
gimptextlayout.c \ gimptextlayout.c \

View File

@ -0,0 +1,90 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpText
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
*
* 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 <string.h>
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "text/text-types.h"
#include "config/gimpconfig.h"
#include "gimptext.h"
#include "gimptext-parasite.h"
GimpParasite *
gimp_text_to_parasite (const GimpText *text)
{
GimpParasite *parasite;
gchar *str;
g_return_val_if_fail (GIMP_IS_TEXT (text), NULL);
str = gimp_config_serialize_to_string (G_OBJECT (text), NULL);
g_return_val_if_fail (str != NULL, NULL);
parasite = gimp_parasite_new (gimp_text_parasite_name (),
GIMP_PARASITE_PERSISTENT,
strlen (str) + 1, str);
g_free (str);
return parasite;
}
GimpText *
gimp_text_from_parasite (const GimpParasite *parasite)
{
GimpText *text;
const gchar *str;
GError *error = NULL;
g_return_val_if_fail (parasite != NULL, NULL);
g_return_val_if_fail (strcmp (gimp_parasite_name (parasite),
gimp_text_parasite_name ()) == 0, NULL);
str = gimp_parasite_data (parasite);
g_return_val_if_fail (str != NULL, NULL);
text = g_object_new (GIMP_TYPE_TEXT, NULL);
if (! gimp_config_deserialize_string (G_OBJECT (text),
str,
gimp_parasite_data_size (parasite),
NULL,
&error))
{
g_warning ("Failed to deserialize text parasite: %s", error->message);
g_error_free (error);
}
return text;
}
const gchar *
gimp_text_parasite_name (void)
{
return "gimp-text-layer";
}

View File

@ -0,0 +1,32 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpText
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
*
* 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_PARASITE_H__
#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;
#endif /* __GIMP_TEXT_PARASITE_H__ */

View File

@ -57,7 +57,8 @@ static GimpItem * gimp_text_layer_duplicate (GimpItem *item,
static void gimp_text_layer_rename (GimpItem *item, static void gimp_text_layer_rename (GimpItem *item,
const gchar *new_name, const gchar *new_name,
const gchar *undo_desc); const gchar *undo_desc);
static void gimp_text_layer_set_text (GimpTextLayer *layer,
GimpText *text);
static void gimp_text_layer_notify_text (GimpTextLayer *layer); static void gimp_text_layer_notify_text (GimpTextLayer *layer);
static gboolean gimp_text_layer_idle_render (GimpTextLayer *layer); static gboolean gimp_text_layer_idle_render (GimpTextLayer *layer);
static gboolean gimp_text_layer_render (GimpTextLayer *layer); static gboolean gimp_text_layer_render (GimpTextLayer *layer);
@ -224,7 +225,7 @@ GimpLayer *
gimp_text_layer_new (GimpImage *image, gimp_text_layer_new (GimpImage *image,
GimpText *text) GimpText *text)
{ {
GimpTextLayer *layer; GimpTextLayer *layer;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_TEXT (text), NULL); g_return_val_if_fail (GIMP_IS_TEXT (text), NULL);
@ -240,7 +241,7 @@ gimp_text_layer_new (GimpImage *image,
gimp_image_base_type_with_alpha (image), gimp_image_base_type_with_alpha (image),
NULL); NULL);
layer->text = g_object_ref (text); gimp_text_layer_set_text (layer, text);
if (! gimp_text_layer_render (layer)) if (! gimp_text_layer_render (layer))
{ {
@ -248,11 +249,90 @@ gimp_text_layer_new (GimpImage *image,
return NULL; return NULL;
} }
return GIMP_LAYER (layer);
}
/**
* gimp_text_layer_from_layer:
* @layer: a #GimpLayer object
* @text: a #GimpText object
*
* Converts a standard #GimpLayer and a #GimpText object into a
* #GimpTextLayer. The new text layer takes ownership of the @text and
* @layer objects. The @layer object is rendered unusable by this
* function. Don't even try to use if afterwards!
*
* This is a gross hack that is needed in order to load text layers
* from XCF files in a backwards-compatible way. Please don't use it
* for anything else!
*
* Return value: a newly allocated #GimpTextLayer object
**/
GimpLayer *
gimp_text_layer_from_layer (GimpLayer *layer,
GimpText *text)
{
GimpTextLayer *text_layer;
GimpItem *item;
GimpDrawable *drawable;
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
g_return_val_if_fail (GIMP_IS_TEXT (text), NULL);
text_layer = g_object_new (GIMP_TYPE_TEXT_LAYER, NULL);
item = GIMP_ITEM (text_layer);
drawable = GIMP_DRAWABLE (text_layer);
gimp_object_set_name (GIMP_OBJECT (text_layer),
gimp_object_get_name (GIMP_OBJECT (layer)));
item->ID = gimp_item_get_ID (GIMP_ITEM (layer));
item->tattoo = gimp_item_get_tattoo (GIMP_ITEM (layer));
item->gimage = gimp_item_get_image (GIMP_ITEM (layer));
item->parasites = GIMP_ITEM (layer)->parasites;
GIMP_ITEM (layer)->parasites = NULL;
item->width = gimp_item_width (GIMP_ITEM (layer));
item->height = gimp_item_height (GIMP_ITEM (layer));
gimp_item_offsets (GIMP_ITEM (layer), &item->offset_x, &item->offset_y);
item->linked = gimp_item_get_linked (GIMP_ITEM (layer));
drawable->tiles = GIMP_DRAWABLE (layer)->tiles;
GIMP_DRAWABLE (layer)->tiles = NULL;
drawable->visible = gimp_drawable_get_visible (GIMP_DRAWABLE (layer));
drawable->bytes = gimp_drawable_bytes (GIMP_DRAWABLE (layer));
drawable->type = gimp_drawable_type (GIMP_DRAWABLE (layer));
drawable->has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
GIMP_LAYER (text_layer)->opacity = gimp_layer_get_opacity (layer);
GIMP_LAYER (text_layer)->mode = gimp_layer_get_mode (layer);
GIMP_LAYER (text_layer)->preserve_trans = gimp_layer_get_preserve_trans (layer);
gimp_text_layer_set_text (text_layer, text);
g_object_unref (layer);
g_object_unref (text);
return GIMP_LAYER (text_layer);
}
static void
gimp_text_layer_set_text (GimpTextLayer *layer,
GimpText *text)
{
g_return_if_fail (GIMP_IS_TEXT_LAYER (layer));
g_return_if_fail (GIMP_IS_TEXT (text));
g_return_if_fail (layer->text == NULL);
layer->text = g_object_ref (text);
g_signal_connect_object (text, "notify", g_signal_connect_object (text, "notify",
G_CALLBACK (gimp_text_layer_notify_text), G_CALLBACK (gimp_text_layer_notify_text),
layer, G_CONNECT_SWAPPED); layer, G_CONNECT_SWAPPED);
return GIMP_LAYER (layer);
} }
GimpText * GimpText *

View File

@ -55,9 +55,11 @@ struct _GimpTextLayerClass
GType gimp_text_layer_get_type (void) G_GNUC_CONST; GType gimp_text_layer_get_type (void) G_GNUC_CONST;
GimpLayer * gimp_text_layer_new (GimpImage *image, GimpLayer * gimp_text_layer_new (GimpImage *image,
GimpText *text); GimpText *text);
GimpText * gimp_text_layer_get_text (GimpTextLayer *layer); GimpLayer * gimp_text_layer_from_layer (GimpLayer *layer,
GimpText *text);
GimpText * gimp_text_layer_get_text (GimpTextLayer *layer);
#endif /* __GIMP_TEXT_LAYER_H__ */ #endif /* __GIMP_TEXT_LAYER_H__ */