app, pdb, po: new GimpRasterizable interface.

Share the whole rasterize logic of the text, link and vector layer into
an interface. I didn't write it as an abstract parent class, because we
might have more rasterizable items in the future, which may not be
layers (e.g. there were discussions of vector masks).
This commit is contained in:
Jehan 2025-10-13 01:09:50 +02:00
parent 59c0e1ae6e
commit d593cb3230
34 changed files with 612 additions and 350 deletions

View file

@ -53,6 +53,7 @@
#include "core/gimplist.h"
#include "core/gimppickable.h"
#include "core/gimppickable-auto-shrink.h"
#include "core/gimprasterizable.h"
#include "core/gimptoolinfo.h"
#include "core/gimpundostack.h"
#include "core/gimpprogress.h"
@ -1121,12 +1122,8 @@ layers_rasterize_cmd_callback (GimpAction *action,
for (iter = layers; iter; iter = iter->next)
{
if (gimp_item_is_link_layer (iter->data))
gimp_link_layer_discard (GIMP_LINK_LAYER (iter->data));
else if (gimp_item_is_text_layer (iter->data))
gimp_text_layer_discard (GIMP_TEXT_LAYER (iter->data));
else if (gimp_item_is_vector_layer (iter->data))
gimp_vector_layer_discard (GIMP_VECTOR_LAYER (iter->data));
if (GIMP_IS_RASTERIZABLE (iter->data) && ! gimp_rasterizable_is_rasterized (iter->data))
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (iter->data));
}
gimp_image_undo_group_end (image);
@ -1148,12 +1145,8 @@ layers_retrieve_cmd_callback (GimpAction *action,
for (iter = layers; iter; iter = iter->next)
{
if (GIMP_IS_LINK_LAYER (iter->data) && ! gimp_item_is_link_layer (iter->data))
gimp_link_layer_monitor (GIMP_LINK_LAYER (iter->data));
else if (GIMP_IS_TEXT_LAYER (iter->data) && ! gimp_item_is_text_layer (iter->data))
gimp_text_layer_retrieve (GIMP_TEXT_LAYER (iter->data));
else if (GIMP_IS_VECTOR_LAYER (iter->data) && ! gimp_item_is_vector_layer (iter->data))
gimp_vector_layer_retrieve (GIMP_VECTOR_LAYER (iter->data));
if (GIMP_IS_RASTERIZABLE (iter->data) && gimp_rasterizable_is_rasterized (iter->data))
gimp_rasterizable_restore (GIMP_RASTERIZABLE (iter->data));
}
gimp_image_undo_group_end (image);

View file

@ -1266,10 +1266,8 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_GROUP_LAYER_END_TRANSFORM, "GIMP_UNDO_GROUP_LAYER_END_TRANSFORM", "group-layer-end-transform" },
{ GIMP_UNDO_GROUP_LAYER_CONVERT, "GIMP_UNDO_GROUP_LAYER_CONVERT", "group-layer-convert" },
{ GIMP_UNDO_TEXT_LAYER, "GIMP_UNDO_TEXT_LAYER", "text-layer" },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" },
{ GIMP_UNDO_TEXT_LAYER_CONVERT, "GIMP_UNDO_TEXT_LAYER_CONVERT", "text-layer-convert" },
{ GIMP_UNDO_VECTOR_LAYER, "GIMP_UNDO_VECTOR_LAYER", "vector-layer" },
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, "GIMP_UNDO_VECTOR_LAYER_MODIFIED", "vector-layer-modified" },
{ GIMP_UNDO_LAYER_MASK_ADD, "GIMP_UNDO_LAYER_MASK_ADD", "layer-mask-add" },
{ GIMP_UNDO_LAYER_MASK_REMOVE, "GIMP_UNDO_LAYER_MASK_REMOVE", "layer-mask-remove" },
{ GIMP_UNDO_LAYER_MASK_APPLY, "GIMP_UNDO_LAYER_MASK_APPLY", "layer-mask-apply" },
@ -1291,6 +1289,7 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_FILTER_REMOVE, "GIMP_UNDO_FILTER_REMOVE", "filter-remove" },
{ GIMP_UNDO_FILTER_REORDER, "GIMP_UNDO_FILTER_REORDER", "filter-reorder" },
{ GIMP_UNDO_FILTER_MODIFIED, "GIMP_UNDO_FILTER_MODIFIED", "filter-modified" },
{ GIMP_UNDO_RASTERIZABLE, "GIMP_UNDO_RASTERIZABLE", "rasterizable" },
{ GIMP_UNDO_CANT, "GIMP_UNDO_CANT", "cant" },
{ 0, NULL, NULL }
};
@ -1382,10 +1381,8 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_GROUP_LAYER_END_TRANSFORM, NC_("undo-type", "End transforming group layer"), NULL },
{ GIMP_UNDO_GROUP_LAYER_CONVERT, NC_("undo-type", "Convert group layer"), NULL },
{ GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text layer"), NULL },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, NC_("undo-type", "Text layer modification"), NULL },
{ GIMP_UNDO_TEXT_LAYER_CONVERT, NC_("undo-type", "Convert text layer"), NULL },
{ GIMP_UNDO_VECTOR_LAYER, NC_("undo-type", "Vector layer"), NULL },
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, NC_("undo-type", "Vector layer modification"), NULL },
{ GIMP_UNDO_LAYER_MASK_ADD, NC_("undo-type", "Add layer masks"), NULL },
{ GIMP_UNDO_LAYER_MASK_REMOVE, NC_("undo-type", "Delete layer masks"), NULL },
{ GIMP_UNDO_LAYER_MASK_APPLY, NC_("undo-type", "Apply layer masks"), NULL },
@ -1407,6 +1404,7 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_FILTER_REMOVE, NC_("undo-type", "Remove effect"), NULL },
{ GIMP_UNDO_FILTER_REORDER, NC_("undo-type", "Reorder effect"), NULL },
{ GIMP_UNDO_FILTER_MODIFIED, NC_("undo-type", "Effect modification"), NULL },
{ GIMP_UNDO_RASTERIZABLE, NC_("undo-type", "Text, link or vector layer"), NULL },
{ GIMP_UNDO_CANT, NC_("undo-type", "Not undoable"), NULL },
{ 0, NULL, NULL }
};

View file

@ -618,10 +618,8 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_GROUP_LAYER_END_TRANSFORM, /*< desc="End transforming group layer" >*/
GIMP_UNDO_GROUP_LAYER_CONVERT, /*< desc="Convert group layer" >*/
GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/
GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/
GIMP_UNDO_TEXT_LAYER_CONVERT, /*< desc="Convert text layer" >*/
GIMP_UNDO_VECTOR_LAYER, /*< desc="Vector layer" >*/
GIMP_UNDO_VECTOR_LAYER_MODIFIED, /*< desc="Vector layer modification" >*/
GIMP_UNDO_LAYER_MASK_ADD, /*< desc="Add layer masks" >*/
GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer masks" >*/
GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer masks" >*/
@ -643,6 +641,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_FILTER_REMOVE, /*< desc="Remove effect" >*/
GIMP_UNDO_FILTER_REORDER, /*< desc="Reorder effect" >*/
GIMP_UNDO_FILTER_MODIFIED, /*< desc="Effect modification" >*/
GIMP_UNDO_RASTERIZABLE, /*< desc="Text, link or vector layer" >*/
GIMP_UNDO_CANT /*< desc="Not undoable" >*/
} GimpUndoType;

