mirror of https://github.com/GNOME/gimp.git
app: implement gimp_symmetry_get_operation() in terms of gimp_symmetry_get_matrix()
Remove the GimpSymmetry::get_operation() virtual function, and instead implement gimp_symmetry_get_operation() by returning an appropriate gegl:transform node based on the matrix returned by gimp_symmetry_get_matrix(). The returned node is owned by the caller; since we no longer use the node's identity for caching trnasformed brushes, we no longer cache the transformation nodes. Remove the function's paint_width and paint_height parameters, and instead return a transformation that should be applied at the center of the brush. This simplifies the application of the transformation in the Clone and Heal tools, as per the next commit. Remove the implementation of GimpSymmetry::get_operation() from all its subclasses, which should now only implement GimpSymmetry::get_transform().
This commit is contained in:
parent
3895dc07a9
commit
60a3965020
|
@ -81,10 +81,6 @@ static void gimp_mandala_guide_position_cb (GObject *object,
|
|||
static void gimp_mandala_update_strokes (GimpSymmetry *mandala,
|
||||
GimpDrawable *drawable,
|
||||
GimpCoords *origin);
|
||||
static GeglNode * gimp_mandala_get_operation (GimpSymmetry *mandala,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height);
|
||||
static void gimp_mandala_get_transform (GimpSymmetry *mandala,
|
||||
gint stroke,
|
||||
gdouble *angle,
|
||||
|
@ -116,7 +112,6 @@ gimp_mandala_class_init (GimpMandalaClass *klass)
|
|||
|
||||
symmetry_class->label = _("Mandala");
|
||||
symmetry_class->update_strokes = gimp_mandala_update_strokes;
|
||||
symmetry_class->get_operation = gimp_mandala_get_operation;
|
||||
symmetry_class->get_transform = gimp_mandala_get_transform;
|
||||
symmetry_class->active_changed = gimp_mandala_active_changed;
|
||||
|
||||
|
@ -184,20 +179,6 @@ gimp_mandala_finalize (GObject *object)
|
|||
g_clear_object (&mandala->horizontal_guide);
|
||||
g_clear_object (&mandala->vertical_guide);
|
||||
|
||||
if (mandala->ops)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
for (iter = mandala->ops; iter; iter = g_list_next (iter))
|
||||
{
|
||||
if (iter->data)
|
||||
g_object_unref (G_OBJECT (iter->data));
|
||||
}
|
||||
|
||||
g_list_free (mandala->ops);
|
||||
mandala->ops = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -495,68 +476,6 @@ gimp_mandala_update_strokes (GimpSymmetry *sym,
|
|||
g_signal_emit_by_name (sym, "strokes-updated", sym->image);
|
||||
}
|
||||
|
||||
static GeglNode *
|
||||
gimp_mandala_get_operation (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height)
|
||||
{
|
||||
GimpMandala *mandala = GIMP_MANDALA (sym);
|
||||
GeglNode *op = NULL;
|
||||
gint i;
|
||||
|
||||
if (! mandala->disable_transformation &&
|
||||
stroke != 0 &&
|
||||
paint_width != 0 &&
|
||||
paint_height != 0)
|
||||
{
|
||||
if (mandala->size != mandala->cached_size ||
|
||||
mandala->cached_paint_width != paint_width ||
|
||||
mandala->cached_paint_height != paint_height)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
if (mandala->ops)
|
||||
{
|
||||
for (iter = mandala->ops; iter; iter = g_list_next (iter))
|
||||
{
|
||||
if (iter->data)
|
||||
g_object_unref (G_OBJECT (iter->data));
|
||||
}
|
||||
|
||||
g_list_free (mandala->ops);
|
||||
mandala->ops = NULL;
|
||||
}
|
||||
|
||||
mandala->ops = g_list_prepend (mandala->ops, NULL);
|
||||
|
||||
for (i = 1; i < mandala->size; i++)
|
||||
{
|
||||
op = gegl_node_new_child (NULL,
|
||||
"operation", "gegl:rotate",
|
||||
"origin-x",
|
||||
(gdouble) paint_width / 2.0,
|
||||
"origin-y",
|
||||
(gdouble) paint_height / 2.0,
|
||||
"degrees",
|
||||
i * 360.0 / (gdouble) mandala->size,
|
||||
NULL);
|
||||
mandala->ops = g_list_prepend (mandala->ops, op);
|
||||
}
|
||||
|
||||
mandala->ops = g_list_reverse (mandala->ops);
|
||||
|
||||
mandala->cached_size = mandala->size;
|
||||
mandala->cached_paint_width = paint_width;
|
||||
mandala->cached_paint_height = paint_height;
|
||||
}
|
||||
|
||||
op = g_list_nth_data (mandala->ops, stroke);
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_mandala_get_transform (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
|
|
|
@ -46,11 +46,6 @@ struct _GimpMandala
|
|||
|
||||
GimpGuide *horizontal_guide;
|
||||
GimpGuide *vertical_guide;
|
||||
|
||||
GList *ops;
|
||||
gint cached_size;
|
||||
gint cached_paint_width;
|
||||
gint cached_paint_height;
|
||||
};
|
||||
|
||||
struct _GimpMandalaClass
|
||||
|
|
|
@ -71,13 +71,6 @@ static void gimp_mirror_get_property (GObject *obje
|
|||
static void gimp_mirror_update_strokes (GimpSymmetry *mirror,
|
||||
GimpDrawable *drawable,
|
||||
GimpCoords *origin);
|
||||
static void gimp_mirror_prepare_operations (GimpMirror *mirror,
|
||||
gint paint_width,
|
||||
gint paint_height);
|
||||
static GeglNode * gimp_mirror_get_operation (GimpSymmetry *mirror,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height);
|
||||
static void gimp_mirror_get_transform (GimpSymmetry *mirror,
|
||||
gint stroke,
|
||||
gdouble *angle,
|
||||
|
@ -126,7 +119,6 @@ gimp_mirror_class_init (GimpMirrorClass *klass)
|
|||
|
||||
symmetry_class->label = _("Mirror");
|
||||
symmetry_class->update_strokes = gimp_mirror_update_strokes;
|
||||
symmetry_class->get_operation = gimp_mirror_get_operation;
|
||||
symmetry_class->get_transform = gimp_mirror_get_transform;
|
||||
symmetry_class->active_changed = gimp_mirror_active_changed;
|
||||
|
||||
|
@ -210,10 +202,6 @@ gimp_mirror_finalize (GObject *object)
|
|||
g_clear_object (&mirror->horizontal_guide);
|
||||
g_clear_object (&mirror->vertical_guide);
|
||||
|
||||
g_clear_object (&mirror->horizontal_op);
|
||||
g_clear_object (&mirror->vertical_op);
|
||||
g_clear_object (&mirror->central_op);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -369,81 +357,6 @@ gimp_mirror_update_strokes (GimpSymmetry *sym,
|
|||
g_signal_emit_by_name (sym, "strokes-updated", sym->image);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_mirror_prepare_operations (GimpMirror *mirror,
|
||||
gint paint_width,
|
||||
gint paint_height)
|
||||
{
|
||||
if (paint_width == mirror->last_paint_width &&
|
||||
paint_height == mirror->last_paint_height)
|
||||
return;
|
||||
|
||||
mirror->last_paint_width = paint_width;
|
||||
mirror->last_paint_height = paint_height;
|
||||
|
||||
if (mirror->horizontal_op)
|
||||
g_object_unref (mirror->horizontal_op);
|
||||
|
||||
mirror->horizontal_op = gegl_node_new_child (NULL,
|
||||
"operation", "gegl:reflect",
|
||||
"origin-x", 0.0,
|
||||
"origin-y", paint_height / 2.0,
|
||||
"x", 1.0,
|
||||
"y", 0.0,
|
||||
NULL);
|
||||
|
||||
if (mirror->vertical_op)
|
||||
g_object_unref (mirror->vertical_op);
|
||||
|
||||
mirror->vertical_op = gegl_node_new_child (NULL,
|
||||
"operation", "gegl:reflect",
|
||||
"origin-x", paint_width / 2.0,
|
||||
"origin-y", 0.0,
|
||||
"x", 0.0,
|
||||
"y", 1.0,
|
||||
NULL);
|
||||
|
||||
if (mirror->central_op)
|
||||
g_object_unref (mirror->central_op);
|
||||
|
||||
mirror->central_op = gegl_node_new_child (NULL,
|
||||
"operation", "gegl:rotate",
|
||||
"origin-x", paint_width / 2.0,
|
||||
"origin-y", paint_height / 2.0,
|
||||
"degrees", 180.0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GeglNode *
|
||||
gimp_mirror_get_operation (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height)
|
||||
{
|
||||
GimpMirror *mirror = GIMP_MIRROR (sym);
|
||||
GeglNode *op;
|
||||
|
||||
g_return_val_if_fail (stroke >= 0 &&
|
||||
stroke < g_list_length (sym->strokes), NULL);
|
||||
|
||||
gimp_mirror_prepare_operations (mirror, paint_width, paint_height);
|
||||
|
||||
if (mirror->disable_transformation || stroke == 0 ||
|
||||
paint_width == 0 || paint_height == 0)
|
||||
op = NULL;
|
||||
else if (stroke == 1 && mirror->horizontal_mirror)
|
||||
op = g_object_ref (mirror->horizontal_op);
|
||||
else if ((stroke == 2 && mirror->horizontal_mirror &&
|
||||
mirror->vertical_mirror) ||
|
||||
(stroke == 1 && mirror->vertical_mirror &&
|
||||
! mirror->horizontal_mirror))
|
||||
op = g_object_ref (mirror->vertical_op);
|
||||
else
|
||||
op = g_object_ref (mirror->central_op);
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_mirror_get_transform (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
|
|
|
@ -37,24 +37,17 @@ typedef struct _GimpMirrorClass GimpMirrorClass;
|
|||
|
||||
struct _GimpMirror
|
||||
{
|
||||
GimpSymmetry parent_instance;
|
||||
GimpSymmetry parent_instance;
|
||||
|
||||
gboolean horizontal_mirror;
|
||||
gboolean vertical_mirror;
|
||||
gboolean point_symmetry;
|
||||
gboolean disable_transformation;
|
||||
gboolean horizontal_mirror;
|
||||
gboolean vertical_mirror;
|
||||
gboolean point_symmetry;
|
||||
gboolean disable_transformation;
|
||||
|
||||
gdouble mirror_position_y;
|
||||
gdouble mirror_position_x;
|
||||
GimpGuide *horizontal_guide;
|
||||
GimpGuide *vertical_guide;
|
||||
|
||||
/* Cached data */
|
||||
gint last_paint_width;
|
||||
gint last_paint_height;
|
||||
GeglNode *horizontal_op;
|
||||
GeglNode *vertical_op;
|
||||
GeglNode *central_op;
|
||||
gdouble mirror_position_y;
|
||||
gdouble mirror_position_x;
|
||||
GimpGuide *horizontal_guide;
|
||||
GimpGuide *vertical_guide;
|
||||
};
|
||||
|
||||
struct _GimpMirrorClass
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gegl/gimp-gegl-nodes.h"
|
||||
|
||||
#include "gimpdrawable.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-symmetry.h"
|
||||
|
@ -72,10 +74,6 @@ static void gimp_symmetry_get_property (GObject *object,
|
|||
static void gimp_symmetry_real_update_strokes (GimpSymmetry *sym,
|
||||
GimpDrawable *drawable,
|
||||
GimpCoords *origin);
|
||||
static GeglNode * gimp_symmetry_real_get_op (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height);
|
||||
static void gimp_symmetry_real_get_transform (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
gdouble *angle,
|
||||
|
@ -138,7 +136,6 @@ gimp_symmetry_class_init (GimpSymmetryClass *klass)
|
|||
|
||||
klass->label = _("None");
|
||||
klass->update_strokes = gimp_symmetry_real_update_strokes;
|
||||
klass->get_operation = gimp_symmetry_real_get_op;
|
||||
klass->get_transform = gimp_symmetry_real_get_transform;
|
||||
klass->active_changed = NULL;
|
||||
klass->update_version = gimp_symmetry_real_update_version;
|
||||
|
@ -241,17 +238,6 @@ gimp_symmetry_real_update_strokes (GimpSymmetry *sym,
|
|||
g_memdup (origin, sizeof (GimpCoords)));
|
||||
}
|
||||
|
||||
static GeglNode *
|
||||
gimp_symmetry_real_get_op (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height)
|
||||
{
|
||||
/* The basic symmetry just returns NULL, since no transformation of the
|
||||
* brush painting happen. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_symmetry_real_get_transform (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
|
@ -411,30 +397,6 @@ gimp_symmetry_get_coords (GimpSymmetry *sym,
|
|||
return g_list_nth_data (sym->strokes, stroke);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_symmetry_get_operation:
|
||||
* @sym: the #GimpSymmetry
|
||||
* @stroke: the stroke number
|
||||
* @paint_width: the width of the painting area
|
||||
* @paint_height: the height of the painting area
|
||||
*
|
||||
* Returns: the operation to apply to the paint buffer for stroke number @stroke.
|
||||
* NULL means to copy the original stroke as-is.
|
||||
**/
|
||||
GeglNode *
|
||||
gimp_symmetry_get_operation (GimpSymmetry *sym,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_SYMMETRY (sym), NULL);
|
||||
|
||||
return GIMP_SYMMETRY_GET_CLASS (sym)->get_operation (sym,
|
||||
stroke,
|
||||
paint_width,
|
||||
paint_height);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_symmetry_get_transform:
|
||||
* @sym: the #GimpSymmetry
|
||||
|
@ -443,9 +405,9 @@ gimp_symmetry_get_operation (GimpSymmetry *sym,
|
|||
* in degrees (ccw)
|
||||
* @reflect: output pointer to the transformation reflection flag
|
||||
*
|
||||
* Returns the transformation to apply to the paint buffer for stroke
|
||||
* number @stroke. The transformation is comprised of rotation around the
|
||||
* center, possibly followed by horizontal reflection around the center.
|
||||
* Returns: the transformation to apply to the paint content for stroke
|
||||
* number @stroke. The transformation is comprised of rotation, possibly
|
||||
* followed by horizontal reflection, around the stroke coordinates.
|
||||
**/
|
||||
void
|
||||
gimp_symmetry_get_transform (GimpSymmetry *sym,
|
||||
|
@ -472,7 +434,7 @@ gimp_symmetry_get_transform (GimpSymmetry *sym,
|
|||
* @stroke: the stroke number
|
||||
* @matrix: output pointer to the transformation matrix
|
||||
*
|
||||
* Returns the transformation matrix to apply to the paint buffer for stroke
|
||||
* Returns: the transformation matrix to apply to the paint content for stroke
|
||||
* number @stroke.
|
||||
**/
|
||||
void
|
||||
|
@ -494,6 +456,32 @@ gimp_symmetry_get_matrix (GimpSymmetry *sym,
|
|||
gimp_matrix3_scale (matrix, -1.0, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_symmetry_get_operation:
|
||||
* @sym: the #GimpSymmetry
|
||||
* @stroke: the stroke number
|
||||
*
|
||||
* Returns: the transformation operation to apply to the paint content for
|
||||
* stroke number @stroke, or NULL for the identity transformation.
|
||||
*
|
||||
* The returned #GeglNode should be freed by the caller.
|
||||
**/
|
||||
GeglNode *
|
||||
gimp_symmetry_get_operation (GimpSymmetry *sym,
|
||||
gint stroke)
|
||||
{
|
||||
GimpMatrix3 matrix;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_SYMMETRY (sym), NULL);
|
||||
|
||||
gimp_symmetry_get_matrix (sym, stroke, &matrix);
|
||||
|
||||
if (gimp_matrix3_is_identity (&matrix))
|
||||
return NULL;
|
||||
|
||||
return gimp_gegl_create_transform_node (&matrix);
|
||||
}
|
||||
|
||||
/*
|
||||
* gimp_symmetry_parasite_name:
|
||||
* @type: the #GimpSymmetry's #GType
|
||||
|
|
|
@ -63,10 +63,6 @@ struct _GimpSymmetryClass
|
|||
void (* update_strokes) (GimpSymmetry *symmetry,
|
||||
GimpDrawable *drawable,
|
||||
GimpCoords *origin);
|
||||
GeglNode * (* get_operation) (GimpSymmetry *symmetry,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height);
|
||||
void (* get_transform) (GimpSymmetry *symmetry,
|
||||
gint stroke,
|
||||
gdouble *angle,
|
||||
|
@ -90,10 +86,6 @@ GimpCoords * gimp_symmetry_get_origin (GimpSymmetry *symmetry);
|
|||
gint gimp_symmetry_get_size (GimpSymmetry *symmetry);
|
||||
GimpCoords * gimp_symmetry_get_coords (GimpSymmetry *symmetry,
|
||||
gint stroke);
|
||||
GeglNode * gimp_symmetry_get_operation (GimpSymmetry *symmetry,
|
||||
gint stroke,
|
||||
gint paint_width,
|
||||
gint paint_height);
|
||||
void gimp_symmetry_get_transform (GimpSymmetry *symmetry,
|
||||
gint stroke,
|
||||
gdouble *angle,
|
||||
|
@ -101,6 +93,8 @@ void gimp_symmetry_get_transform (GimpSymmetry *symmetry,
|
|||
void gimp_symmetry_get_matrix (GimpSymmetry *symmetry,
|
||||
gint stroke,
|
||||
GimpMatrix3 *matrix);
|
||||
GeglNode * gimp_symmetry_get_operation (GimpSymmetry *symmetry,
|
||||
gint stroke);
|
||||
|
||||
gchar * gimp_symmetry_parasite_name (GType type);
|
||||
GimpParasite * gimp_symmetry_to_parasite (const GimpSymmetry *symmetry);
|
||||
|
|
Loading…
Reference in New Issue