avoid to set the unit property with every size change; only set it if it

2004-03-20  Sven Neumann  <sven@gimp.org>

	* app/widgets/gimppropwidgets.c (gimp_prop_size_entry_callback):
	avoid to set the unit property with every size change; only set it
	if it actually changed.

	* app/core/gimpimage-undo-push.c (gimp_image_undo_push_text_layer):
	allow to pass a GParamSpec that identifies a single text property
	to be changed. In this case, don't store a GimpText object on the
	undo stack but only the changed value.

	* app/tools/gimptexttool.c: use the new undo feature to reduce the
	memory footprint of text undo for the common case.

	* app/text/gimptextlayer.c: changed accordingly.
This commit is contained in:
Sven Neumann 2004-03-20 17:21:48 +00:00 committed by Sven Neumann
parent 9d616282c3
commit 20d03407fe
7 changed files with 151 additions and 36 deletions

View file

@ -1,3 +1,19 @@
2004-03-20 Sven Neumann <sven@gimp.org>
* app/widgets/gimppropwidgets.c (gimp_prop_size_entry_callback):
avoid to set the unit property with every size change; only set it
if it actually changed.
* app/core/gimpimage-undo-push.c (gimp_image_undo_push_text_layer):
allow to pass a GParamSpec that identifies a single text property
to be changed. In this case, don't store a GimpText object on the
undo stack but only the changed value.
* app/tools/gimptexttool.c: use the new undo feature to reduce the
memory footprint of text undo for the common case.
* app/text/gimptextlayer.c: changed accordingly.
2004-03-20 Simon Budig <simon@gimp.org> 2004-03-20 Simon Budig <simon@gimp.org>
* app/core/gimpimage-qmask.c: Applied slightly modified patch * app/core/gimpimage-qmask.c: Applied slightly modified patch

View file