View file

@ -163,6 +163,7 @@ typedef struct _GimpTagCache GimpTagCache;
typedef struct _GimpDrawable GimpDrawable;
typedef struct _GimpDrawableFilterMask GimpDrawableFilterMask;
typedef struct _GimpRasterizable GimpRasterizable;
typedef struct _GimpChannel GimpChannel;
typedef struct _GimpLayerMask GimpLayerMask;
typedef struct _GimpSelection GimpSelection;

View file

@ -234,3 +234,5 @@ void gimp_drawable_start_paint (GimpDrawable *drawable)
gboolean gimp_drawable_end_paint (GimpDrawable *drawable);
gboolean gimp_drawable_flush_paint (GimpDrawable *drawable);
gboolean gimp_drawable_is_painting (GimpDrawable *drawable);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GimpDrawable, g_object_unref);

View file

@ -51,6 +51,8 @@
#include "gimplinklayer.h"
#include "gimplinklayerundo.h"
#include "gimpmaskundo.h"
#include "gimprasterizable.h"
#include "gimprasterizableundo.h"
#include "gimpsamplepoint.h"
#include "gimpsamplepointundo.h"
#include "gimpselection.h"
@ -826,6 +828,27 @@ gimp_image_undo_push_group_layer_convert (GimpImage *image,
}
/************************/
/* Rasterizable Undos */
/************************/
GimpUndo *
gimp_image_undo_push_rasterizable (GimpImage *image,
const gchar *undo_desc,
GimpRasterizable *rasterizable)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_RASTERIZABLE (rasterizable), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (rasterizable)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_RASTERIZABLE_UNDO,
GIMP_UNDO_RASTERIZABLE, undo_desc,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
"item", rasterizable,
NULL);
}
/**********************/
/* Text Layer Undos */
/**********************/
@ -848,22 +871,6 @@ gimp_image_undo_push_text_layer (GimpImage *image,
NULL);
}
GimpUndo *
gimp_image_undo_push_text_layer_modified (GimpImage *image,
const gchar *undo_desc,
GimpTextLayer *layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_TEXT_UNDO,
GIMP_UNDO_TEXT_LAYER_MODIFIED, undo_desc,
GIMP_DIRTY_ITEM_META,
"item", layer,
NULL);
}
GimpUndo *
gimp_image_undo_push_text_layer_convert (GimpImage *image,
const gchar *undo_desc,
@ -880,6 +887,7 @@ gimp_image_undo_push_text_layer_convert (GimpImage *image,
NULL);
}
/**********************/
/* Link Layer Undos */
/**********************/
@ -922,22 +930,6 @@ gimp_image_undo_push_vector_layer (GimpImage *image,
NULL);
}
GimpUndo *
gimp_image_undo_push_vector_layer_modified (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_VECTOR_LAYER_UNDO,
GIMP_UNDO_VECTOR_LAYER_MODIFIED, undo_desc,
GIMP_DIRTY_ITEM_META,
"item", layer,
NULL);
}
/**********************/
/* Layer Mask Undos */

View file

@ -200,6 +200,11 @@ GimpUndo * gimp_image_undo_push_group_layer_convert (GimpImage *image,
const gchar *undo_desc,
GimpGroupLayer *group);
/* rasterizable undos */
GimpUndo * gimp_image_undo_push_rasterizable (GimpImage *image,
const gchar *undo_desc,
GimpRasterizable *rasterizable);
/* text layer undos */
@ -207,9 +212,6 @@ GimpUndo * gimp_image_undo_push_text_layer (GimpImage *image,
const gchar *undo_desc,
GimpTextLayer *layer,
const GParamSpec *pspec);
GimpUndo * gimp_image_undo_push_text_layer_modified (GimpImage *image,
const gchar *undo_desc,
GimpTextLayer *layer);
GimpUndo * gimp_image_undo_push_text_layer_convert (GimpImage *image,
const gchar *undo_desc,
GimpTextLayer *layer);
@ -226,10 +228,6 @@ GimpUndo * gimp_image_undo_push_vector_layer (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer,
const GParamSpec *pspec);
GimpUndo * gimp_image_undo_push_vector_layer_modified
(GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer);
/* layer mask undos */

View file

@ -45,3 +45,5 @@ struct _GimpItemUndoClass
GType gimp_item_undo_get_type (void) G_GNUC_CONST;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GimpItemUndo, g_object_unref);

View file

