1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
5
* Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#include <glib-object.h>
26
#include "vectors-types.h"
28
#include "core/gimpimage.h"
29
#include "core/gimplist.h"
31
#include "gimpanchor.h"
32
#include "gimpbezierstroke.h"
33
#include "gimpvectors.h"
34
#include "gimpvectors-compat.h"
39
GIMP_VECTORS_COMPAT_ANCHOR = 1,
40
GIMP_VECTORS_COMPAT_CONTROL = 2,
41
GIMP_VECTORS_COMPAT_NEW_STROKE = 3
47
gimp_vectors_compat_new (GimpImage *gimage,
49
GimpVectorsCompatPoint *points,
56
GimpCoords *curr_stroke;
57
GimpCoords *curr_coord;
60
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
61
g_return_val_if_fail (name != NULL, NULL);
62
g_return_val_if_fail (points != NULL || n_points == 0, NULL);
63
g_return_val_if_fail (n_points >= 0, NULL);
65
vectors = gimp_vectors_new (gimage, name);
67
coords = g_new0 (GimpCoords, n_points + 1);
69
curr_stroke = curr_coord = coords;
71
/* skip the first control point, will set it later */
74
for (i = 0; i < n_points; i++)
76
curr_coord->x = points[i].x;
77
curr_coord->y = points[i].y;
78
curr_coord->pressure = GIMP_COORDS_DEFAULT_PRESSURE;
79
curr_coord->xtilt = GIMP_COORDS_DEFAULT_TILT;
80
curr_coord->ytilt = GIMP_COORDS_DEFAULT_TILT;
81
curr_coord->wheel = GIMP_COORDS_DEFAULT_WHEEL;
83
/* copy the first anchor to be the first control point */
84
if (curr_coord == curr_stroke + 1)
85
*curr_stroke = *curr_coord;
87
/* found new stroke start */
88
if (points[i].type == GIMP_VECTORS_COMPAT_NEW_STROKE)
90
/* copy the last control point to the beginning of the stroke */
91
*curr_stroke = *(curr_coord - 1);
94
gimp_bezier_stroke_new_from_coords (curr_stroke,
95
curr_coord - curr_stroke - 1,
97
gimp_vectors_stroke_add (vectors, stroke);
98
g_object_unref (stroke);
100
/* start a new stroke */
101
curr_stroke = curr_coord - 1;
103
/* copy the first anchor to be the first control point */
104
*curr_stroke = *curr_coord;
112
/* copy the last control point to the beginning of the stroke */
114
*curr_stroke = *curr_coord;
117
stroke = gimp_bezier_stroke_new_from_coords (curr_stroke,
118
curr_coord - curr_stroke,
120
gimp_vectors_stroke_add (vectors, stroke);
121
g_object_unref (stroke);
129
gimp_vectors_compat_is_compatible (GimpImage *gimage)
131
GList *list, *strokes;
132
GimpVectors *vectors;
136
for (list = GIMP_LIST (gimage->vectors)->list;
138
list = g_list_next (list))
142
vectors = GIMP_VECTORS (list->data);
144
if (GIMP_ITEM (vectors)->visible == TRUE)
147
for (strokes = vectors->strokes; strokes; strokes = g_list_next (strokes))
149
stroke = GIMP_STROKE (strokes->data);
150
if (! GIMP_IS_BEZIER_STROKE (stroke))
163
GimpVectorsCompatPoint *
164
gimp_vectors_compat_get_points (GimpVectors *vectors,
168
GimpVectorsCompatPoint *points;
171
GList *postponed = NULL; /* for the one open stroke... */
173
gboolean first_stroke = TRUE;
175
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
176
g_return_val_if_fail (n_points != NULL, NULL);
177
g_return_val_if_fail (closed != NULL, NULL);
184
for (strokes = vectors->strokes; strokes; strokes = g_list_next (strokes))
186
GimpStroke *stroke = strokes->data;
189
if (! stroke->closed)
197
g_warning ("gimp_vectors_compat_get_points(): convert failed");
203
n_anchors = g_list_length (stroke->anchors);
205
if (! stroke->closed)
208
*n_points += n_anchors;
211
points = g_new0 (GimpVectorsCompatPoint, *n_points);
215
for (strokes = vectors->strokes;
216
strokes || postponed;
217
strokes = g_list_next (strokes))
224
if (postponed && strokes == postponed)
225
/* we need to visit the open stroke last... */
228
stroke = GIMP_STROKE (strokes->data);
232
stroke = GIMP_STROKE (postponed->data);
236
for (anchors = stroke->anchors;
238
anchors = g_list_next (anchors))
240
GimpAnchor *anchor = anchors->data;
242
/* skip the first anchor, will add it at the end if needed */
246
switch (anchor->type)
248
case GIMP_ANCHOR_ANCHOR:
249
if (anchors->prev == stroke->anchors && ! first_stroke)
250
points[i].type = GIMP_VECTORS_COMPAT_NEW_STROKE;
252
points[i].type = GIMP_VECTORS_COMPAT_ANCHOR;
255
case GIMP_ANCHOR_CONTROL:
256
points[i].type = GIMP_VECTORS_COMPAT_CONTROL;
260
points[i].x = anchor->position.x;
261
points[i].y = anchor->position.y;
265
/* write the skipped control point */
266
if (! anchors->next && stroke->closed)
268
anchor = GIMP_ANCHOR (stroke->anchors->data);
270
points[i].type = GIMP_VECTORS_COMPAT_CONTROL;
271
points[i].x = anchor->position.x;
272
points[i].y = anchor->position.y;
277
first_stroke = FALSE;