From 0c67310555bb03526eca0f50c201cc6b3dad94d4 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 16 May 2003 16:49:04 +0000 Subject: [PATCH] app/vectors/gimpbezierstroke.[ch] app/vectors/gimpstroke.[ch] 2003-05-16 Michael Natterer * app/vectors/gimpbezierstroke.[ch] * app/vectors/gimpstroke.[ch] * app/vectors/gimpvectors-preview.c * app/vectors/gimpvectors.[ch]: massive cleanup / code review: Made default implementations real ones. Don't add "const" to call-by-value parameters. Iterate lists using for() loops. Moved variables to local scopes. Removed tabs. Indentation. Stuff... * app/vectors/gimpstroke.[ch]: added unused "gboolean closed" member. --- ChangeLog | 13 + app/vectors/gimpbezierstroke.c | 153 ++++---- app/vectors/gimpbezierstroke.h | 19 +- app/vectors/gimpstroke.c | 598 ++++++++++++++---------------- app/vectors/gimpstroke.h | 193 ++++------ app/vectors/gimpvectors-preview.c | 32 +- app/vectors/gimpvectors.c | 343 +++++++++-------- app/vectors/gimpvectors.h | 34 +- 8 files changed, 679 insertions(+), 706 deletions(-) diff --git a/ChangeLog b/ChangeLog index d6df648fa8..0c5e324c14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-05-16 Michael Natterer + + * app/vectors/gimpbezierstroke.[ch] + * app/vectors/gimpstroke.[ch] + * app/vectors/gimpvectors-preview.c + * app/vectors/gimpvectors.[ch]: massive cleanup / code review: + Made default implementations real ones. Don't add "const" to + call-by-value parameters. Iterate lists using for() loops. Moved + variables to local scopes. Removed tabs. Indentation. Stuff... + + * app/vectors/gimpstroke.[ch]: added unused "gboolean closed" + member. + 2003-05-16 Michael Natterer * app/core/gimpimage-mask.[ch] (gimp_image_mask_extract): added diff --git a/app/vectors/gimpbezierstroke.c b/app/vectors/gimpbezierstroke.c index 58262a668b..c5f15f7462 100644 --- a/app/vectors/gimpbezierstroke.c +++ b/app/vectors/gimpbezierstroke.c @@ -19,24 +19,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include "config.h" -#include "glib-object.h" +#include #include "vectors-types.h" #include "gimpanchor.h" #include "gimpbezierstroke.h" + #define INPUT_RESOLUTION 256 -/* private variables */ - -static GimpStrokeClass *parent_class = NULL; - - /* local prototypes */ static void gimp_bezier_stroke_class_init (GimpBezierStrokeClass *klass); @@ -44,15 +39,18 @@ static void gimp_bezier_stroke_init (GimpBezierStroke *bezier_stroke) static void gimp_bezier_stroke_anchor_move_relative (GimpStroke *stroke, GimpAnchor *anchor, const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature); + GimpAnchorFeatureType feature); static void gimp_bezier_stroke_anchor_move_absolute (GimpStroke *stroke, GimpAnchor *anchor, const GimpCoords *coord, - const GimpAnchorFeatureType feature); + GimpAnchorFeatureType feature); static void gimp_bezier_stroke_anchor_convert (GimpStroke *stroke, GimpAnchor *anchor, GimpAnchorFeatureType feature); +static GArray * gimp_bezier_stroke_interpolate (const GimpStroke *stroke, + const gdouble precision, + gboolean *closed); static void gimp_bezier_stroke_finalize (GObject *object); @@ -61,27 +59,21 @@ static void gimp_bezier_coords_mix (const gdouble amul, const gdouble bmul, const GimpCoords *b, GimpCoords *ret_val); - static void gimp_bezier_coords_average (const GimpCoords *a, const GimpCoords *b, GimpCoords *ret_average); - static void gimp_bezier_coords_add (const GimpCoords *a, const GimpCoords *b, GimpCoords *ret_add); - static void gimp_bezier_coords_difference (const GimpCoords *a, const GimpCoords *b, - GimpCoords *ret_difference); - + GimpCoords *difference); static void gimp_bezier_coords_scale (const gdouble f, const GimpCoords *a, GimpCoords *ret_multiply); - static void gimp_bezier_coords_subdivide (const GimpCoords *beziercoords, const gdouble precision, GArray **ret_coords); - static void gimp_bezier_coords_subdivide2 (const GimpCoords *beziercoords, const gdouble precision, GArray **ret_coords, @@ -89,15 +81,17 @@ static void gimp_bezier_coords_subdivide2 (const GimpCoords *beziercoords, static gdouble gimp_bezier_coords_scalarprod (const GimpCoords *a, const GimpCoords *b); - static gdouble gimp_bezier_coords_length (const GimpCoords *a); - static gdouble gimp_bezier_coords_length2 (const GimpCoords *a); - static gboolean gimp_bezier_coords_is_straight (const GimpCoords *beziercoords, const gdouble precision); +/* private variables */ + +static GimpStrokeClass *parent_class = NULL; + + GType gimp_bezier_stroke_get_type (void) { @@ -129,8 +123,8 @@ gimp_bezier_stroke_get_type (void) static void gimp_bezier_stroke_class_init (GimpBezierStrokeClass *klass) { - GObjectClass *object_class; - GimpStrokeClass *stroke_class; + GObjectClass *object_class; + GimpStrokeClass *stroke_class; object_class = G_OBJECT_CLASS (klass); stroke_class = GIMP_STROKE_CLASS (klass); @@ -143,7 +137,6 @@ gimp_bezier_stroke_class_init (GimpBezierStrokeClass *klass) stroke_class->anchor_move_absolute = gimp_bezier_stroke_anchor_move_absolute; stroke_class->anchor_convert = gimp_bezier_stroke_anchor_convert; stroke_class->interpolate = gimp_bezier_stroke_interpolate; - } static void @@ -192,22 +185,21 @@ gimp_bezier_stroke_new (const GimpCoords *start) GimpStroke * gimp_bezier_stroke_new_from_coords (const GimpCoords *coords, - const gint ncoords) + gint n_coords) { GimpBezierStroke *bezier_stroke; GimpStroke *stroke = NULL; GimpAnchor *last_anchor; - gint count; - if (ncoords >= 1) + if (n_coords >= 1) { stroke = gimp_bezier_stroke_new (coords); bezier_stroke = GIMP_BEZIER_STROKE (stroke); last_anchor = (GimpAnchor *) (stroke->anchors->data); count = 1; - while (count < ncoords) + while (count < n_coords) { last_anchor = gimp_bezier_stroke_extend (bezier_stroke, &coords[count++], @@ -225,10 +217,10 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke, GimpAnchor *neighbor, GimpVectorExtendMode extend_mode) { - GimpAnchor *anchor=NULL; - GimpStroke *stroke; - GList *listneighbor; - gint loose_end, control_count; + GimpAnchor *anchor = NULL; + GimpStroke *stroke; + GList *listneighbor; + gint loose_end, control_count; g_return_val_if_fail (GIMP_IS_BEZIER_STROKE (bezier_stroke), NULL); g_return_val_if_fail ((neighbor != NULL), NULL); @@ -237,6 +229,7 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke, loose_end = 0; listneighbor = g_list_last (stroke->anchors); + if (listneighbor->data == neighbor) { loose_end = 1; @@ -284,14 +277,7 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke, { case EXTEND_SIMPLE: anchor = g_new0 (GimpAnchor, 1); - anchor->position.x = coords->x; - anchor->position.y = coords->y; - anchor->position.pressure = 1.0; - anchor->position.xtilt = 0.5; - anchor->position.ytilt = 0.5; - anchor->position.wheel = 0.5; - - anchor->selected = FALSE; + anchor->position = *coords; switch (control_count) { @@ -348,28 +334,28 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke, "%d successive control handles", control_count); } } + return anchor; } - else - return NULL; /* No loose end to add an anchor to... */ + return NULL; /* No loose end to add an anchor to... */ } static void -gimp_bezier_stroke_anchor_move_relative (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature) +gimp_bezier_stroke_anchor_move_relative (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *deltacoord, + GimpAnchorFeatureType feature) { - GimpCoords delta, coord1, coord2; - GList *anchor_list; + GimpCoords delta, coord1, coord2; + GList *anchor_list; delta = *deltacoord; delta.pressure = 0; - delta.xtilt = 0; - delta.ytilt = 0; - delta.wheel = 0; + delta.xtilt = 0; + delta.ytilt = 0; + delta.wheel = 0; gimp_bezier_coords_add (&(anchor->position), &delta, &coord1); anchor->position = coord1; @@ -431,22 +417,22 @@ gimp_bezier_stroke_anchor_move_relative (GimpStroke *stroke, static void -gimp_bezier_stroke_anchor_move_absolute (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *coord, - const GimpAnchorFeatureType feature) +gimp_bezier_stroke_anchor_move_absolute (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *coord, + GimpAnchorFeatureType feature) { GimpCoords deltacoord; - - gimp_bezier_coords_difference (coord, &(anchor->position), &deltacoord); + + gimp_bezier_coords_difference (coord, &anchor->position, &deltacoord); gimp_bezier_stroke_anchor_move_relative (stroke, anchor, &deltacoord, feature); } -void -gimp_bezier_stroke_anchor_convert (GimpStroke *stroke, - GimpAnchor *anchor, - GimpAnchorFeatureType feature) +static void +gimp_bezier_stroke_anchor_convert (GimpStroke *stroke, + GimpAnchor *anchor, + GimpAnchorFeatureType feature) { GList *anchor_list; @@ -455,36 +441,33 @@ gimp_bezier_stroke_anchor_convert (GimpStroke *stroke, g_return_if_fail (anchor_list != NULL); switch (feature) - { + { case GIMP_ANCHOR_FEATURE_EDGE: if (g_list_previous (anchor_list)) ((GimpAnchor *) g_list_previous (anchor_list)->data)->position = - anchor->position; + anchor->position; if (g_list_next (anchor_list)) ((GimpAnchor *) g_list_next (anchor_list)->data)->position = - anchor->position; - + anchor->position; break; default: g_printerr ("gimp_bezier_stroke_anchor_convert: " "unimplemented anchor conversion %d\n", feature); - - } + } } - -GArray * +static GArray * gimp_bezier_stroke_interpolate (const GimpStroke *stroke, gdouble precision, gboolean *ret_closed) { - GArray *ret_coords; - GimpAnchor *anchor; - GList *anchorlist; - GimpCoords segmentcoords[4]; - gint count; + GArray *ret_coords; + GimpAnchor *anchor; + GList *anchorlist; + GimpCoords segmentcoords[4]; + gint count; g_return_val_if_fail (GIMP_IS_BEZIER_STROKE (stroke), NULL); g_return_val_if_fail (ret_closed != NULL, NULL); @@ -514,7 +497,7 @@ gimp_bezier_stroke_interpolate (const GimpStroke *stroke, /* ret_coords = g_array_append_val (ret_coords, anchor->position); */ - *ret_closed = FALSE; + *ret_closed = FALSE; return ret_coords; } @@ -525,11 +508,11 @@ gimp_bezier_stroke_interpolate (const GimpStroke *stroke, /* amul * a + bmul * b */ static void -gimp_bezier_coords_mix (const gdouble amul, +gimp_bezier_coords_mix (const gdouble amul, const GimpCoords *a, - const gdouble bmul, + const gdouble bmul, const GimpCoords *b, - GimpCoords *ret_val) + GimpCoords *ret_val) { if (b) { @@ -557,7 +540,7 @@ gimp_bezier_coords_mix (const gdouble amul, static void gimp_bezier_coords_average (const GimpCoords *a, const GimpCoords *b, - GimpCoords *ret_average) + GimpCoords *ret_average) { gimp_bezier_coords_mix (0.5, a, 0.5, b, ret_average); } @@ -568,7 +551,7 @@ gimp_bezier_coords_average (const GimpCoords *a, static void gimp_bezier_coords_add (const GimpCoords *a, const GimpCoords *b, - GimpCoords *ret_add) + GimpCoords *ret_add) { gimp_bezier_coords_mix (1.0, a, 1.0, b, ret_add); } @@ -579,7 +562,7 @@ gimp_bezier_coords_add (const GimpCoords *a, static void gimp_bezier_coords_difference (const GimpCoords *a, const GimpCoords *b, - GimpCoords *ret_difference) + GimpCoords *ret_difference) { gimp_bezier_coords_mix (1.0, a, -1.0, b, ret_difference); } @@ -590,7 +573,7 @@ gimp_bezier_coords_difference (const GimpCoords *a, static void gimp_bezier_coords_scale (const gdouble f, const GimpCoords *a, - GimpCoords *ret_multiply) + GimpCoords *ret_multiply) { gimp_bezier_coords_mix (f, a, 0.0, NULL, ret_multiply); } @@ -628,14 +611,15 @@ gimp_bezier_coords_length2 (const GimpCoords *a) upscaled_a.xtilt = a->xtilt * INPUT_RESOLUTION; upscaled_a.ytilt = a->ytilt * INPUT_RESOLUTION; upscaled_a.wheel = a->wheel * INPUT_RESOLUTION; - return (gimp_bezier_coords_scalarprod (&upscaled_a, &upscaled_a)); + + return gimp_bezier_coords_scalarprod (&upscaled_a, &upscaled_a); } static gdouble gimp_bezier_coords_length (const GimpCoords *a) { - return (sqrt (gimp_bezier_coords_length2 (a))); + return sqrt (gimp_bezier_coords_length2 (a)); } @@ -648,10 +632,10 @@ gimp_bezier_coords_length (const GimpCoords *a) static gboolean gimp_bezier_coords_is_straight (const GimpCoords *beziercoords, - gdouble precision) + gdouble precision) { GimpCoords line, tan1, tan2, d1, d2; - gdouble l2, s1, s2; + gdouble l2, s1, s2; gimp_bezier_coords_difference (&(beziercoords[3]), &(beziercoords[0]), @@ -792,4 +776,3 @@ gimp_bezier_coords_subdivide (const GimpCoords *beziercoords, { gimp_bezier_coords_subdivide2 (beziercoords, precision, ret_coords, 10); } - diff --git a/app/vectors/gimpbezierstroke.h b/app/vectors/gimpbezierstroke.h index 09b0e7181a..16bb0d0a60 100644 --- a/app/vectors/gimpbezierstroke.h +++ b/app/vectors/gimpbezierstroke.h @@ -22,12 +22,6 @@ #ifndef __GIMP_BEZIER_STROKE_H__ #define __GIMP_BEZIER_STROKE_H__ -#include "config.h" - -#include "glib-object.h" - -#include "vectors-types.h" - #include "gimpstroke.h" @@ -41,7 +35,7 @@ struct _GimpBezierStroke { - GimpStroke parent_instance; + GimpStroke parent_instance; /* Stuff missing? */ }; @@ -49,15 +43,13 @@ struct _GimpBezierStroke struct _GimpBezierStrokeClass { - GimpStrokeClass parent_class; + GimpStrokeClass parent_class; }; -GType gimp_bezier_stroke_get_type (void) G_GNUC_CONST; - - -GimpStroke * gimp_bezier_stroke_new (const GimpCoords *start); +GType gimp_bezier_stroke_get_type (void) G_GNUC_CONST; +GimpStroke * gimp_bezier_stroke_new (const GimpCoords *start); GimpStroke * gimp_bezier_stroke_new_from_coords (const GimpCoords *coords, const gint ncoords); @@ -66,8 +58,5 @@ GimpAnchor * gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke, GimpAnchor *neighbor, GimpVectorExtendMode extend_mode); -GArray * gimp_bezier_stroke_interpolate (const GimpStroke *stroke, - const gdouble precision, - gboolean *ret_closed); #endif /* __GIMP_BEZIER_STROKE_H__ */ diff --git a/app/vectors/gimpstroke.c b/app/vectors/gimpstroke.c index 986aa09df0..d5d31880e9 100644 --- a/app/vectors/gimpstroke.c +++ b/app/vectors/gimpstroke.c @@ -42,19 +42,42 @@ static GimpAnchor * gimp_stroke_real_anchor_get (const GimpStroke *stroke, const GimpCoords *coord); static GimpAnchor * gimp_stroke_real_anchor_get_next (const GimpStroke *stroke, const GimpAnchor *prev); -static void gimp_stroke_real_anchor_move_relative (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature); -static void gimp_stroke_real_anchor_move_absolute (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature); -static GimpStroke * gimp_stroke_real_duplicate (const GimpStroke *stroke); +static void gimp_stroke_real_anchor_select (GimpStroke *stroke, + GimpAnchor *anchor, + gboolean exclusive); +static void gimp_stroke_real_anchor_move_relative (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *delta, + GimpAnchorFeatureType feature); +static void gimp_stroke_real_anchor_move_absolute (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *delta, + GimpAnchorFeatureType feature); +static void gimp_stroke_real_anchor_convert (GimpStroke *stroke, + GimpAnchor *anchor, + GimpAnchorFeatureType feature); +static void gimp_stroke_real_anchor_delete (GimpStroke *stroke, + GimpAnchor *anchor); +static gdouble gimp_stroke_real_get_length (const GimpStroke *stroke); +static gdouble gimp_stroke_real_get_distance (const GimpStroke *stroke, + const GimpCoords *coord); +static GArray * gimp_stroke_real_interpolate (const GimpStroke *stroke, + gdouble precision, + gboolean *closed); +static GimpAnchor * gimp_stroke_real_temp_anchor_get (const GimpStroke *stroke); +static GimpAnchor * gimp_stroke_real_temp_anchor_set (GimpStroke *stroke, + const GimpCoords *coord); +static gboolean gimp_stroke_real_temp_anchor_fix (GimpStroke *stroke); +static GimpStroke * gimp_stroke_real_duplicate (const GimpStroke *stroke); +static GimpStroke * gimp_stroke_real_make_bezier (const GimpStroke *stroke); +static GList * gimp_stroke_real_get_draw_anchors (const GimpStroke *stroke); +static GList * gimp_stroke_real_get_draw_controls (const GimpStroke *stroke); +static GArray * gimp_stroke_real_get_draw_lines (const GimpStroke *stroke); + /* private variables */ -static GObjectClass *parent_class = NULL; +static GimpObjectClass *parent_class = NULL; GType @@ -105,25 +128,26 @@ gimp_stroke_class_init (GimpStrokeClass *klass) klass->anchor_get = gimp_stroke_real_anchor_get; klass->anchor_get_next = gimp_stroke_real_anchor_get_next; + klass->anchor_select = gimp_stroke_real_anchor_select; klass->anchor_move_relative = gimp_stroke_real_anchor_move_relative; klass->anchor_move_absolute = gimp_stroke_real_anchor_move_absolute; - klass->anchor_convert = NULL; - klass->anchor_delete = NULL; + klass->anchor_convert = gimp_stroke_real_anchor_convert; + klass->anchor_delete = gimp_stroke_real_anchor_delete; - klass->get_length = NULL; - klass->get_distance = NULL; - klass->interpolate = NULL; + klass->get_length = gimp_stroke_real_get_length; + klass->get_distance = gimp_stroke_real_get_distance; + klass->interpolate = gimp_stroke_real_interpolate; - klass->temp_anchor_get = NULL; - klass->temp_anchor_set = NULL; - klass->temp_anchor_fix = NULL; + klass->temp_anchor_get = gimp_stroke_real_temp_anchor_get; + klass->temp_anchor_set = gimp_stroke_real_temp_anchor_set; + klass->temp_anchor_fix = gimp_stroke_real_temp_anchor_fix; klass->duplicate = gimp_stroke_real_duplicate; - klass->make_bezier = NULL; + klass->make_bezier = gimp_stroke_real_make_bezier; - klass->get_draw_anchors = NULL; - klass->get_draw_controls = NULL; - klass->get_draw_lines = NULL; + klass->get_draw_anchors = gimp_stroke_real_get_draw_anchors; + klass->get_draw_controls = gimp_stroke_real_get_draw_controls; + klass->get_draw_lines = gimp_stroke_real_get_draw_lines; } static void @@ -131,11 +155,16 @@ gimp_stroke_init (GimpStroke *stroke) { stroke->anchors = NULL; stroke->temp_anchor = NULL; + stroke->closed = FALSE; }; static void gimp_stroke_finalize (GObject *object) { + GimpStroke *stroke; + + stroke = GIMP_STROKE (object); + #ifdef __GNUC__ #warning FIXME: implement gimp_stroke_finalize() #endif @@ -158,59 +187,58 @@ gimp_stroke_get_memsize (GimpObject *object) } -/* Calling the virtual functions */ - GimpAnchor * gimp_stroke_anchor_get (const GimpStroke *stroke, const GimpCoords *coord) { g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - return (GIMP_STROKE_GET_CLASS (stroke))->anchor_get (stroke, coord); + return GIMP_STROKE_GET_CLASS (stroke)->anchor_get (stroke, coord); } - static GimpAnchor * gimp_stroke_real_anchor_get (const GimpStroke *stroke, const GimpCoords *coord) { - gdouble dx, dy, mindist = -1; + gdouble dx, dy; + gdouble mindist = -1; + GList *anchors; GList *list; GimpAnchor *anchor = NULL; g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - list = gimp_stroke_get_draw_controls (stroke); + anchors = gimp_stroke_get_draw_controls (stroke); - while (list) + for (list = anchors; list; list = g_list_next (list)) { dx = coord->x - ((GimpAnchor *) list->data)->position.x; dy = coord->y - ((GimpAnchor *) list->data)->position.y; + if (mindist < 0 || mindist > dx * dx + dy * dy) { mindist = dx * dx + dy * dy; anchor = (GimpAnchor *) list->data; } - list = list->next; } - g_list_free (list); + g_list_free (anchors); - list = gimp_stroke_get_draw_anchors (stroke); + anchors = gimp_stroke_get_draw_anchors (stroke); - while (list) + for (list = anchors; list; list = g_list_next (list)) { dx = coord->x - ((GimpAnchor *) list->data)->position.x; dy = coord->y - ((GimpAnchor *) list->data)->position.y; + if (mindist < 0 || mindist > dx * dx + dy * dy) { mindist = dx * dx + dy * dy; anchor = (GimpAnchor *) list->data; } - list = list->next; } - g_list_free (list); + g_list_free (anchors); return anchor; } @@ -220,136 +248,119 @@ GimpAnchor * gimp_stroke_anchor_get_next (const GimpStroke *stroke, const GimpAnchor *prev) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); - return stroke_class->anchor_get_next (stroke, prev); + return GIMP_STROKE_GET_CLASS (stroke)->anchor_get_next (stroke, prev); } - static GimpAnchor * gimp_stroke_real_anchor_get_next (const GimpStroke *stroke, const GimpAnchor *prev) { - GList *listitem; + GList *list; g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); if (prev) { - listitem = g_list_find (stroke->anchors, prev); - if (listitem) - listitem = g_list_next (listitem); + list = g_list_find (stroke->anchors, prev); + if (list) + list = g_list_next (list); } else - listitem = stroke->anchors; + { + list = stroke->anchors; + } - if (listitem) - return (GimpAnchor *) listitem->data; + if (list) + return (GimpAnchor *) list->data; return NULL; } void -gimp_stroke_anchor_select (GimpStroke *stroke, - GimpAnchor *anchor, - gboolean exclusive) +gimp_stroke_anchor_select (GimpStroke *stroke, + GimpAnchor *anchor, + gboolean exclusive) { - GimpStrokeClass *stroke_class; - g_return_if_fail (GIMP_IS_STROKE (stroke)); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + GIMP_STROKE_GET_CLASS (stroke)->anchor_select (stroke, anchor, exclusive); +} - if (stroke_class->anchor_select) - stroke_class->anchor_select (stroke, anchor, exclusive); - else +static void +gimp_stroke_real_anchor_select (GimpStroke *stroke, + GimpAnchor *anchor, + gboolean exclusive) +{ + GList *list; + + list = stroke->anchors; + + if (exclusive) { - GList *cur_ptr; - - cur_ptr = stroke->anchors; - - if (exclusive) + while (list) { - while (cur_ptr) - { - ((GimpAnchor *) cur_ptr->data)->selected = FALSE; - cur_ptr = g_list_next (cur_ptr); - } + ((GimpAnchor *) list->data)->selected = FALSE; + list = g_list_next (list); } - - if ((cur_ptr = g_list_find (stroke->anchors, anchor)) != NULL) - ((GimpAnchor *) cur_ptr->data)->selected = TRUE; } + + list = g_list_find (stroke->anchors, anchor); + + if (list) + ((GimpAnchor *) list->data)->selected = TRUE; } void -gimp_stroke_anchor_move_relative (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature) +gimp_stroke_anchor_move_relative (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *delta, + GimpAnchorFeatureType feature) { - GimpStrokeClass *stroke_class; - g_return_if_fail (GIMP_IS_STROKE (stroke)); + g_return_if_fail (anchor != NULL); + g_return_if_fail (g_list_find (stroke->anchors, anchor)); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); - - stroke_class->anchor_move_relative (stroke, anchor, deltacoord, feature); + GIMP_STROKE_GET_CLASS (stroke)->anchor_move_relative (stroke, anchor, + delta, feature); } - static void -gimp_stroke_real_anchor_move_relative (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature) +gimp_stroke_real_anchor_move_relative (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *delta, + GimpAnchorFeatureType feature) { - /* - * There should be a test that ensures that the anchor is owned by - * the stroke... - */ - if (anchor) { - anchor->position.x += deltacoord->x; - anchor->position.y += deltacoord->y; - } + anchor->position.x += delta->x; + anchor->position.y += delta->y; } void -gimp_stroke_anchor_move_absolute (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *coord, - const GimpAnchorFeatureType feature) +gimp_stroke_anchor_move_absolute (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *coord, + GimpAnchorFeatureType feature) { - GimpStrokeClass *stroke_class; - g_return_if_fail (GIMP_IS_STROKE (stroke)); + g_return_if_fail (anchor != NULL); + g_return_if_fail (g_list_find (stroke->anchors, anchor)); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); - - stroke_class->anchor_move_absolute (stroke, anchor, coord, feature); + GIMP_STROKE_GET_CLASS (stroke)->anchor_move_absolute (stroke, anchor, + coord, feature); } - static void -gimp_stroke_real_anchor_move_absolute (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *coord, - const GimpAnchorFeatureType feature) +gimp_stroke_real_anchor_move_absolute (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *coord, + GimpAnchorFeatureType feature) { - /* - * There should be a test that ensures that the anchor is owned by - * the stroke... - */ - if (anchor) { - anchor->position.x = coord->x; - anchor->position.y = coord->y; - } + anchor->position.x = coord->x; + anchor->position.y = coord->y; } @@ -358,130 +369,126 @@ gimp_stroke_anchor_convert (GimpStroke *stroke, GimpAnchor *anchor, GimpAnchorFeatureType feature) { - GimpStrokeClass *stroke_class; - g_return_if_fail (GIMP_IS_STROKE (stroke)); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + GIMP_STROKE_GET_CLASS (stroke)->anchor_convert (stroke, anchor, feature); +} - if (stroke_class->anchor_convert) - stroke_class->anchor_convert (stroke, anchor, feature); - else - g_printerr ("gimp_stroke_anchor_convert: default implementation\n"); - - return; +static void +gimp_stroke_real_anchor_convert (GimpStroke *stroke, + GimpAnchor *anchor, + GimpAnchorFeatureType feature) +{ + g_printerr ("gimp_stroke_anchor_convert: default implementation\n"); } void -gimp_stroke_anchor_delete (GimpStroke *stroke, - GimpAnchor *anchor) +gimp_stroke_anchor_delete (GimpStroke *stroke, + GimpAnchor *anchor) { - GimpStrokeClass *stroke_class; - g_return_if_fail (GIMP_IS_STROKE (stroke)); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + GIMP_STROKE_GET_CLASS (stroke)->anchor_delete (stroke, anchor); +} - if (stroke_class->anchor_delete) - stroke_class->anchor_delete (stroke, anchor); - else - g_printerr ("gimp_stroke_anchor_delete: default implementation\n"); - - return; +static void +gimp_stroke_real_anchor_delete (GimpStroke *stroke, + GimpAnchor *anchor) +{ + g_printerr ("gimp_stroke_anchor_delete: default implementation\n"); } gdouble gimp_stroke_get_length (const GimpStroke *stroke) { - GimpStrokeClass *stroke_class; + g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0.0); - g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0); + return GIMP_STROKE_GET_CLASS (stroke)->get_length (stroke); +} - stroke_class = GIMP_STROKE_GET_CLASS (stroke); +static gdouble +gimp_stroke_real_get_length (const GimpStroke *stroke) +{ + g_printerr ("gimp_stroke_get_length: default implementation\n"); - if (stroke_class->get_length) - return stroke_class->get_length (stroke); - else - g_printerr ("gimp_stroke_get_length: default implementation\n"); - - return 0; + return 0.0; } gdouble gimp_stroke_get_distance (const GimpStroke *stroke, - const GimpCoords *coord) + const GimpCoords *coord) { - GimpStrokeClass *stroke_class; + g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0.0); - g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0); + return GIMP_STROKE_GET_CLASS (stroke)->get_distance (stroke, coord); +} - stroke_class = GIMP_STROKE_GET_CLASS (stroke); +static gdouble +gimp_stroke_real_get_distance (const GimpStroke *stroke, + const GimpCoords *coord) +{ + g_printerr ("gimp_stroke_get_distance: default implementation\n"); - if (stroke_class->get_distance) - return stroke_class->get_distance (stroke, coord); - else - g_printerr ("gimp_stroke_get_distance: default implementation\n"); - - return 0; + return 0.0; } GArray * -gimp_stroke_interpolate (const GimpStroke *stroke, - const gdouble precision, - gboolean *ret_closed) +gimp_stroke_interpolate (const GimpStroke *stroke, + gdouble precision, + gboolean *ret_closed) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); - - if (stroke_class->interpolate) - return stroke_class->interpolate (stroke, precision, - ret_closed); - else - g_printerr ("gimp_stroke_interpolate: default implementation\n"); - - return 0; + return GIMP_STROKE_GET_CLASS (stroke)->interpolate (stroke, precision, + ret_closed); } - -GimpAnchor * -gimp_stroke_temp_anchor_get (const GimpStroke *stroke) +static GArray * +gimp_stroke_real_interpolate (const GimpStroke *stroke, + gdouble precision, + gboolean *ret_closed) { - GimpStrokeClass *stroke_class; - - g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - - stroke_class = GIMP_STROKE_GET_CLASS (stroke); - - if (stroke_class->temp_anchor_get) - return stroke_class->temp_anchor_get (stroke); - else - g_printerr ("gimp_stroke_temp_anchor_get: default implementation\n"); + g_printerr ("gimp_stroke_interpolate: default implementation\n"); return NULL; } GimpAnchor * -gimp_stroke_temp_anchor_set (GimpStroke *stroke, - const GimpCoords *coord) +gimp_stroke_temp_anchor_get (const GimpStroke *stroke) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + return GIMP_STROKE_GET_CLASS (stroke)->temp_anchor_get (stroke); +} - if (stroke_class->temp_anchor_set) - return stroke_class->temp_anchor_set (stroke, coord); - else - g_printerr ("gimp_stroke_temp_anchor_set: default implementation\n"); +static GimpAnchor * +gimp_stroke_real_temp_anchor_get (const GimpStroke *stroke) +{ + g_printerr ("gimp_stroke_temp_anchor_get: default implementation\n"); + + return NULL; +} + + +GimpAnchor * +gimp_stroke_temp_anchor_set (GimpStroke *stroke, + const GimpCoords *coord) +{ + g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); + + return GIMP_STROKE_GET_CLASS (stroke)->temp_anchor_set (stroke, coord); +} + +static GimpAnchor * +gimp_stroke_real_temp_anchor_set (GimpStroke *stroke, + const GimpCoords *coord) +{ + g_printerr ("gimp_stroke_temp_anchor_set: default implementation\n"); return NULL; } @@ -490,16 +497,15 @@ gimp_stroke_temp_anchor_set (GimpStroke *stroke, gboolean gimp_stroke_temp_anchor_fix (GimpStroke *stroke) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), FALSE); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + return GIMP_STROKE_GET_CLASS (stroke)->temp_anchor_fix (stroke); +} - if (stroke_class->temp_anchor_fix) - return stroke_class->temp_anchor_fix (stroke); - else - g_printerr ("gimp_stroke_temp_anchor_fix: default implementation\n"); +static gboolean +gimp_stroke_real_temp_anchor_fix (GimpStroke *stroke) +{ + g_printerr ("gimp_stroke_temp_anchor_fix: default implementation\n"); return FALSE; } @@ -513,43 +519,33 @@ gimp_stroke_duplicate (const GimpStroke *stroke) return (GIMP_STROKE_GET_CLASS (stroke))->duplicate (stroke); } - GimpStroke * gimp_stroke_real_duplicate (const GimpStroke *stroke) { GimpStroke *new_stroke; - GimpObject *new_gimpobject; - GList *anchorlist; - GimpAnchor *new_anchor; - GType stroke_type = G_OBJECT_TYPE (stroke); + GList *list; - new_stroke = g_object_new (stroke_type, NULL); - new_gimpobject = GIMP_OBJECT (new_stroke); + new_stroke = g_object_new (G_TYPE_FROM_INSTANCE (stroke), + "name", GIMP_OBJECT (stroke)->name, + NULL); - gimp_object_set_name (new_gimpobject, GIMP_OBJECT (stroke)->name); + new_stroke->anchors = g_list_copy (stroke->anchors); - anchorlist = g_list_copy (stroke->anchors); - - new_stroke->anchors = anchorlist; - - while (anchorlist) + for (list = new_stroke->anchors; list; list = g_list_next (list)) { - new_anchor = g_new0 (GimpAnchor, 1); - *new_anchor = *((GimpAnchor *) (anchorlist->data)); + GimpAnchor *new_anchor = g_new0 (GimpAnchor, 1); - anchorlist->data = (gpointer) new_anchor; - anchorlist = g_list_next (anchorlist); + *new_anchor = *((GimpAnchor *) (list->data)); + + list->data = new_anchor; } if (stroke->temp_anchor) { - new_stroke->temp_anchor = g_new0 (GimpAnchor, 1); + new_stroke->temp_anchor = g_new0 (GimpAnchor, 1); + *(new_stroke->temp_anchor) = *(stroke->temp_anchor); } - else - { - new_stroke->temp_anchor = NULL; - } return new_stroke; } @@ -558,137 +554,119 @@ gimp_stroke_real_duplicate (const GimpStroke *stroke) GimpStroke * gimp_stroke_make_bezier (const GimpStroke *stroke) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + return GIMP_STROKE_GET_CLASS (stroke)->make_bezier (stroke); +} - if (stroke_class->make_bezier) - return stroke_class->make_bezier (stroke); - else - g_printerr ("gimp_stroke_make_bezier: default implementation\n"); +static GimpStroke * +gimp_stroke_real_make_bezier (const GimpStroke *stroke) +{ + g_printerr ("gimp_stroke_make_bezier: default implementation\n"); return NULL; } - GList * gimp_stroke_get_draw_anchors (const GimpStroke *stroke) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + return GIMP_STROKE_GET_CLASS (stroke)->get_draw_anchors (stroke); +} - if (stroke_class->get_draw_anchors) - return stroke_class->get_draw_anchors (stroke); - else +static GList * +gimp_stroke_real_get_draw_anchors (const GimpStroke *stroke) +{ + GList *list; + GList *ret_list = NULL; + + for (list = stroke->anchors; list; list = g_list_next (list)) { - GList *cur_ptr, *ret_list = NULL; - - cur_ptr = stroke->anchors; - - while (cur_ptr) - { - if (((GimpAnchor *) cur_ptr->data)->type == GIMP_ANCHOR_ANCHOR) - ret_list = g_list_append (ret_list, cur_ptr->data); - cur_ptr = g_list_next (cur_ptr); - } - - return ret_list; + if (((GimpAnchor *) list->data)->type == GIMP_ANCHOR_ANCHOR) + ret_list = g_list_prepend (ret_list, list->data); } + return g_list_reverse (ret_list); } GList * gimp_stroke_get_draw_controls (const GimpStroke *stroke) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); + return GIMP_STROKE_GET_CLASS (stroke)->get_draw_controls (stroke); +} - if (stroke_class->get_draw_controls) - return stroke_class->get_draw_controls (stroke); - else +static GList * +gimp_stroke_real_get_draw_controls (const GimpStroke *stroke) +{ + GList *list; + GList *ret_list = NULL; + + for (list = stroke->anchors; list; list = g_list_next (list)) { - GList *cur_ptr, *ret_list = NULL; + GimpAnchor *anchor = list->data; - cur_ptr = stroke->anchors; - - while (cur_ptr) + if (anchor->type == GIMP_ANCHOR_CONTROL) { - if (((GimpAnchor *) cur_ptr->data)->type == GIMP_ANCHOR_CONTROL) - { - if (cur_ptr->next && - ((GimpAnchor *) cur_ptr->next->data)->type == GIMP_ANCHOR_ANCHOR && - ((GimpAnchor *) cur_ptr->next->data)->selected) - ret_list = g_list_append (ret_list, cur_ptr->data); - else if (cur_ptr->prev && - ((GimpAnchor *) cur_ptr->prev->data)->type == GIMP_ANCHOR_ANCHOR && - ((GimpAnchor *) cur_ptr->prev->data)->selected) - ret_list = g_list_append (ret_list, cur_ptr->data); - } - cur_ptr = g_list_next (cur_ptr); - } + GimpAnchor *next = list->next ? list->next->data : NULL; + GimpAnchor *prev = list->prev ? list->prev->data : NULL; - return ret_list; + if (next && next->type == GIMP_ANCHOR_ANCHOR && next->selected) + { + ret_list = g_list_prepend (ret_list, anchor); + } + else if (prev && prev->type == GIMP_ANCHOR_ANCHOR && prev->selected) + { + ret_list = g_list_prepend (ret_list, anchor); + } + } } - return NULL; + return g_list_reverse (ret_list); } + GArray * gimp_stroke_get_draw_lines (const GimpStroke *stroke) { - GimpStrokeClass *stroke_class; - g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL); - stroke_class = GIMP_STROKE_GET_CLASS (stroke); - - if (stroke_class->get_draw_lines) - return stroke_class->get_draw_lines (stroke); - else - { - GList *cur_ptr; - GArray *ret_lines = g_array_new (FALSE, FALSE, sizeof (GimpCoords)); - - cur_ptr = stroke->anchors; - - while (cur_ptr) - { - if (((GimpAnchor *) cur_ptr->data)->type == GIMP_ANCHOR_ANCHOR && - ((GimpAnchor *) cur_ptr->data)->selected) - { - if (cur_ptr->next) - { - ret_lines = g_array_append_val (ret_lines, - ((GimpAnchor *) cur_ptr->data)->position); - - ret_lines = g_array_append_val (ret_lines, - ((GimpAnchor *) cur_ptr->next->data)->position); - - } - if (cur_ptr->prev) - { - ret_lines = g_array_append_val (ret_lines, - ((GimpAnchor *) cur_ptr->data)->position); - - ret_lines = g_array_append_val (ret_lines, - ((GimpAnchor *) cur_ptr->prev->data)->position); - - } - } - cur_ptr = g_list_next (cur_ptr); - } - - return ret_lines; - } + return GIMP_STROKE_GET_CLASS (stroke)->get_draw_lines (stroke); } +static GArray * +gimp_stroke_real_get_draw_lines (const GimpStroke *stroke) +{ + GList *list; + GArray *ret_lines = g_array_new (FALSE, FALSE, sizeof (GimpCoords)); + + for (list = stroke->anchors; list; list = g_list_next (list)) + { + GimpAnchor *anchor = list->data; + + if (anchor->type == GIMP_ANCHOR_ANCHOR && anchor->selected) + { + if (list->next) + { + GimpAnchor *next = list->next->data; + + ret_lines = g_array_append_val (ret_lines, anchor->position); + ret_lines = g_array_append_val (ret_lines, next->position); + } + + if (list->prev) + { + GimpAnchor *prev = list->prev->data; + + ret_lines = g_array_append_val (ret_lines, anchor->position); + ret_lines = g_array_append_val (ret_lines, prev->position); + } + } + } + + return ret_lines; +} diff --git a/app/vectors/gimpstroke.h b/app/vectors/gimpstroke.h index 1648a3e7a1..e66c964051 100644 --- a/app/vectors/gimpstroke.h +++ b/app/vectors/gimpstroke.h @@ -36,13 +36,12 @@ struct _GimpStroke { - GimpObject parent_instance; + GimpObject parent_instance; - GList * anchors; + GList *anchors; - GimpAnchor * temp_anchor; - - /* Stuff missing? */ + GimpAnchor *temp_anchor; + gboolean closed; }; @@ -50,144 +49,116 @@ struct _GimpStrokeClass { GimpObjectClass parent_class; - void (* changed) (GimpStroke *stroke); - - void (* removed) (GimpStroke *stroke); - - GimpAnchor * (* anchor_get) (const GimpStroke *stroke, - const GimpCoords *coord); - - GimpAnchor * (* anchor_get_next) (const GimpStroke *stroke, - const GimpAnchor *prev); - - void (* anchor_select) (GimpStroke *stroke, - GimpAnchor *anchor, - gboolean exclusive); + void (* changed) (GimpStroke *stroke); + void (* removed) (GimpStroke *stroke); - void (* anchor_move_relative) (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature); - - void (* anchor_move_absolute) (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *coord, - const GimpAnchorFeatureType feature); - - void (* anchor_convert) (GimpStroke *stroke, - GimpAnchor *anchor, - GimpAnchorFeatureType feature); - - void (* anchor_delete) (GimpStroke *stroke, - GimpAnchor *anchor); - - - gdouble (* get_length) (const GimpStroke *stroke); - - gdouble (* get_distance) (const GimpStroke *stroke, - const GimpCoords *coord); - - GArray * (* interpolate) (const GimpStroke *stroke, - const gdouble precision, - gboolean *ret_closed); - + GimpAnchor * (* anchor_get) (const GimpStroke *stroke, + const GimpCoords *coord); + GimpAnchor * (* anchor_get_next) (const GimpStroke *stroke, + const GimpAnchor *prev); + void (* anchor_select) (GimpStroke *stroke, + GimpAnchor *anchor, + gboolean exclusive); + void (* anchor_move_relative) (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *deltacoord, + GimpAnchorFeatureType feature); + void (* anchor_move_absolute) (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *coord, + GimpAnchorFeatureType feature); + void (* anchor_convert) (GimpStroke *stroke, + GimpAnchor *anchor, + GimpAnchorFeatureType feature); + void (* anchor_delete) (GimpStroke *stroke, + GimpAnchor *anchor); - GimpAnchor * (* temp_anchor_get) (const GimpStroke *stroke); - - GimpAnchor * (* temp_anchor_set) (GimpStroke *stroke, - const GimpCoords *coord); - - gboolean (* temp_anchor_fix) (GimpStroke *stroke); + gdouble (* get_length) (const GimpStroke *stroke); + gdouble (* get_distance) (const GimpStroke *stroke, + const GimpCoords *coord); - GimpStroke * (* duplicate) (const GimpStroke *stroke); - - GimpStroke * (* make_bezier) (const GimpStroke *stroke); + GArray * (* interpolate) (const GimpStroke *stroke, + const gdouble precision, + gboolean *ret_closed); - GList * (* get_draw_anchors) (const GimpStroke *stroke); - - GList * (* get_draw_controls) (const GimpStroke *stroke); - - GArray * (* get_draw_lines) (const GimpStroke *stroke); + GimpAnchor * (* temp_anchor_get) (const GimpStroke *stroke); + GimpAnchor * (* temp_anchor_set) (GimpStroke *stroke, + const GimpCoords *coord); + gboolean (* temp_anchor_fix) (GimpStroke *stroke); + + GimpStroke * (* duplicate) (const GimpStroke *stroke); + GimpStroke * (* make_bezier) (const GimpStroke *stroke); + + GList * (* get_draw_anchors) (const GimpStroke *stroke); + GList * (* get_draw_controls) (const GimpStroke *stroke); + GArray * (* get_draw_lines) (const GimpStroke *stroke); }; -/* stroke utility functions */ - -GType gimp_stroke_get_type (void) G_GNUC_CONST; +GType gimp_stroke_get_type (void) G_GNUC_CONST; /* accessing / modifying the anchors */ -GimpAnchor * gimp_stroke_anchor_get (const GimpStroke *stroke, - const GimpCoords *coord); - +GimpAnchor * gimp_stroke_anchor_get (const GimpStroke *stroke, + const GimpCoords *coord); + /* prev == NULL: "first" anchor */ -GimpAnchor * gimp_stroke_anchor_get_next (const GimpStroke *stroke, - const GimpAnchor *prev); - - -void gimp_stroke_anchor_select (GimpStroke *stroke, - GimpAnchor *anchor, - gboolean exclusive); +GimpAnchor * gimp_stroke_anchor_get_next (const GimpStroke *stroke, + const GimpAnchor *prev); + +void gimp_stroke_anchor_select (GimpStroke *stroke, + GimpAnchor *anchor, + gboolean exclusive); /* type will be an xorable enum: * VECTORS_NONE, VECTORS_FIX_ANGLE, VECTORS_FIX_RATIO, VECTORS_RESTRICT_ANGLE * or so. */ -void gimp_stroke_anchor_move_relative (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const GimpAnchorFeatureType feature); +void gimp_stroke_anchor_move_relative (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *delta, + GimpAnchorFeatureType feature); +void gimp_stroke_anchor_move_absolute (GimpStroke *stroke, + GimpAnchor *anchor, + const GimpCoords *coord, + GimpAnchorFeatureType feature); -void gimp_stroke_anchor_move_absolute (GimpStroke *stroke, - GimpAnchor *anchor, - const GimpCoords *coord, - const GimpAnchorFeatureType feature); +void gimp_stroke_anchor_convert (GimpStroke *stroke, + GimpAnchor *anchor, + GimpAnchorFeatureType feature); -void gimp_stroke_anchor_convert (GimpStroke *stroke, - GimpAnchor *anchor, - GimpAnchorFeatureType feature); - -void gimp_stroke_anchor_delete (GimpStroke *stroke, - GimpAnchor *anchor); +void gimp_stroke_anchor_delete (GimpStroke *stroke, + GimpAnchor *anchor); /* accessing the shape of the curve */ -gdouble gimp_stroke_get_length (const GimpStroke *stroke); - -gdouble gimp_stroke_get_distance (const GimpStroke *stroke, - const GimpCoords *coord); - +gdouble gimp_stroke_get_length (const GimpStroke *stroke); +gdouble gimp_stroke_get_distance (const GimpStroke *stroke, + const GimpCoords *coord); + /* returns the number of valid coordinates */ -GArray * gimp_stroke_interpolate (const GimpStroke *stroke, - gdouble precision, - gboolean *ret_closed); +GArray * gimp_stroke_interpolate (const GimpStroke *stroke, + gdouble precision, + gboolean *closed); /* Allow a singular temorary anchor (marking the "working point")? */ -GimpAnchor * gimp_stroke_temp_anchor_get (const GimpStroke *stroke); - -GimpAnchor * gimp_stroke_temp_anchor_set (GimpStroke *stroke, - const GimpCoords *coord); - -gboolean gimp_stroke_temp_anchor_fix (GimpStroke *stroke); +GimpAnchor * gimp_stroke_temp_anchor_get (const GimpStroke *stroke); +GimpAnchor * gimp_stroke_temp_anchor_set (GimpStroke *stroke, + const GimpCoords *coord); +gboolean gimp_stroke_temp_anchor_fix (GimpStroke *stroke); - -GimpStroke * gimp_stroke_duplicate (const GimpStroke *stroke); - -/* usually overloaded */ +GimpStroke * gimp_stroke_duplicate (const GimpStroke *stroke); /* creates a bezier approximation. */ +GimpStroke * gimp_stroke_make_bezier (const GimpStroke *stroke); -GimpStroke * gimp_stroke_make_bezier (const GimpStroke *stroke); +GList * gimp_stroke_get_draw_anchors (const GimpStroke *stroke); +GList * gimp_stroke_get_draw_controls (const GimpStroke *stroke); +GArray * gimp_stroke_get_draw_lines (const GimpStroke *stroke); -GList * gimp_stroke_get_draw_anchors (const GimpStroke *stroke); - -GList * gimp_stroke_get_draw_controls (const GimpStroke *stroke); - -GArray * gimp_stroke_get_draw_lines (const GimpStroke *stroke); - #endif /* __GIMP_STROKE_H__ */ diff --git a/app/vectors/gimpvectors-preview.c b/app/vectors/gimpvectors-preview.c index 18fd75ab6b..66025624ed 100644 --- a/app/vectors/gimpvectors-preview.c +++ b/app/vectors/gimpvectors-preview.c @@ -27,6 +27,7 @@ #include "base/temp-buf.h" #include "core/gimpimage.h" + #include "gimpstroke.h" #include "gimpvectors.h" #include "gimpvectors-preview.h" @@ -41,37 +42,40 @@ gimp_vectors_get_new_preview (GimpViewable *viewable, { GimpVectors *vectors; GimpItem *item; - GArray *coords; - GimpCoords point; - GimpStroke *cur_stroke = NULL; + GimpStroke *cur_stroke; gdouble xscale, yscale; - gint x, y; guchar *data; - gboolean closed; - TempBuf *temp_buf; guchar white[1] = { 255 }; - gint i; vectors = GIMP_VECTORS (viewable); - item = GIMP_ITEM (viewable); + item = GIMP_ITEM (viewable); - xscale = ((gdouble) width) / gimp_image_get_width (item->gimage); + xscale = ((gdouble) width) / gimp_image_get_width (item->gimage); yscale = ((gdouble) height) / gimp_image_get_height (item->gimage); temp_buf = temp_buf_new (width, height, 1, 0, 0, white); data = temp_buf_data (temp_buf); - while ((cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke))) + for (cur_stroke = gimp_vectors_stroke_get_next (vectors, NULL); + cur_stroke; + cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke)) { - coords = gimp_stroke_interpolate (cur_stroke, 1.0, &closed); + GArray *coords; + gboolean closed; + gint i; - for (i=0; i < coords->len; i++) + coords = gimp_stroke_interpolate (cur_stroke, 0.5, &closed); + + for (i = 0; i < coords->len; i++) { + GimpCoords point; + gint x, y; + point = g_array_index (coords, GimpCoords, i); - x = (gint) (point.x * xscale + 0.5); - y = (gint) (point.y * yscale + 0.5); + x = ROUND (point.x * xscale); + y = ROUND (point.y * yscale); if (x >= 0 && y >= 0 && x < width && y < height) data[y * width + x] = 0; diff --git a/app/vectors/gimpvectors.c b/app/vectors/gimpvectors.c index 4bd78b372b..7d76c23bd5 100644 --- a/app/vectors/gimpvectors.c +++ b/app/vectors/gimpvectors.c @@ -21,7 +21,7 @@ #include "config.h" -#include "glib-object.h" +#include #include "vectors-types.h" @@ -82,7 +82,30 @@ static void gimp_vectors_transform (GimpItem *item, GimpProgressFunc progress_callback, gpointer progress_data); -static void gimp_vectors_real_thaw (GimpVectors *vectors); +static void gimp_vectors_real_thaw (GimpVectors *vectors); +static void gimp_vectors_real_stroke_add (GimpVectors *vectors, + GimpStroke *stroke); +static GimpStroke * gimp_vectors_real_stroke_get (const GimpVectors *vectors, + const GimpCoords *coord); +static GimpStroke *gimp_vectors_real_stroke_get_next(const GimpVectors *vectors, + const GimpStroke *prev); +static gdouble gimp_vectors_real_stroke_get_length (const GimpVectors *vectors, + const GimpStroke *prev); +static GimpAnchor * gimp_vectors_real_anchor_get (const GimpVectors *vectors, + const GimpCoords *coord, + GimpStroke **ret_stroke); +static void gimp_vectors_real_anchor_delete (GimpVectors *vectors, + GimpAnchor *anchor); +static gdouble gimp_vectors_real_get_length (const GimpVectors *vectors, + const GimpAnchor *start); +static gdouble gimp_vectors_real_get_distance (const GimpVectors *vectors, + const GimpCoords *coord); +static gint gimp_vectors_real_interpolate (const GimpVectors *vectors, + const GimpStroke *stroke, + gdouble precision, + gint max_points, + GimpCoords *ret_coords); +static GimpVectors * gimp_vectors_real_make_bezier (const GimpVectors *vectors); /* private variables */ @@ -171,18 +194,19 @@ gimp_vectors_class_init (GimpVectorsClass *klass) klass->freeze = NULL; klass->thaw = gimp_vectors_real_thaw; - klass->stroke_add = NULL; - klass->stroke_get = NULL; - klass->stroke_get_next = NULL; - klass->stroke_get_length = NULL; + klass->stroke_add = gimp_vectors_real_stroke_add; + klass->stroke_get = gimp_vectors_real_stroke_get; + klass->stroke_get_next = gimp_vectors_real_stroke_get_next; + klass->stroke_get_length = gimp_vectors_real_stroke_get_length; - klass->anchor_get = NULL; + klass->anchor_get = gimp_vectors_real_anchor_get; + klass->anchor_delete = gimp_vectors_real_anchor_delete; - klass->get_length = NULL; - klass->get_distance = NULL; - klass->interpolate = NULL; + klass->get_length = gimp_vectors_real_get_length; + klass->get_distance = gimp_vectors_real_get_distance; + klass->interpolate = gimp_vectors_real_interpolate; - klass->make_bezier = NULL; + klass->make_bezier = gimp_vectors_real_make_bezier; } static void @@ -528,118 +552,66 @@ gimp_vectors_copy_strokes (const GimpVectors *src_vectors, /* Calling the virtual functions */ -GimpAnchor * -gimp_vectors_anchor_get (const GimpVectors *vectors, - const GimpCoords *coord, - GimpStroke **ret_stroke) -{ - GimpVectorsClass *vectors_class; - - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); - - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); - - if (vectors_class->anchor_get) - return vectors_class->anchor_get (vectors, coord, ret_stroke); - else - { - gdouble dx, dy, mindist; - GList *stroke; - GimpAnchor *anchor = NULL, *minanchor = NULL; - - mindist = -1; - - for (stroke = vectors->strokes; stroke; stroke = g_list_next (stroke)) - { - anchor = gimp_stroke_anchor_get (GIMP_STROKE (stroke->data), coord); - if (anchor) - { - dx = coord->x - anchor->position.x; - dy = coord->y - anchor->position.y; - if (mindist > dx * dx + dy * dy || mindist < 0) - { - mindist = dx * dx + dy * dy; - minanchor = anchor; - if (ret_stroke) - *ret_stroke = stroke->data; - } - } - } - return minanchor; - } - - return NULL; -} - - void gimp_vectors_stroke_add (GimpVectors *vectors, GimpStroke *stroke) { - GimpVectorsClass *vectors_class; - g_return_if_fail (GIMP_IS_VECTORS (vectors)); g_return_if_fail (GIMP_IS_STROKE (stroke)); - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); - gimp_vectors_freeze (vectors); - if (vectors_class->stroke_add) - { - vectors_class->stroke_add (vectors, stroke); - } - else - { - vectors->strokes = g_list_prepend (vectors->strokes, stroke); - g_object_ref (stroke); - } + GIMP_VECTORS_GET_CLASS (vectors)->stroke_add (vectors, stroke); gimp_vectors_thaw (vectors); } +static void +gimp_vectors_real_stroke_add (GimpVectors *vectors, + GimpStroke *stroke) +{ + vectors->strokes = g_list_prepend (vectors->strokes, stroke); + g_object_ref (stroke); +} + GimpStroke * gimp_vectors_stroke_get (const GimpVectors *vectors, const GimpCoords *coord) { - GimpVectorsClass *vectors_class; - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); + return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get (vectors, coord); +} - if (vectors_class->stroke_get) - return vectors_class->stroke_get (vectors, coord); - else +static GimpStroke * +gimp_vectors_real_stroke_get (const GimpVectors *vectors, + const GimpCoords *coord) +{ + GList *stroke; + gdouble mindist = G_MAXDOUBLE; + GimpStroke *minstroke = NULL; + + for (stroke = vectors->strokes; stroke; stroke = g_list_next (stroke)) { - gdouble dx, dy, mindist; - GList *stroke; - GimpStroke *minstroke = NULL; - GimpAnchor *anchor = NULL; + GimpAnchor *anchor = gimp_stroke_anchor_get (stroke->data, coord); - mindist = -1; - stroke = vectors->strokes; - - while (stroke) + if (anchor) { - anchor = gimp_stroke_anchor_get (stroke->data, coord); - if (anchor) + gdouble dx, dy; + + dx = coord->x - anchor->position.x; + dy = coord->y - anchor->position.y; + + if (mindist > dx * dx + dy * dy) { - dx = coord->x - anchor->position.x; - dy = coord->y - anchor->position.y; - if (mindist > dx * dx + dy * dy || mindist < 0) - { - mindist = dx * dx + dy * dy; - minstroke = GIMP_STROKE (stroke->data); - } + mindist = dx * dx + dy * dy; + minstroke = GIMP_STROKE (stroke->data); } - stroke = g_list_next (stroke); } - return minstroke; } - return NULL; + return minstroke; } @@ -647,30 +619,29 @@ GimpStroke * gimp_vectors_stroke_get_next (const GimpVectors *vectors, const GimpStroke *prev) { - GimpVectorsClass *vectors_class; - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); + return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_next (vectors, prev); +} - if (vectors_class->stroke_get_next) - return vectors_class->stroke_get_next (vectors, prev); +static GimpStroke * +gimp_vectors_real_stroke_get_next (const GimpVectors *vectors, + const GimpStroke *prev) +{ + if (! prev) + { + return vectors->strokes ? vectors->strokes->data : NULL; + } else { - if (!prev) - { - return vectors->strokes ? vectors->strokes->data : NULL; - } - else - { - GList *stroke; - stroke = g_list_find (vectors->strokes, prev); - g_return_val_if_fail (stroke != NULL, NULL); - return stroke->next ? GIMP_STROKE (stroke->next->data) : NULL; - } - } + GList *stroke; - return NULL; + stroke = g_list_find (vectors->strokes, prev); + + g_return_val_if_fail (stroke != NULL, NULL); + + return stroke->next ? GIMP_STROKE (stroke->next->data) : NULL; + } } @@ -678,18 +649,82 @@ gdouble gimp_vectors_stroke_get_length (const GimpVectors *vectors, const GimpStroke *prev) { - GimpVectorsClass *vectors_class; + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0); + return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_length (vectors, prev); +} - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); +static gdouble +gimp_vectors_real_stroke_get_length (const GimpVectors *vectors, + const GimpStroke *prev) +{ + g_printerr ("gimp_vectors_stroke_get_length: default implementation\n"); - if (vectors_class->stroke_get_length) - return vectors_class->stroke_get_length (vectors, prev); - else - g_printerr ("gimp_vectors_stroke_get_length: default implementation\n"); + return 0.0; +} - return 0; + +GimpAnchor * +gimp_vectors_anchor_get (const GimpVectors *vectors, + const GimpCoords *coord, + GimpStroke **ret_stroke) +{ + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); + + return GIMP_VECTORS_GET_CLASS (vectors)->anchor_get (vectors, coord, + ret_stroke); +} + +static GimpAnchor * +gimp_vectors_real_anchor_get (const GimpVectors *vectors, + const GimpCoords *coord, + GimpStroke **ret_stroke) +{ + gdouble dx, dy, mindist; + GList *stroke; + GimpAnchor *anchor = NULL; + GimpAnchor *minanchor = NULL; + + mindist = -1; + + for (stroke = vectors->strokes; stroke; stroke = g_list_next (stroke)) + { + anchor = gimp_stroke_anchor_get (GIMP_STROKE (stroke->data), coord); + + if (anchor) + { + dx = coord->x - anchor->position.x; + dy = coord->y - anchor->position.y; + + if (mindist > dx * dx + dy * dy || mindist < 0) + { + mindist = dx * dx + dy * dy; + minanchor = anchor; + + if (ret_stroke) + *ret_stroke = stroke->data; + } + } + } + + return minanchor; +} + + +void +gimp_vectors_anchor_delete (GimpVectors *vectors, + GimpAnchor *anchor) +{ + g_return_if_fail (GIMP_IS_VECTORS (vectors)); + g_return_if_fail (anchor != NULL); + + return GIMP_VECTORS_GET_CLASS (vectors)->anchor_delete (vectors, anchor); +} + +static void +gimp_vectors_real_anchor_delete (GimpVectors *vectors, + GimpAnchor *anchor) +{ } @@ -697,16 +732,16 @@ gdouble gimp_vectors_get_length (const GimpVectors *vectors, const GimpAnchor *start) { - GimpVectorsClass *vectors_class; + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0); + return GIMP_VECTORS_GET_CLASS (vectors)->get_length (vectors, start); +} - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); - - if (vectors_class->get_length) - return vectors_class->get_length (vectors, start); - else - g_printerr ("gimp_vectors_get_length: default implementation\n"); +static gdouble +gimp_vectors_real_get_length (const GimpVectors *vectors, + const GimpAnchor *start) +{ + g_printerr ("gimp_vectors_get_length: default implementation\n"); return 0; } @@ -716,16 +751,16 @@ gdouble gimp_vectors_get_distance (const GimpVectors *vectors, const GimpCoords *coord) { - GimpVectorsClass *vectors_class; + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0); + return GIMP_VECTORS_GET_CLASS (vectors)->get_distance (vectors, coord); +} - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); - - if (vectors_class->get_distance) - return vectors_class->get_distance (vectors, coord); - else - g_printerr ("gimp_vectors_get_distance: default implementation\n"); +static gdouble +gimp_vectors_real_get_distance (const GimpVectors *vectors, + const GimpCoords *coord) +{ + g_printerr ("gimp_vectors_get_distance: default implementation\n"); return 0; } @@ -734,20 +769,25 @@ gimp_vectors_get_distance (const GimpVectors *vectors, gint gimp_vectors_interpolate (const GimpVectors *vectors, const GimpStroke *stroke, - const gdouble precision, - const gint max_points, + gdouble precision, + gint max_points, GimpCoords *ret_coords) { - GimpVectorsClass *vectors_class; - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0); - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); + return GIMP_VECTORS_GET_CLASS (vectors)->interpolate (vectors, stroke, + precision, max_points, + ret_coords); +} - if (vectors_class->interpolate) - return vectors_class->interpolate (vectors, stroke, precision, max_points, ret_coords); - else - g_printerr ("gimp_vectors_interpolate: default implementation\n"); +static gint +gimp_vectors_real_interpolate (const GimpVectors *vectors, + const GimpStroke *stroke, + gdouble precision, + gint max_points, + GimpCoords *ret_coords) +{ + g_printerr ("gimp_vectors_interpolate: default implementation\n"); return 0; } @@ -756,16 +796,15 @@ gimp_vectors_interpolate (const GimpVectors *vectors, GimpVectors * gimp_vectors_make_bezier (const GimpVectors *vectors) { - GimpVectorsClass *vectors_class; - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); - vectors_class = GIMP_VECTORS_GET_CLASS (vectors); + return GIMP_VECTORS_GET_CLASS (vectors)->make_bezier (vectors); +} - if (vectors_class->make_bezier) - return vectors_class->make_bezier (vectors); - else - g_printerr ("gimp_vectors_make_bezier: default implementation\n"); +static GimpVectors * +gimp_vectors_real_make_bezier (const GimpVectors *vectors) +{ + g_printerr ("gimp_vectors_make_bezier: default implementation\n"); return NULL; } diff --git a/app/vectors/gimpvectors.h b/app/vectors/gimpvectors.h index 0d6b91887b..3af19508f5 100644 --- a/app/vectors/gimpvectors.h +++ b/app/vectors/gimpvectors.h @@ -54,7 +54,7 @@ struct _GimpVectorsClass /* virtual functions */ void (* stroke_add) (GimpVectors *vectors, - const GimpStroke *stroke); + GimpStroke *stroke); GimpStroke * (* stroke_get) (const GimpVectors *vectors, const GimpCoords *coord); GimpStroke * (* stroke_get_next) (const GimpVectors *vectors, @@ -72,8 +72,8 @@ struct _GimpVectorsClass const GimpCoords *coord); gint (* interpolate) (const GimpVectors *vectors, const GimpStroke *stroke, - const gdouble precision, - const gint max_points, + gdouble precision, + gint max_points, GimpCoords *ret_coords); GimpVectors * (* make_bezier) (const GimpVectors *vectors); }; @@ -107,31 +107,28 @@ GimpAnchor * gimp_vectors_anchor_get_next (const GimpVectors *vectors, * VECTORS_NONE, VECTORS_FIX_ANGLE, VECTORS_FIX_RATIO, VECTORS_RESTRICT_ANGLE * or so. */ -void gimp_vectors_anchor_move_relative (GimpVectors *vectors, - GimpAnchor *anchor, - const GimpCoords *deltacoord, - const gint type); - -void gimp_vectors_anchor_move_absolute (GimpVectors *vectors, - GimpAnchor *anchor, - const GimpCoords *coord, - const gint type); +void gimp_vectors_anchor_move_relative (GimpVectors *vectors, + GimpAnchor *anchor, + const GimpCoords *deltacoord, + gint type); +void gimp_vectors_anchor_move_absolute (GimpVectors *vectors, + GimpAnchor *anchor, + const GimpCoords *coord, + gint type); void gimp_vectors_anchor_delete (GimpVectors *vectors, GimpAnchor *anchor); /* GimpStroke is a connected component of a GimpVectors object */ -void gimp_vectors_stroke_add (GimpVectors *vectors, - GimpStroke *stroke); - +void gimp_vectors_stroke_add (GimpVectors *vectors, + GimpStroke *stroke); GimpStroke * gimp_vectors_stroke_get (const GimpVectors *vectors, const GimpCoords *coord); /* prev == NULL: "first" stroke */ GimpStroke * gimp_vectors_stroke_get_next (const GimpVectors *vectors, const GimpStroke *prev); - gdouble gimp_vectors_stroke_get_length (const GimpVectors *vectors, const GimpStroke *stroke); @@ -139,15 +136,14 @@ gdouble gimp_vectors_stroke_get_length (const GimpVectors *vectors, gdouble gimp_vectors_get_length (const GimpVectors *vectors, const GimpAnchor *start); - gdouble gimp_vectors_get_distance (const GimpVectors *vectors, const GimpCoords *coord); /* returns the number of valid coordinates */ gint gimp_vectors_interpolate (const GimpVectors *vectors, const GimpStroke *stroke, - const gdouble precision, - const gint max_points, + gdouble precision, + gint max_points, GimpCoords *ret_coords);