@ -43,11 +43,11 @@
#include "gimpimage-undo.h"
#include "gimpimage-undo-push.h"
#include "gimpitemtree.h"
#include "gimpobjectqueue.h"
#include "gimpprogress.h"
#include "gimplink.h"
#include "gimplinklayer.h"
#include "gimpobjectqueue.h"
#include "gimpprogress.h"
#include "gimprasterizable.h"
#include "gimp-intl.h"
@ -87,6 +87,9 @@ struct _GimpLinkLayerPrivate
gboolean keep_monitoring;
};
static void gimp_link_layer_rasterizable_iface_init
(GimpRasterizableInterface *iface);
static void gimp_link_layer_finalize (GObject *object);
static void gimp_link_layer_get_property (GObject *object,
guint property_id,
@ -140,6 +143,9 @@ static void gimp_link_layer_push_undo (GimpDrawable *drawable,
gint width,
gint height);
static void gimp_link_layer_set_rasterized (GimpRasterizable *rasterizable,
gboolean rasterized);
static void gimp_link_layer_convert_type (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
@ -162,7 +168,10 @@ static gboolean
gint *new_offset_y);
G_DEFINE_TYPE_WITH_PRIVATE (GimpLinkLayer, gimp_link_layer, GIMP_TYPE_LAYER)
G_DEFINE_TYPE_WITH_CODE (GimpLinkLayer, gimp_link_layer, GIMP_TYPE_LAYER,
G_ADD_PRIVATE (GimpLinkLayer)
G_IMPLEMENT_INTERFACE (GIMP_TYPE_RASTERIZABLE,
gimp_link_layer_rasterizable_iface_init))
#define parent_class gimp_link_layer_parent_class
@ -245,6 +254,12 @@ gimp_link_layer_init (GimpLinkLayer *layer)
layer->p->keep_monitoring = FALSE;
}
static void
gimp_link_layer_rasterizable_iface_init (GimpRasterizableInterface *iface)
{
iface->set_rasterized = gimp_link_layer_set_rasterized;
}
static void
gimp_link_layer_finalize (GObject *object)
{
@ -677,6 +692,24 @@ gimp_link_layer_push_undo (GimpDrawable *drawable,
}
}
static void
gimp_link_layer_set_rasterized (GimpRasterizable *rasterizable,
gboolean rasterized)
{
GimpLinkLayer *layer = GIMP_LINK_LAYER (rasterizable);
if (rasterized)
{
gimp_link_freeze (layer->p->link);
}
else
{
gimp_link_thaw (layer->p->link);
gimp_matrix3_identity (&layer->p->matrix);
gimp_link_layer_render_link (layer);
}
}
static void
gimp_link_layer_convert_type (GimpLayer *layer,
GimpImage *dest_image,
@ -822,44 +855,6 @@ gimp_link_layer_set_link_with_matrix (GimpLinkLayer *layer,
return rendered;
}
/**
* gimp_link_layer_discard:
* @layer: a #GimpLinkLayer
*
* Discards the link. This makes @layer behave like a
* normal layer.
*/
void
gimp_link_layer_discard (GimpLinkLayer *layer)
{
g_return_if_fail (GIMP_IS_LINK_LAYER (layer));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
gimp_image_undo_push_link_layer (gimp_item_get_image (GIMP_ITEM (layer)),
_("Discard Link"), layer);
gimp_link_freeze (layer->p->link);
/* Triggers thumbnail update. */
gimp_drawable_update_all (GIMP_DRAWABLE (layer));
/* Triggers contextual menu update. */
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer)));
}
void
gimp_link_layer_monitor (GimpLinkLayer *layer)
{
g_return_if_fail (GIMP_IS_LINK_LAYER (layer));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
gimp_image_undo_push_link_layer (gimp_item_get_image (GIMP_ITEM (layer)),
_("Monitor Link"), layer);
gimp_link_thaw (layer->p->link);
gimp_matrix3_identity (&layer->p->matrix);
gimp_link_layer_render_link (layer);
}
gboolean
gimp_link_layer_is_monitored (GimpLinkLayer *layer)
{

View file

@ -64,8 +64,6 @@ gboolean gimp_link_layer_set_link_with_matrix (GimpLinkLayer *layer,
gint offset_y,
gboolean push_undo);
void gimp_link_layer_discard (GimpLinkLayer *layer);
void gimp_link_layer_monitor (GimpLinkLayer *layer);
gboolean gimp_link_layer_is_monitored (GimpLinkLayer *layer);
gboolean gimp_link_layer_get_transform (GimpLinkLayer *layer,

212
app/core/gimprasterizable.c Normal file
View file

@ -0,0 +1,212 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimprasterizable.c
* Copyright (C) 2025 Jehan
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "core-types.h"
#include "gimpimage.h"
#include "gimpimage-undo.h"
#include "gimpimage-undo-push.h"
#include "gimprasterizable.h"
#include "gimp-intl.h"
enum
{
SET_RASTERIZED,
LAST_SIGNAL
};
typedef struct _GimpRasterizablePrivate GimpRasterizablePrivate;
struct _GimpRasterizablePrivate
{
gboolean rasterized;
};
#define GIMP_RASTERIZABLE_GET_PRIVATE(obj) (gimp_rasterizable_get_private ((GimpRasterizable *) (obj)))
static GimpRasterizablePrivate * gimp_rasterizable_get_private (GimpRasterizable *rasterizable);
static void gimp_rasterizable_private_finalize (GimpRasterizablePrivate *private);
G_DEFINE_INTERFACE (GimpRasterizable, gimp_rasterizable, GIMP_TYPE_DRAWABLE)
static guint gimp_rasterizable_signals[LAST_SIGNAL] = { 0, };
static void
gimp_rasterizable_default_init (GimpRasterizableInterface *iface)
{
gimp_rasterizable_signals[SET_RASTERIZED] =
g_signal_new ("set-rasterized",
GIMP_TYPE_RASTERIZABLE,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GimpRasterizableInterface, set_rasterized),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
G_TYPE_BOOLEAN);
}
/* Public functions */
/**
* gimp_rasterizable_rasterize:
* @rasterizable: an object that implements the %GimpRasterizable interface
*
* Rasterize @rasterizable.
**/
void
gimp_rasterizable_rasterize (GimpRasterizable *rasterizable)
{
GimpRasterizablePrivate *private;
GimpImage *image;
gchar *undo_text;
g_return_if_fail (GIMP_IS_RASTERIZABLE (rasterizable));
g_return_if_fail (! gimp_rasterizable_is_rasterized (rasterizable));
private = GIMP_RASTERIZABLE_GET_PRIVATE (rasterizable);
image = gimp_item_get_image (GIMP_ITEM (rasterizable));
/* TRANSLATORS: the %s will be a type of item, i.e. "Text Layer". */
undo_text = g_strdup_printf (_("Rasterize %s"),
GIMP_VIEWABLE_GET_CLASS (rasterizable)->default_name);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES, undo_text);
gimp_image_undo_push_rasterizable (image, NULL, rasterizable);
private->rasterized = TRUE;
g_signal_emit (rasterizable, gimp_rasterizable_signals[SET_RASTERIZED], 0, TRUE);
gimp_image_undo_group_end (image);
/* Triggers thumbnail update. */
gimp_drawable_update_all (GIMP_DRAWABLE (rasterizable));
/* Triggers contextual menu update. */
gimp_image_flush (image);
}
/**
* gimp_rasterizable_restore:
* @rasterizable: an object that implements the %GimpRasterizable interface
*
* Revert the rasterization of @rasterizable.
**/
void
gimp_rasterizable_restore (GimpRasterizable *rasterizable)
{
GimpRasterizablePrivate *private;
GimpImage *image;
gchar *undo_text;
g_return_if_fail (GIMP_IS_RASTERIZABLE (rasterizable));
g_return_if_fail (gimp_rasterizable_is_rasterized (rasterizable));
private = GIMP_RASTERIZABLE_GET_PRIVATE (rasterizable);
image = gimp_item_get_image (GIMP_ITEM (rasterizable));
/* TRANSLATORS: the %s will be a type of item, i.e. "Text Layer". */
undo_text = g_strdup_printf (_("Revert Rasterize %s"),
GIMP_VIEWABLE_GET_CLASS (rasterizable)->default_name);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES, undo_text);
gimp_image_undo_push_rasterizable (image, NULL, rasterizable);
gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (rasterizable), TRUE);
private->rasterized = FALSE;
g_signal_emit (rasterizable, gimp_rasterizable_signals[SET_RASTERIZED], 0, FALSE);
gimp_image_undo_group_end (image);
gimp_image_flush (image);
}
/**
* gimp_rasterizable_is_rasterized:
* @rasterizable: an object that implements the %GimpRasterizable interface
*
* Returns: whether @rasterizable is rasterized or not.
**/
gboolean
gimp_rasterizable_is_rasterized (GimpRasterizable *rasterizable)
{
GimpRasterizablePrivate *private;
g_return_val_if_fail (GIMP_IS_RASTERIZABLE (rasterizable), FALSE);
private = GIMP_RASTERIZABLE_GET_PRIVATE (rasterizable);
return private->rasterized;
}
void
gimp_rasterizable_set_undo_rasterized (GimpRasterizable *rasterizable,
gboolean rasterized)
{
GimpRasterizablePrivate *private;
g_return_if_fail (GIMP_IS_RASTERIZABLE (rasterizable));
private = GIMP_RASTERIZABLE_GET_PRIVATE (rasterizable);
private->rasterized = rasterized;
}
/* Private functions */
static GimpRasterizablePrivate *
gimp_rasterizable_get_private (GimpRasterizable *rasterizable)
{
GimpRasterizablePrivate *private;
static GQuark private_key = 0;
g_return_val_if_fail (GIMP_IS_RASTERIZABLE (rasterizable), NULL);
if (! private_key)
private_key = g_quark_from_static_string ("gimp-rasterizable-private");
private = g_object_get_qdata ((GObject *) rasterizable, private_key);
if (! private)
{
private = g_slice_new0 (GimpRasterizablePrivate);
g_object_set_qdata_full ((GObject *) rasterizable, private_key, private,
(GDestroyNotify) gimp_rasterizable_private_finalize);
}
return private;
}
static void
gimp_rasterizable_private_finalize (GimpRasterizablePrivate *private)
{
g_slice_free (GimpRasterizablePrivate, private);
}