@ -49,6 +49,7 @@
#include "gimplist.h" #include "gimplist.h"
#include "gimpparasitelist.h" #include "gimpparasitelist.h"
#include "text/gimptext.h"
#include "text/gimptextlayer.h" #include "text/gimptextlayer.h"
#include "vectors/gimpvectors.h" #include "vectors/gimpvectors.h"
@ -1740,7 +1741,9 @@ typedef struct _TextUndo TextUndo;
struct _TextUndo struct _TextUndo
{ {
GimpText *text; GimpText *text;
const GParamSpec *pspec;
GValue *value;
}; };
static gboolean undo_pop_text_layer (GimpUndo *undo, static gboolean undo_pop_text_layer (GimpUndo *undo,
@ -1751,20 +1754,34 @@ static void undo_free_text_layer (GimpUndo *undo,
gboolean gboolean
gimp_image_undo_push_text_layer (GimpImage *gimage, gimp_image_undo_push_text_layer (GimpImage *gimage,
const gchar *undo_desc, const gchar *undo_desc,
GimpTextLayer *layer) GimpTextLayer *layer,
const GParamSpec *pspec)
{ {
GimpUndo *undo; GimpUndo *undo;
gssize size; gssize size;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), FALSE); g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), FALSE);
g_return_val_if_fail (pspec == NULL || pspec->owner_type == GIMP_TYPE_TEXT,
FALSE);
g_return_val_if_fail (pspec == NULL || layer->text != NULL, FALSE);
size = sizeof (TextUndo); size = sizeof (TextUndo);
if (layer->text) g_printerr ("gimp_image_undo_push_text_layer (%s)\n",
size += gimp_object_get_memsize (GIMP_OBJECT (layer->text), NULL); pspec ? pspec->name : NULL);
if (pspec)
{
/* this is incorrect, but how can it be done better? */
size += sizeof (GValue);
}
else if (layer->text)
{
size += gimp_object_get_memsize (GIMP_OBJECT (layer->text), NULL);
}
undo = gimp_image_undo_push_item (gimage, GIMP_ITEM (layer), undo = gimp_image_undo_push_item (gimage, GIMP_ITEM (layer),
size, sizeof (TextUndo), size, sizeof (TextUndo),
@ -1777,8 +1794,19 @@ gimp_image_undo_push_text_layer (GimpImage *gimage,
{ {
TextUndo *tu = undo->data; TextUndo *tu = undo->data;
tu->text = (layer->text ? if (pspec)
gimp_config_duplicate (GIMP_CONFIG (layer->text)) : NULL); {
tu->pspec = pspec;
tu->value = g_new0 (GValue, 1);
g_value_init (tu->value, pspec->value_type);
g_object_get_property (G_OBJECT (layer->text),
pspec->name, tu->value);
}
else if (layer->text)
{
tu->text = gimp_config_duplicate (GIMP_CONFIG (layer->text));
}
return TRUE; return TRUE;
} }
@ -1793,26 +1821,51 @@ undo_pop_text_layer (GimpUndo *undo,
{ {
TextUndo *tu = undo->data; TextUndo *tu = undo->data;
GimpTextLayer *layer = GIMP_TEXT_LAYER (GIMP_ITEM_UNDO (undo)->item); GimpTextLayer *layer = GIMP_TEXT_LAYER (GIMP_ITEM_UNDO (undo)->item);
GimpText *text;
if (tu->text) if (tu->pspec)
undo->size -= gimp_object_get_memsize (GIMP_OBJECT (tu->text), NULL); {
GValue *value;
text = (layer->text ? g_return_val_if_fail (layer->text != NULL, FALSE);
gimp_config_duplicate (GIMP_CONFIG (layer->text)) : NULL);
if (layer->text && tu->text) value = g_new0 (GValue, 1);
gimp_config_sync (GIMP_CONFIG (tu->text), GIMP_CONFIG (layer->text), 0); g_value_init (value, tu->pspec->value_type);
g_object_get_property (G_OBJECT (layer->text),
tu->pspec->name, value);
g_object_set_property (G_OBJECT (layer->text),
tu->pspec->name, tu->value);
g_value_unset (tu->value);
g_free (tu->value);
tu->value = value;
}
else else
gimp_text_layer_set_text (layer, tu->text); {
GimpText *text;
if (tu->text) if (tu->text)
g_object_unref (tu->text); undo->size -= gimp_object_get_memsize (GIMP_OBJECT (tu->text), NULL);
tu->text = text; text = (layer->text ?
gimp_config_duplicate (GIMP_CONFIG (layer->text)) : NULL);
if (tu->text) if (layer->text && tu->text)
undo->size += gimp_object_get_memsize (GIMP_OBJECT (tu->text), NULL); gimp_config_sync (GIMP_CONFIG (tu->text),
GIMP_CONFIG (layer->text), 0);
else
gimp_text_layer_set_text (layer, tu->text);
if (tu->text)
g_object_unref (tu->text);
tu->text = text;
if (tu->text)
undo->size += gimp_object_get_memsize (GIMP_OBJECT (tu->text), NULL);
}
return TRUE; return TRUE;
} }
@ -1826,6 +1879,12 @@ undo_free_text_layer (GimpUndo *undo,
if (tu->text) if (tu->text)
g_object_unref (tu->text); g_object_unref (tu->text);
if (tu->pspec)
{
g_value_unset (tu->value);
g_free (tu->value);
}
g_free (tu); g_free (tu);
} }

View file

@ -111,9 +111,10 @@ gboolean gimp_image_undo_push_layer_preserve_trans (GimpImage *gimage,
GimpLayer *layer); GimpLayer *layer);
/* text layer undo */ /* text layer undo */
gboolean gimp_image_undo_push_text_layer (GimpImage *gimage, gboolean gimp_image_undo_push_text_layer (GimpImage *gimage,
const gchar *undo_desc, const gchar *undo_desc,
GimpTextLayer *layer); GimpTextLayer *layer,
const GParamSpec *pspec);
/* channel undos */ /* channel undos */

View file

@ -500,7 +500,7 @@ gimp_text_layer_set (GimpTextLayer *layer,
if (undo_group) if (undo_group)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, undo_desc); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, undo_desc);
gimp_image_undo_push_text_layer (image, undo_desc, layer); gimp_image_undo_push_text_layer (image, undo_desc, layer, NULL);
va_start (var_args, first_property_name); va_start (var_args, first_property_name);
@ -529,7 +529,7 @@ gimp_text_layer_discard (GimpTextLayer *layer)
gimp_image_undo_push_text_layer (gimp_item_get_image (GIMP_ITEM (layer)), gimp_image_undo_push_text_layer (gimp_item_get_image (GIMP_ITEM (layer)),
_("Discard Text Information"), _("Discard Text Information"),
layer); layer, NULL);
gimp_text_layer_set_text (layer, NULL); gimp_text_layer_set_text (layer, NULL);
} }

