mirror of https://github.com/GNOME/gimp.git
695 lines
18 KiB
C
695 lines
18 KiB
C
/* The GIMP -- an image manipulation program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* gimpstroke.c
|
|
* Copyright (C) 2002 Simon Budig <simon@gimp.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "glib-object.h"
|
|
|
|
#include "vectors-types.h"
|
|
|
|
#include "gimpanchor.h"
|
|
#include "gimpstroke.h"
|
|
|
|
|
|
/* Prototypes */
|
|
|
|
static void gimp_stroke_class_init (GimpStrokeClass *klass);
|
|
static void gimp_stroke_init (GimpStroke *stroke);
|
|
|
|
static void gimp_stroke_finalize (GObject *object);
|
|
|
|
static gsize gimp_stroke_get_memsize (GimpObject *object);
|
|
|
|
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);
|
|
|
|
/* private variables */
|
|
|
|
static GObjectClass *parent_class = NULL;
|
|
|
|
|
|
GType
|
|
gimp_stroke_get_type (void)
|
|
{
|
|
static GType stroke_type = 0;
|
|
|
|
if (! stroke_type)
|
|
{
|
|
static const GTypeInfo stroke_info =
|
|
{
|
|
sizeof (GimpStrokeClass),
|
|
(GBaseInitFunc) NULL,
|
|
(GBaseFinalizeFunc) NULL,
|
|
(GClassInitFunc) gimp_stroke_class_init,
|
|
NULL, /* class_finalize */
|
|
NULL, /* class_data */
|
|
sizeof (GimpStroke),
|
|
0, /* n_preallocs */
|
|
(GInstanceInitFunc) gimp_stroke_init,
|
|
};
|
|
|
|
stroke_type = g_type_register_static (GIMP_TYPE_OBJECT,
|
|
"GimpStroke",
|
|
&stroke_info, 0);
|
|
}
|
|
|
|
return stroke_type;
|
|
}
|
|
|
|
static void
|
|
gimp_stroke_class_init (GimpStrokeClass *klass)
|
|
{
|
|
GObjectClass *object_class;
|
|
GimpObjectClass *gimp_object_class;
|
|
|
|
object_class = G_OBJECT_CLASS (klass);
|
|
gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
|
|
|
parent_class = g_type_class_peek_parent (klass);
|
|
|
|
object_class->finalize = gimp_stroke_finalize;
|
|
|
|
gimp_object_class->get_memsize = gimp_stroke_get_memsize;
|
|
|
|
klass->changed = NULL;
|
|
klass->removed = NULL;
|
|
|
|
klass->anchor_get = gimp_stroke_real_anchor_get;
|
|
klass->anchor_get_next = gimp_stroke_real_anchor_get_next;
|
|
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->get_length = NULL;
|
|
klass->get_distance = NULL;
|
|
klass->interpolate = NULL;
|
|
|
|
klass->temp_anchor_get = NULL;
|
|
klass->temp_anchor_set = NULL;
|
|
klass->temp_anchor_fix = NULL;
|
|
|
|
klass->duplicate = gimp_stroke_real_duplicate;
|
|
klass->make_bezier = NULL;
|
|
|
|
klass->get_draw_anchors = NULL;
|
|
klass->get_draw_controls = NULL;
|
|
klass->get_draw_lines = NULL;
|
|
}
|
|
|
|
static void
|
|
gimp_stroke_init (GimpStroke *stroke)
|
|
{
|
|
stroke->anchors = NULL;
|
|
stroke->temp_anchor = NULL;
|
|
};
|
|
|
|
static void
|
|
gimp_stroke_finalize (GObject *object)
|
|
{
|
|
#ifdef __GNUC__
|
|
#warning FIXME: implement gimp_stroke_finalize()
|
|
#endif
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
}
|
|
|
|
static gsize
|
|
gimp_stroke_get_memsize (GimpObject *object)
|
|
{
|
|
GimpStroke *stroke;
|
|
gsize memsize = 0;
|
|
|
|
stroke = GIMP_STROKE (object);
|
|
|
|
memsize += g_list_length (stroke->anchors) * (sizeof (GList) +
|
|
sizeof (GimpAnchor));
|
|
|
|
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (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);
|
|
}
|
|
|
|
|
|
static GimpAnchor *
|
|
gimp_stroke_real_anchor_get (const GimpStroke *stroke,
|
|
const GimpCoords *coord)
|
|
{
|
|
gdouble dx, dy, mindist = -1;
|
|
GList *list;
|
|
GimpAnchor *anchor = NULL;
|
|
|
|
g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL);
|
|
|
|
list = gimp_stroke_get_draw_controls (stroke);
|
|
|
|
while (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);
|
|
|
|
list = gimp_stroke_get_draw_anchors (stroke);
|
|
|
|
while (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);
|
|
|
|
return anchor;
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
static GimpAnchor *
|
|
gimp_stroke_real_anchor_get_next (const GimpStroke *stroke,
|
|
const GimpAnchor *prev)
|
|
{
|
|
GList *listitem;
|
|
|
|
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);
|
|
}
|
|
else
|
|
listitem = stroke->anchors;
|
|
|
|
if (listitem)
|
|
return (GimpAnchor *) listitem->data;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void
|
|
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);
|
|
|
|
if (stroke_class->anchor_select)
|
|
stroke_class->anchor_select (stroke, anchor, exclusive);
|
|
else
|
|
{
|
|
GList *cur_ptr;
|
|
|
|
cur_ptr = stroke->anchors;
|
|
|
|
if (exclusive)
|
|
{
|
|
while (cur_ptr)
|
|
{
|
|
((GimpAnchor *) cur_ptr->data)->selected = FALSE;
|
|
cur_ptr = g_list_next (cur_ptr);
|
|
}
|
|
}
|
|
|
|
if ((cur_ptr = g_list_find (stroke->anchors, anchor)) != NULL)
|
|
((GimpAnchor *) cur_ptr->data)->selected = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
gimp_stroke_anchor_move_relative (GimpStroke *stroke,
|
|
GimpAnchor *anchor,
|
|
const GimpCoords *deltacoord,
|
|
const GimpAnchorFeatureType feature)
|
|
{
|
|
GimpStrokeClass *stroke_class;
|
|
|
|
g_return_if_fail (GIMP_IS_STROKE (stroke));
|
|
|
|
stroke_class = GIMP_STROKE_GET_CLASS (stroke);
|
|
|
|
stroke_class->anchor_move_relative (stroke, anchor, deltacoord, feature);
|
|
}
|
|
|
|
|
|
static void
|
|
gimp_stroke_real_anchor_move_relative (GimpStroke *stroke,
|
|
GimpAnchor *anchor,
|
|
const GimpCoords *deltacoord,
|
|
const 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;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
gimp_stroke_anchor_move_absolute (GimpStroke *stroke,
|
|
GimpAnchor *anchor,
|
|
const GimpCoords *coord,
|
|
const GimpAnchorFeatureType feature)
|
|
{
|
|
GimpStrokeClass *stroke_class;
|
|
|
|
g_return_if_fail (GIMP_IS_STROKE (stroke));
|
|
|
|
stroke_class = GIMP_STROKE_GET_CLASS (stroke);
|
|
|
|
stroke_class->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)
|
|
{
|
|
/*
|
|
* 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;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
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);
|
|
|
|
if (stroke_class->anchor_convert)
|
|
stroke_class->anchor_convert (stroke, anchor, feature);
|
|
else
|
|
g_printerr ("gimp_stroke_anchor_convert: default implementation\n");
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void
|
|
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);
|
|
|
|
if (stroke_class->anchor_delete)
|
|
stroke_class->anchor_delete (stroke, anchor);
|
|
else
|
|
g_printerr ("gimp_stroke_anchor_delete: default implementation\n");
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
gdouble
|
|
gimp_stroke_get_length (const GimpStroke *stroke)
|
|
{
|
|
GimpStrokeClass *stroke_class;
|
|
|
|
g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0);
|
|
|
|
stroke_class = GIMP_STROKE_GET_CLASS (stroke);
|
|
|
|
if (stroke_class->get_length)
|
|
return stroke_class->get_length (stroke);
|
|
else
|
|
g_printerr ("gimp_stroke_get_length: default implementation\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
gdouble
|
|
gimp_stroke_get_distance (const GimpStroke *stroke,
|
|
const GimpCoords *coord)
|
|
{
|
|
GimpStrokeClass *stroke_class;
|
|
|
|
g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0);
|
|
|
|
stroke_class = GIMP_STROKE_GET_CLASS (stroke);
|
|
|
|
if (stroke_class->get_distance)
|
|
return stroke_class->get_distance (stroke, coord);
|
|
else
|
|
g_printerr ("gimp_stroke_get_distance: default implementation\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
GArray *
|
|
gimp_stroke_interpolate (const GimpStroke *stroke,
|
|
const 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;
|
|
}
|
|
|
|
|
|
GimpAnchor *
|
|
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);
|
|
|
|
if (stroke_class->temp_anchor_get)
|
|
return stroke_class->temp_anchor_get (stroke);
|
|
else
|
|
g_printerr ("gimp_stroke_temp_anchor_get: default implementation\n");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
GimpAnchor *
|
|
gimp_stroke_temp_anchor_set (GimpStroke *stroke,
|
|
const GimpCoords *coord)
|
|
{
|
|
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_set)
|
|
return stroke_class->temp_anchor_set (stroke, coord);
|
|
else
|
|
g_printerr ("gimp_stroke_temp_anchor_set: default implementation\n");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
if (stroke_class->temp_anchor_fix)
|
|
return stroke_class->temp_anchor_fix (stroke);
|
|
else
|
|
g_printerr ("gimp_stroke_temp_anchor_fix: default implementation\n");
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
GimpStroke *
|
|
gimp_stroke_duplicate (const GimpStroke *stroke)
|
|
{
|
|
g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL);
|
|
|
|
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);
|
|
|
|
new_stroke = g_object_new (stroke_type, NULL);
|
|
new_gimpobject = GIMP_OBJECT (new_stroke);
|
|
|
|
gimp_object_set_name (new_gimpobject, GIMP_OBJECT (stroke)->name);
|
|
|
|
anchorlist = g_list_copy (stroke->anchors);
|
|
|
|
new_stroke->anchors = anchorlist;
|
|
|
|
while (anchorlist)
|
|
{
|
|
new_anchor = g_new0 (GimpAnchor, 1);
|
|
*new_anchor = *((GimpAnchor *) (anchorlist->data));
|
|
|
|
anchorlist->data = (gpointer) new_anchor;
|
|
anchorlist = g_list_next (anchorlist);
|
|
}
|
|
|
|
if (stroke->temp_anchor)
|
|
{
|
|
new_stroke->temp_anchor = g_new0 (GimpAnchor, 1);
|
|
*(new_stroke->temp_anchor) = *(stroke->temp_anchor);
|
|
}
|
|
else
|
|
{
|
|
new_stroke->temp_anchor = NULL;
|
|
}
|
|
|
|
return new_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);
|
|
|
|
if (stroke_class->make_bezier)
|
|
return stroke_class->make_bezier (stroke);
|
|
else
|
|
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);
|
|
|
|
if (stroke_class->get_draw_anchors)
|
|
return stroke_class->get_draw_anchors (stroke);
|
|
else
|
|
{
|
|
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;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
if (stroke_class->get_draw_controls)
|
|
return stroke_class->get_draw_controls (stroke);
|
|
else
|
|
{
|
|
GList *cur_ptr, *ret_list = NULL;
|
|
|
|
cur_ptr = stroke->anchors;
|
|
|
|
while (cur_ptr)
|
|
{
|
|
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);
|
|
}
|
|
|
|
return ret_list;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|