View file

@ -0,0 +1,47 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* gimprasterizable.h
* Copyright (C) 2025 Jehan
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "gimpdrawable.h"
#define GIMP_TYPE_RASTERIZABLE (gimp_rasterizable_get_type ())
G_DECLARE_INTERFACE (GimpRasterizable, gimp_rasterizable, GIMP, RASTERIZABLE, GimpDrawable)
struct _GimpRasterizableInterface
{
GTypeInterface base_iface;
/* signals */
void (* set_rasterized) (GimpRasterizable *rasterizable,
gboolean rasterized);
};
void gimp_rasterizable_rasterize (GimpRasterizable *rasterizable);
void gimp_rasterizable_restore (GimpRasterizable *rasterizable);
gboolean gimp_rasterizable_is_rasterized (GimpRasterizable *rasterizable);
/* To be used for undo steps only */
void gimp_rasterizable_set_undo_rasterized (GimpRasterizable *rasterizable,
gboolean rasterize);

View file

@ -0,0 +1,117 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimprasterizableundo.c
* Copyright (C) 2025 Jehan
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "core-types.h"
#include "gimprasterizable.h"
#include "gimprasterizableundo.h"
struct _GimpRasterizableUndo
{
GimpItemUndo parent_instance;
gboolean rasterized;
};
static void gimp_rasterizable_undo_constructed (GObject *object);
static void gimp_rasterizable_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
G_DEFINE_TYPE (GimpRasterizableUndo, gimp_rasterizable_undo, GIMP_TYPE_ITEM_UNDO)
#define parent_class gimp_rasterizable_undo_parent_class
static void
gimp_rasterizable_undo_class_init (GimpRasterizableUndoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructed = gimp_rasterizable_undo_constructed;
undo_class->pop = gimp_rasterizable_undo_pop;
}
static void
gimp_rasterizable_undo_init (GimpRasterizableUndo *undo)
{
}
static void
gimp_rasterizable_undo_constructed (GObject *object)
{
GimpRasterizableUndo *undo = GIMP_RASTERIZABLE_UNDO (object);
GimpRasterizable *rasterizable;
G_OBJECT_CLASS (parent_class)->constructed (object);
gimp_assert (GIMP_IS_RASTERIZABLE (GIMP_ITEM_UNDO (undo)->item));
rasterizable = GIMP_RASTERIZABLE (GIMP_ITEM_UNDO (undo)->item);
switch (GIMP_UNDO (object)->undo_type)
{
case GIMP_UNDO_RASTERIZABLE:
undo->rasterized = gimp_rasterizable_is_rasterized (rasterizable);
break;
default:
gimp_assert_not_reached ();
}
}
static void
gimp_rasterizable_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GimpRasterizableUndo *rundo = GIMP_RASTERIZABLE_UNDO (undo);
GimpRasterizable *rasterizable = GIMP_RASTERIZABLE (GIMP_ITEM_UNDO (undo)->item);
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
switch (undo->undo_type)
{
case GIMP_UNDO_RASTERIZABLE:
{
gboolean rasterized = gimp_rasterizable_is_rasterized (rasterizable);
gimp_rasterizable_set_undo_rasterized (rasterizable, rundo->rasterized);
rundo->rasterized = rasterized;
GIMP_RASTERIZABLE_GET_IFACE (rasterizable)->set_rasterized (rasterizable, ! rasterized);
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (rasterizable));
}
break;
default:
gimp_assert_not_reached ();
}
}

View file

@ -0,0 +1,26 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimprasterizableundo.h
* Copyright (C) 2025 Jehan
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "gimpitemundo.h"
#define GIMP_TYPE_RASTERIZABLE_UNDO (gimp_rasterizable_undo_get_type ())
G_DECLARE_FINAL_TYPE (GimpRasterizableUndo, gimp_rasterizable_undo, GIMP, RASTERIZABLE_UNDO, GimpItemUndo)

View file