View file

@ -479,12 +479,13 @@ gimp_text_tool_idle_apply (GimpTextTool *text_tool)
static void static void
gimp_text_tool_apply (GimpTextTool *text_tool) gimp_text_tool_apply (GimpTextTool *text_tool)
{ {
GimpImage *image; const GParamSpec *pspec = NULL;
GimpTextLayer *text_layer; GimpImage *image;
GObject *src; GimpTextLayer *text_layer;
GObject *dest; GObject *src;
GList *list; GObject *dest;
gboolean undo_group; GList *list;
gboolean undo_group;
if (text_tool->idle_id) if (text_tool->idle_id)
{ {
@ -500,6 +501,17 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
g_return_if_fail (text_layer->text == text_tool->text); g_return_if_fail (text_layer->text == text_tool->text);
/* Walk over the list of changes and figure out if we are changing
* a single property or need to push a full text undo.
*/
for (list = text_tool->pending;
list && list->next && list->next->data == list->data;
list = list->next)
/* do nothing */;
if (g_list_length (list) == 1)
pspec = list->data;
gimp_tool_control_set_preserve (GIMP_TOOL (text_tool)->control, TRUE); gimp_tool_control_set_preserve (GIMP_TOOL (text_tool)->control, TRUE);
/* If the layer contains a mask, /* If the layer contains a mask,
@ -513,7 +525,7 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
gimp_image_undo_push_drawable_mod (image, NULL, gimp_image_undo_push_drawable_mod (image, NULL,
GIMP_DRAWABLE (text_layer)); GIMP_DRAWABLE (text_layer));
gimp_image_undo_push_text_layer (image, NULL, text_layer); gimp_image_undo_push_text_layer (image, NULL, text_layer, pspec);
src = G_OBJECT (text_tool->proxy); src = G_OBJECT (text_tool->proxy);
dest = G_OBJECT (text_tool->text); dest = G_OBJECT (text_tool->text);
@ -523,15 +535,18 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
g_object_freeze_notify (dest); g_object_freeze_notify (dest);
for (list = text_tool->pending; list; list = list->next) for (; list; list = list->next)
{ {
GParamSpec *pspec = list->data; GValue value = { 0, };
GValue value = { 0, };
/* look ahead and compress changes */ /* look ahead and compress changes */
if (list->next && list->next->data == list->data) if (list->next && list->next->data == list->data)
continue; continue;
pspec = list->data;
g_printerr ("gimp_text_tool_apply: changing %s\n", pspec->name);
g_value_init (&value, pspec->value_type); g_value_init (&value, pspec->value_type);
g_object_get_property (src, pspec->name, &value); g_object_get_property (src, pspec->name, &value);

View file

@ -1778,6 +1778,18 @@ gimp_prop_size_entry_callback (GimpSizeEntry *sizeentry,
value = gimp_size_entry_get_value (sizeentry, 0); value = gimp_size_entry_get_value (sizeentry, 0);
unit_value = gimp_size_entry_get_unit (sizeentry); unit_value = gimp_size_entry_get_unit (sizeentry);
if (unit_param_spec)
{
GimpUnit old_unit;
g_object_get (config,
unit_param_spec->name, &old_unit,
NULL);
if (unit_value == old_unit)
unit_param_spec = NULL;
}
if (G_IS_PARAM_SPEC_INT (param_spec)) if (G_IS_PARAM_SPEC_INT (param_spec))
{ {
g_object_set (config, g_object_set (config,

View file

@ -1778,6 +1778,18 @@ gimp_prop_size_entry_callback (GimpSizeEntry *sizeentry,
value = gimp_size_entry_get_value (sizeentry, 0); value = gimp_size_entry_get_value (sizeentry, 0);
unit_value = gimp_size_entry_get_unit (sizeentry); unit_value = gimp_size_entry_get_unit (sizeentry);
if (unit_param_spec)
{
GimpUnit old_unit;
g_object_get (config,
unit_param_spec->name, &old_unit,
NULL);
if (unit_value == old_unit)
unit_param_spec = NULL;
}
if (G_IS_PARAM_SPEC_INT (param_spec)) if (G_IS_PARAM_SPEC_INT (param_spec))
{ {
g_object_set (config, g_object_set (config,