@ -224,6 +224,8 @@ libappcore_sources = [
'gimpprogress.c',
'gimpprojectable.c',
'gimpprojection.c',
'gimprasterizable.c',
'gimprasterizableundo.c',
'gimpresource.c',
'gimpsamplepoint.c',
'gimpsamplepointundo.c',

View file

@ -42,6 +42,7 @@
#include "core/gimpimage-undo-push.h"
#include "core/gimpstrokeoptions.h"
#include "core/gimpparasitelist.h"
#include "core/gimprasterizable.h"
#include "gimpvectorlayer.h"
#include "gimpvectorlayeroptions.h"
@ -54,12 +55,15 @@ enum
{
PROP_0,
PROP_VECTOR_LAYER_OPTIONS,
PROP_MODIFIED
};
/* local function declarations */
static void gimp_vector_layer_rasterizable_iface_init
(GimpRasterizableInterface *iface);
static void gimp_vector_layer_finalize (GObject *object);
static void gimp_vector_layer_get_property (GObject *object,
guint property_id,
@ -69,6 +73,10 @@ static void gimp_vector_layer_set_property (GObject *obj
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_vector_layer_set_rasterized (GimpRasterizable *rasterizable,
gboolean rasterized);
static void gimp_vector_layer_set_vector_options
(GimpVectorLayer *layer,
GimpVectorLayerOptions *options);
@ -132,7 +140,9 @@ static void gimp_vector_layer_removed_options_path
(GimpVectorLayer *layer);
G_DEFINE_TYPE (GimpVectorLayer, gimp_vector_layer, GIMP_TYPE_LAYER)
G_DEFINE_TYPE_WITH_CODE (GimpVectorLayer, gimp_vector_layer, GIMP_TYPE_LAYER,
G_IMPLEMENT_INTERFACE (GIMP_TYPE_RASTERIZABLE,
gimp_vector_layer_rasterizable_iface_init))
#define parent_class gimp_vector_layer_parent_class
@ -180,19 +190,18 @@ gimp_vector_layer_class_init (GimpVectorLayerClass *klass)
"vector-layer-options", NULL, NULL,
GIMP_TYPE_VECTOR_LAYER_OPTIONS,
G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_MODIFIED,
"modified",
NULL, NULL,
FALSE,
GIMP_PARAM_STATIC_STRINGS);
}
static void
gimp_vector_layer_init (GimpVectorLayer *layer)
{
layer->options = NULL;
layer->modified = FALSE;
}
static void
gimp_vector_layer_rasterizable_iface_init (GimpRasterizableInterface *iface)
{
iface->set_rasterized = gimp_vector_layer_set_rasterized;
}
static void
@ -222,9 +231,6 @@ gimp_vector_layer_get_property (GObject *object,
case PROP_VECTOR_LAYER_OPTIONS:
g_value_set_object (value, vector_layer->options);
break;
case PROP_MODIFIED:
g_value_set_boolean (value, vector_layer->modified);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -245,9 +251,6 @@ gimp_vector_layer_set_property (GObject *object,
case PROP_VECTOR_LAYER_OPTIONS:
gimp_vector_layer_set_vector_options (vector_layer, g_value_get_object (value));
break;
case PROP_MODIFIED:
vector_layer->modified = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -255,6 +258,14 @@ gimp_vector_layer_set_property (GObject *object,
}
}
static void
gimp_vector_layer_set_rasterized (GimpRasterizable *rasterizable,
gboolean rasterized)
{
if (! rasterized)
gimp_vector_layer_render (GIMP_VECTOR_LAYER (rasterizable));
}
static void
gimp_vector_layer_set_vector_options (GimpVectorLayer *layer,
GimpVectorLayerOptions *options)
@ -303,8 +314,11 @@ gimp_vector_layer_set_buffer (GimpDrawable *drawable,
{
GimpVectorLayer *layer = GIMP_VECTOR_LAYER (drawable);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
gboolean is_rasterized;
if (push_undo && ! layer->modified)
is_rasterized = gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer));
if (push_undo && ! is_rasterized)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE_MOD,
undo_desc);
@ -312,12 +326,9 @@ gimp_vector_layer_set_buffer (GimpDrawable *drawable,
push_undo, undo_desc,
buffer, bounds);
if (push_undo && ! layer->modified)
if (push_undo && ! is_rasterized)
{
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
gimp_image_undo_group_end (image);
}
}
@ -333,20 +344,20 @@ gimp_vector_layer_push_undo (GimpDrawable *drawable,
{
GimpVectorLayer *layer = GIMP_VECTOR_LAYER (drawable);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
gboolean is_rasterized;
if (! layer->modified)
is_rasterized = gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer));
if (! is_rasterized)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE, undo_desc);
GIMP_DRAWABLE_CLASS (parent_class)->push_undo (drawable, undo_desc,
buffer,
x, y, width, height);
if (! layer->modified)
if (! is_rasterized)
{
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
gimp_image_undo_group_end (image);
}
}
@ -646,62 +657,11 @@ gimp_vector_layer_refresh (GimpVectorLayer *layer)
gimp_vector_layer_render (layer);
}
/**
* gimp_vector_layer_discard:
* @layer: a #GimpVectorLayer
*
* Discards the vector information. This makes @layer behave like a
* normal layer.
*/
void
gimp_vector_layer_discard (GimpVectorLayer *layer)
{
GimpImage *image;
g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
if (layer->modified)
return;
image = gimp_item_get_image (GIMP_ITEM (layer));
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
g_object_set (layer, "modified", TRUE, NULL);
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer)));
}
void
gimp_vector_layer_retrieve (GimpVectorLayer *layer)
{
GimpImage *image;
g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
if (! layer->modified)
return;
image = gimp_item_get_image (GIMP_ITEM (layer));
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES,
_("Revert Rasterize Vector Layer"));
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (layer), TRUE);
g_object_set (layer, "modified", FALSE, NULL);
gimp_image_undo_group_end (image);
gimp_vector_layer_render (layer);
gimp_image_flush (image);
}
gboolean
gimp_item_is_vector_layer (GimpItem *item)
{
return (GIMP_IS_VECTOR_LAYER (item) && ! GIMP_VECTOR_LAYER (item)->modified);
return (GIMP_IS_VECTOR_LAYER (item) &&
! gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (item)));
}
@ -817,7 +777,7 @@ gimp_vector_layer_changed_options (GimpVectorLayer *layer)
GimpItem *item = GIMP_ITEM (layer);
if (layer->options && ! layer->options->path)
gimp_vector_layer_discard (layer);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
else if (gimp_item_is_attached (item))
gimp_vector_layer_refresh (layer);
}

View file

@ -41,7 +41,6 @@ struct _GimpVectorLayer
GimpLayer parent_instance;
GimpVectorLayerOptions *options;
gboolean modified;
};
struct _GimpVectorLayerClass
@ -61,8 +60,6 @@ GimpPath * gimp_vector_layer_get_path (GimpVectorLayer *layer)
GimpVectorLayerOptions * gimp_vector_layer_get_options (GimpVectorLayer *layer);
void gimp_vector_layer_refresh (GimpVectorLayer *layer);
void gimp_vector_layer_discard (GimpVectorLayer *layer);
void gimp_vector_layer_retrieve (GimpVectorLayer *layer);
gboolean gimp_item_is_vector_layer (GimpItem *item);

View file

@ -30,9 +30,9 @@
#include "path-types.h"
#include "core/gimp-memsize.h"
#include "core/gimp-utils.h"
#include "core/gimpitem.h"
#include "core/gimpitemundo.h"
#include "core/gimp-utils.h"
#include "gimpvectorlayer.h"
#include "gimpvectorlayeroptions.h"
@ -128,10 +128,6 @@ gimp_vector_layer_undo_constructed (GObject *object)
}
break;
case GIMP_UNDO_VECTOR_LAYER_MODIFIED:
vector_undo->modified = vector_layer->modified;
break;
default:
g_assert_not_reached ();
}
@ -246,18 +242,6 @@ gimp_vector_layer_undo_pop (GimpUndo *undo,
}
break;
case GIMP_UNDO_VECTOR_LAYER_MODIFIED:
{
gboolean modified;
modified = vector_layer->modified;
g_object_set (vector_layer, "modified", vector_undo->modified, NULL);
vector_undo->modified = modified;
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (vector_layer));
}
break;
default:
g_assert_not_reached ();
}

View file

@ -43,7 +43,6 @@ struct _GimpVectorLayerUndo
GimpVectorLayerOptions *vector_layer_options;
const GParamSpec *pspec;
GValue *value;
gboolean modified;
};
struct _GimpVectorLayerUndoClass

View file

@ -33,6 +33,7 @@
#include "core/gimplink.h"
#include "core/gimplinklayer.h"
#include "core/gimpparamspecs.h"
#include "core/gimprasterizable.h"
#include "gimppdb.h"
#include "gimppdberror.h"
@ -120,7 +121,7 @@ link_layer_discard_invoker (GimpProcedure *procedure,
if (success)
{
gimp_link_layer_discard (layer);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
}
return gimp_procedure_get_return_values (procedure, success,
@ -142,7 +143,7 @@ link_layer_monitor_invoker (GimpProcedure *procedure,
if (success)
{
gimp_link_layer_monitor (layer);
gimp_rasterizable_restore (GIMP_RASTERIZABLE (layer));
}
return gimp_procedure_get_return_values (procedure, success,

View file

@ -38,6 +38,7 @@
#include "core/gimpdashpattern.h"
#include "core/gimpimage.h"
#include "core/gimpparamspecs.h"
#include "core/gimprasterizable.h"
#include "core/gimpstrokeoptions.h"
#include "path/gimppath.h"
#include "path/gimpvectorlayer.h"
@ -139,7 +140,7 @@ vector_layer_discard_invoker (GimpProcedure *procedure,
if (success)
{
gimp_vector_layer_discard (layer);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
}
return gimp_procedure_get_return_values (procedure, success,

View file

@ -29,6 +29,7 @@
#include "core/gimp-transform-utils.h"
#include "core/gimpimage-undo.h"
#include "core/gimprasterizable.h"
#include "gimptext.h"
#include "gimptextlayer.h"
@ -169,7 +170,7 @@ static gboolean
gimp_text_layer_get_transformation (GimpTextLayer *layer,
GimpMatrix3 *matrix)
{
if (! layer->text || layer->modified)
if (! layer->text || gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer)))
return FALSE;
gimp_text_get_transformation (layer->text, matrix);

View file

@ -32,6 +32,7 @@
#include "core/gimpimage.h"
#include "core/gimplayer-xcf.h"
#include "core/gimpparasitelist.h"
#include "core/gimprasterizable.h"
#include "gimptext.h"
#include "gimptext-parasite.h"
@ -153,7 +154,7 @@ gimp_text_layer_get_xcf_flags (GimpTextLayer *text_layer)
if (! text_layer->auto_rename)
flags |= TEXT_LAYER_XCF_DONT_AUTO_RENAME;
if (text_layer->modified)
if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (text_layer)))
flags |= TEXT_LAYER_XCF_MODIFIED;
return flags;
@ -167,6 +168,8 @@ gimp_text_layer_set_xcf_flags (GimpTextLayer *text_layer,
g_object_set (text_layer,
"auto-rename", (flags & TEXT_LAYER_XCF_DONT_AUTO_RENAME) == 0,
"modified", (flags & TEXT_LAYER_XCF_MODIFIED) != 0,
NULL);
if ((flags & TEXT_LAYER_XCF_MODIFIED) != 0)
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (text_layer));
}

View file

@ -49,6 +49,7 @@
#include "core/gimpitemtree.h"
#include "core/gimpparasitelist.h"
#include "core/gimppattern.h"
#include "core/gimprasterizable.h"
#include "core/gimptempbuf.h"
#include "gimptext.h"
@ -64,7 +65,6 @@ enum
PROP_0,
PROP_TEXT,
PROP_AUTO_RENAME,
PROP_MODIFIED
};
struct _GimpTextLayerPrivate
@ -72,6 +72,9 @@ struct _GimpTextLayerPrivate
GimpTextDirection base_dir;
};
static void gimp_text_layer_rasterizable_iface_init
(GimpRasterizableInterface *iface);
static void gimp_text_layer_finalize (GObject *object);
static void gimp_text_layer_get_property (GObject *object,
guint property_id,
@ -82,6 +85,9 @@ static void gimp_text_layer_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec);
static void gimp_text_layer_set_rasterized (GimpRasterizable *rasterizable,
gboolean rasterized);
static gint64 gimp_text_layer_get_memsize (GimpObject *object,
gint64 *gui_size);
@ -123,7 +129,10 @@ static void gimp_text_layer_render_layout (GimpTextLayer *layer,
GimpTextLayout *layout);
G_DEFINE_TYPE_WITH_PRIVATE (GimpTextLayer, gimp_text_layer, GIMP_TYPE_LAYER)
G_DEFINE_TYPE_WITH_CODE (GimpTextLayer, gimp_text_layer, GIMP_TYPE_LAYER,
G_ADD_PRIVATE (GimpTextLayer)
G_IMPLEMENT_INTERFACE (GIMP_TYPE_RASTERIZABLE,
gimp_text_layer_rasterizable_iface_init))
#define parent_class gimp_text_layer_parent_class
@ -182,12 +191,6 @@ gimp_text_layer_class_init (GimpTextLayerClass *klass)
NULL, NULL,
TRUE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_MODIFIED,
"modified",
NULL, NULL,
FALSE,
GIMP_PARAM_STATIC_STRINGS);
}
static void
@ -199,6 +202,12 @@ gimp_text_layer_init (GimpTextLayer *layer)
layer->private = gimp_text_layer_get_instance_private (layer);
}
static void
gimp_text_layer_rasterizable_iface_init (GimpRasterizableInterface *iface)
{
iface->set_rasterized = gimp_text_layer_set_rasterized;
}
static void
gimp_text_layer_finalize (GObject *object)
{
@ -225,9 +234,6 @@ gimp_text_layer_get_property (GObject *object,
case PROP_AUTO_RENAME:
g_value_set_boolean (value, text_layer->auto_rename);
break;
case PROP_MODIFIED:
g_value_set_boolean (value, text_layer->modified);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -251,9 +257,6 @@ gimp_text_layer_set_property (GObject *object,
case PROP_AUTO_RENAME:
text_layer->auto_rename = g_value_get_boolean (value);
break;
case PROP_MODIFIED:
text_layer->modified = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -261,6 +264,14 @@ gimp_text_layer_set_property (GObject *object,
}
}
static void
gimp_text_layer_set_rasterized (GimpRasterizable *rasterizable,
gboolean rasterized)
{
if (! rasterized)
gimp_text_layer_render (GIMP_TEXT_LAYER (rasterizable));
}
static gint64
gimp_text_layer_get_memsize (GimpObject *object,
gint64 *gui_size)
@ -284,7 +295,7 @@ gimp_text_layer_size_changed (GimpViewable *viewable)
* gimp_drawable_size_changed () if the layer has been rasterized by
* a transform. This prevents filters like Drop Shadow from being
* cropped just by typing */
if (text_layer->modified)
if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (text_layer)))
GIMP_VIEWABLE_CLASS (parent_class)->size_changed (viewable);
}
@ -352,8 +363,11 @@ gimp_text_layer_set_buffer (GimpDrawable *drawable,
{
GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
gboolean is_rasterized;
if (push_undo && ! layer->modified)
is_rasterized = gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer));
if (push_undo && ! is_rasterized)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE_MOD,
undo_desc);
@ -361,12 +375,9 @@ gimp_text_layer_set_buffer (GimpDrawable *drawable,
push_undo, undo_desc,
buffer, bounds);
if (push_undo && ! layer->modified)
if (push_undo && ! is_rasterized)
{
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
gimp_image_undo_group_end (image);
}
}
@ -382,20 +393,20 @@ gimp_text_layer_push_undo (GimpDrawable *drawable,
{
GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
gboolean is_rasterized;
if (! layer->modified)
is_rasterized = gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer));
if (! is_rasterized)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE, undo_desc);
GIMP_DRAWABLE_CLASS (parent_class)->push_undo (drawable, undo_desc,
buffer,
x, y, width, height);
if (! layer->modified)
if (! is_rasterized)
{
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
gimp_image_undo_group_end (image);
}
}
@ -414,8 +425,8 @@ gimp_text_layer_convert_type (GimpLayer *layer,
GimpTextLayer *text_layer = GIMP_TEXT_LAYER (layer);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (text_layer));
if (! text_layer->text ||
text_layer->modified ||
if (! text_layer->text ||
gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer)) ||
layer_dither_type != GEGL_DITHER_NONE)
{
GIMP_LAYER_CLASS (parent_class)->convert_type (layer, dest_image,
@ -550,10 +561,8 @@ gimp_text_layer_set (GimpTextLayer *layer,
g_object_freeze_notify (G_OBJECT (layer));
if (layer->modified)
if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer)))
{
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
/* pass copy_tiles = TRUE so we not only ref the tiles; after
* being a text layer again, undo doesn't care about the
* layer's pixels any longer because they are generated, so
@ -568,74 +577,21 @@ gimp_text_layer_set (GimpTextLayer *layer,
gimp_image_undo_push_text_layer (image, undo_desc, layer, NULL);
va_start (var_args, first_property_name);
g_object_set_valist (G_OBJECT (text), first_property_name, var_args);
va_end (var_args);
g_object_set (layer, "modified", FALSE, NULL);
gimp_rasterizable_restore (GIMP_RASTERIZABLE (layer));
g_object_thaw_notify (G_OBJECT (layer));
gimp_image_undo_group_end (image);
}
/**
* gimp_text_layer_discard:
* @layer: a #GimpTextLayer
*
* Discards the text information. This makes @layer behave like a
* normal layer.
*/
void
gimp_text_layer_discard (GimpTextLayer *layer)
{
GimpImage *image;
g_return_if_fail (GIMP_IS_TEXT_LAYER (layer));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
if (layer->modified)
return;
image = gimp_item_get_image (GIMP_ITEM (layer));
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
g_object_set (layer, "modified", TRUE, NULL);
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
/* Though technically selected layers are not changed, it will trigger
* actions update, so that visibility of any action depending on text
* layers being rasterized or not will be updated.
*/
g_signal_emit_by_name (image, "selected-layers-changed");
}
void
gimp_text_layer_retrieve (GimpTextLayer *layer)
{
GimpImage *image;
g_return_if_fail (GIMP_IS_TEXT_LAYER (layer));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
if (! layer->modified)
return;
image = gimp_item_get_image (GIMP_ITEM (layer));
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (layer), TRUE);
g_object_set (layer, "modified", FALSE, NULL);
gimp_text_layer_render (layer);
gimp_image_flush (image);
}
gboolean
gimp_item_is_text_layer (GimpItem *item)
{
return (GIMP_IS_TEXT_LAYER (item) && ! GIMP_TEXT_LAYER (item)->modified);
return (GIMP_IS_TEXT_LAYER (item) &&
! gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (item)));
}

View file

@ -45,7 +45,6 @@ struct _GimpTextLayer
*/
gboolean text_parasite_is_old; /* Format before XCF 19. */
gboolean auto_rename;
gboolean modified;
const Babl *convert_format;
@ -65,8 +64,6 @@ GimpLayer * gimp_text_layer_new (GimpImage *image,
GimpText * gimp_text_layer_get_text (GimpTextLayer *layer);
void gimp_text_layer_set_text (GimpTextLayer *layer,
GimpText *text);
void gimp_text_layer_discard (GimpTextLayer *layer);
void gimp_text_layer_retrieve (GimpTextLayer *layer);
void gimp_text_layer_set (GimpTextLayer *layer,
const gchar *undo_desc,
const gchar *first_property_name,

View file

@ -127,10 +127,6 @@ gimp_text_undo_constructed (GObject *object)
}
break;
case GIMP_UNDO_TEXT_LAYER_MODIFIED:
text_undo->modified = layer->modified;
break;
case GIMP_UNDO_TEXT_LAYER_CONVERT:
text_undo->format = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
break;
@ -247,24 +243,6 @@ gimp_text_undo_pop (GimpUndo *undo,
}
break;
case GIMP_UNDO_TEXT_LAYER_MODIFIED:
{
gboolean modified;
#if 0
g_print ("setting layer->modified from %s to %s\n",
layer->modified ? "TRUE" : "FALSE",
text_undo->modified ? "TRUE" : "FALSE");
#endif
modified = layer->modified;
g_object_set (layer, "modified", text_undo->modified, NULL);
text_undo->modified = modified;
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
}
break;
case GIMP_UNDO_TEXT_LAYER_CONVERT:
{
const Babl *format;

View file

@ -37,7 +37,6 @@ struct _GimpTextUndo
GimpText *text;
const GParamSpec *pspec;
GValue *value;
gboolean modified;
const Babl *format;
};

View file

@ -35,6 +35,7 @@
#include "core/gimpimage-pick-item.h"
#include "core/gimpimage-undo.h"
#include "core/gimpimage-undo-push.h"
#include "core/gimprasterizable.h"
#include "core/gimpstrokeoptions.h"
#include "core/gimptoolinfo.h"
#include "core/gimpundostack.h"
@ -149,9 +150,8 @@ static void gimp_path_tool_vector_change_notify
const GParamSpec *pspec,
GimpVectorLayer *layer);
static void gimp_path_tool_vector_layer_modified
(GimpVectorLayer *layer,
const GParamSpec *pspec,
static void gimp_path_tool_layer_rasterized (GimpVectorLayer *layer,
gboolean is_rasterized,
GimpPathTool *tool);
static void gimp_path_tool_set_layer (GimpPathTool *path_tool,
@ -903,11 +903,11 @@ gimp_path_tool_vector_change_notify (GObject *options,
}
static void
gimp_path_tool_vector_layer_modified (GimpVectorLayer *layer,
const GParamSpec *pspec,
GimpPathTool *tool)
gimp_path_tool_layer_rasterized (GimpVectorLayer *layer,
gboolean is_rasterized,
GimpPathTool *tool)
{
if (! layer->modified && ! GIMP_TOOL (tool)->display)
if (! is_rasterized && ! GIMP_TOOL (tool)->display)
{
GList *current_layers = NULL;
@ -919,7 +919,7 @@ gimp_path_tool_vector_layer_modified (GimpVectorLayer *layer,
current_layers->data == layer)
gimp_path_tool_set_layer (tool, layer);
}
else if (layer->modified && GIMP_TOOL (tool)->display)
else if (is_rasterized && GIMP_TOOL (tool)->display)
{
gimp_path_tool_set_layer (tool, NULL);
}
@ -948,7 +948,7 @@ gimp_path_tool_set_layer (GimpPathTool *path_tool,
path_tool->current_vector_layer);
g_signal_handlers_disconnect_by_func (path_tool->current_vector_layer,
G_CALLBACK (gimp_path_tool_vector_layer_modified),
G_CALLBACK (gimp_path_tool_layer_rasterized),
path_tool);
}
@ -980,8 +980,8 @@ gimp_path_tool_set_layer (GimpPathTool *path_tool,
G_CALLBACK (gimp_path_tool_vector_change_notify),
vector_layer, 0);
g_signal_connect_object (vector_layer, "notify::modified",
G_CALLBACK (gimp_path_tool_vector_layer_modified),
g_signal_connect_object (vector_layer, "set-rasterized",
G_CALLBACK (gimp_path_tool_layer_rasterized),
path_tool, 0);
}
}
@ -1078,7 +1078,7 @@ gimp_path_tool_confirm_response (GimpViewableDialog *dialog,
break;
case GTK_RESPONSE_ACCEPT:
gimp_vector_layer_retrieve (layer);
gimp_rasterizable_restore (GIMP_RASTERIZABLE (layer));
gimp_path_tool_set_layer (path_tool, layer);
break;

View file

@ -45,6 +45,7 @@
#include "core/gimpimage-undo-push.h"
#include "core/gimplayer-floating-selection.h"
#include "core/gimplist.h"
#include "core/gimprasterizable.h"
#include "core/gimptoolinfo.h"
#include "core/gimpundostack.h"
@ -1350,7 +1351,7 @@ gimp_text_tool_layer_notify (GimpTextLayer *layer,
if (! strcmp (pspec->name, "modified"))
{
if (layer->modified)
if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer)))
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
}
else if (! strcmp (pspec->name, "text"))
@ -1909,7 +1910,7 @@ gimp_text_tool_set_drawable (GimpTextTool *text_tool,
if (layer == text_tool->layer && layer->text == text_tool->text)
return TRUE;
if (layer->modified)
if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer)))
{
if (confirm)
{
@ -2109,13 +2110,11 @@ gimp_text_tool_apply (GimpTextTool *text_tool,
if (push_undo)
{
if (layer->modified)
if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer)))
{
undo_group = TRUE;
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, NULL);
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
/* see comment in gimp_text_layer_set() */
gimp_image_undo_push_drawable_mod (image, NULL,
GIMP_DRAWABLE (layer), TRUE);
@ -2129,12 +2128,10 @@ gimp_text_tool_apply (GimpTextTool *text_tool,
g_list_free (text_tool->pending);
text_tool->pending = NULL;
if (push_undo)
if (undo_group)
{
g_object_set (layer, "modified", FALSE, NULL);
if (undo_group)
gimp_image_undo_group_end (image);
gimp_rasterizable_restore (GIMP_RASTERIZABLE (layer));
gimp_image_undo_group_end (image);
}
gimp_text_tool_frame_item (text_tool);

View file

@ -68,6 +68,7 @@
#include "core/gimpparasitelist.h"
#include "core/gimppattern.h"
#include "core/gimpprogress.h"
#include "core/gimprasterizable.h"
#include "core/gimpselection.h"
#include "core/gimpstrokeoptions.h"
#include "core/gimpsymmetry.h"
@ -1021,7 +1022,9 @@ xcf_load_image (Gimp *gimp,
"vector-layer-options", options,
NULL);
g_object_unref (options);
GIMP_VECTOR_LAYER (vlayer)->modified = vdata->modified;
if (vdata->modified)
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (vlayer));
if (selected)
{

View file

@ -62,6 +62,7 @@
#include "core/gimplist.h"
#include "core/gimpparasitelist.h"
#include "core/gimpprogress.h"
#include "core/gimprasterizable.h"
#include "core/gimpsamplepoint.h"
#include "core/gimpstrokeoptions.h"
#include "core/gimpsymmetry.h"
@ -1708,7 +1709,7 @@ xcf_save_prop (XcfInfo *info,
xcf_write_int32_check_error (info, &size, 1, va_end (args));
base = info->cp;
uint_val = (guint32) vector_layer->modified;
uint_val = (guint32) gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (vector_layer));
xcf_write_int32_check_error (info, (guint32 *) &uint_val, 1, va_end (args));
uint_val = gimp_item_get_tattoo (GIMP_ITEM (options->path));

View file

@ -107,7 +107,7 @@ HELP
%invoke = (
code => <<'CODE'
{
gimp_link_layer_discard (layer);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
}
CODE
);
@ -133,7 +133,7 @@ HELP
%invoke = (
code => <<'CODE'
{
gimp_link_layer_monitor (layer);
gimp_rasterizable_restore (GIMP_RASTERIZABLE (layer));
}
CODE
);
@ -242,6 +242,7 @@ CODE
}
@headers = qw("core/gimplink.h"
"core/gimplinklayer.h"
"core/gimprasterizable.h"
"gimppdberror.h"
"gimp-intl.h");

View file

@ -117,7 +117,7 @@ HELP
%invoke = (
code => <<'CODE'
{
gimp_vector_layer_discard (layer);
gimp_rasterizable_rasterize (GIMP_RASTERIZABLE (layer));
}
CODE
);
@ -941,6 +941,7 @@ CODE
@headers = qw("libgimpbase/gimpbase.h"
"core/gimpcontext.h"
"core/gimpdashpattern.h"
"core/gimprasterizable.h"
"core/gimpstrokeoptions.h"
"path/gimpvectorlayer.h"
"path/gimpvectorlayeroptions.h"

View file

@ -197,6 +197,7 @@ app/core/gimppattern-save.c
app/core/gimppatternclipboard.c
app/core/gimppdbprogress.c
app/core/gimpprogress.c
app/core/gimprasterizable.c
app/core/gimpselection.c
app/core/gimpsettings.c
app/core/gimpstrokeoptions.c