1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
5
* Copyright (C) 2002 Simon Budig <simon@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 "libgimpcolor/gimpcolor.h"
28
#include "vectors-types.h"
30
#include "core/gimp.h"
31
#include "core/gimpcontainer.h"
32
#include "core/gimpcontext.h"
33
#include "core/gimpdrawable-stroke.h"
34
#include "core/gimp-transform-utils.h"
35
#include "core/gimpimage.h"
36
#include "core/gimpimage-undo-push.h"
37
#include "core/gimpmarshal.h"
38
#include "core/gimppaintinfo.h"
39
#include "core/gimpstrokedesc.h"
41
#include "paint/gimppaintcore-stroke.h"
42
#include "paint/gimppaintoptions.h"
44
#include "gimpanchor.h"
45
#include "gimpstroke.h"
46
#include "gimpvectors.h"
47
#include "gimpvectors-preview.h"
49
#include "gimp-intl.h"
60
static void gimp_vectors_class_init (GimpVectorsClass *klass);
61
static void gimp_vectors_init (GimpVectors *vectors);
63
static void gimp_vectors_finalize (GObject *object);
65
static gint64 gimp_vectors_get_memsize (GimpObject *object,
68
static gboolean gimp_vectors_is_attached (GimpItem *item);
69
static GimpItem * gimp_vectors_duplicate (GimpItem *item,
72
static void gimp_vectors_convert (GimpItem *item,
73
GimpImage *dest_image);
74
static void gimp_vectors_translate (GimpItem *item,
78
static void gimp_vectors_scale (GimpItem *item,
83
GimpInterpolationType interp_type,
84
GimpProgress *progress);
85
static void gimp_vectors_resize (GimpItem *item,
91
static void gimp_vectors_flip (GimpItem *item,
93
GimpOrientationType flip_type,
95
gboolean clip_result);
96
static void gimp_vectors_rotate (GimpItem *item,
98
GimpRotationType rotate_type,
101
gboolean clip_result);
102
static void gimp_vectors_transform (GimpItem *item,
103
GimpContext *context,
104
const GimpMatrix3 *matrix,
105
GimpTransformDirection direction,
106
GimpInterpolationType interp_type,
107
gboolean supersample,
108
gint recursion_level,
109
gboolean clip_result,
110
GimpProgress *progress);
111
static gboolean gimp_vectors_stroke (GimpItem *item,
112
GimpDrawable *drawable,
113
GimpContext *context,
114
GimpStrokeDesc *stroke_desc);
116
static void gimp_vectors_real_thaw (GimpVectors *vectors);
117
static void gimp_vectors_real_stroke_add (GimpVectors *vectors,
119
static void gimp_vectors_real_stroke_remove (GimpVectors *vectors,
121
static GimpStroke * gimp_vectors_real_stroke_get (const GimpVectors *vectors,
122
const GimpCoords *coord);
123
static GimpStroke *gimp_vectors_real_stroke_get_next(const GimpVectors *vectors,
124
const GimpStroke *prev);
125
static gdouble gimp_vectors_real_stroke_get_length (const GimpVectors *vectors,
126
const GimpStroke *prev);
127
static GimpAnchor * gimp_vectors_real_anchor_get (const GimpVectors *vectors,
128
const GimpCoords *coord,
129
GimpStroke **ret_stroke);
130
static void gimp_vectors_real_anchor_delete (GimpVectors *vectors,
132
static gdouble gimp_vectors_real_get_length (const GimpVectors *vectors,
133
const GimpAnchor *start);
134
static gdouble gimp_vectors_real_get_distance (const GimpVectors *vectors,
135
const GimpCoords *coord);
136
static gint gimp_vectors_real_interpolate (const GimpVectors *vectors,
137
const GimpStroke *stroke,
140
GimpCoords *ret_coords);
141
static GimpVectors * gimp_vectors_real_make_bezier (const GimpVectors *vectors);
144
/* private variables */
146
static guint gimp_vectors_signals[LAST_SIGNAL] = { 0 };
148
static GimpItemClass *parent_class = NULL;
152
gimp_vectors_get_type (void)
154
static GType vectors_type = 0;
158
static const GTypeInfo vectors_info =
160
sizeof (GimpVectorsClass),
161
(GBaseInitFunc) NULL,
162
(GBaseFinalizeFunc) NULL,
163
(GClassInitFunc) gimp_vectors_class_init,
164
NULL, /* class_finalize */
165
NULL, /* class_data */
166
sizeof (GimpVectors),
168
(GInstanceInitFunc) gimp_vectors_init,
171
vectors_type = g_type_register_static (GIMP_TYPE_ITEM,
180
gimp_vectors_class_init (GimpVectorsClass *klass)
182
GObjectClass *object_class;
183
GimpObjectClass *gimp_object_class;
184
GimpViewableClass *viewable_class;
185
GimpItemClass *item_class;
187
object_class = G_OBJECT_CLASS (klass);
188
gimp_object_class = GIMP_OBJECT_CLASS (klass);
189
viewable_class = GIMP_VIEWABLE_CLASS (klass);
190
item_class = GIMP_ITEM_CLASS (klass);
192
parent_class = g_type_class_peek_parent (klass);
194
gimp_vectors_signals[FREEZE] =
195
g_signal_new ("freeze",
196
G_TYPE_FROM_CLASS (klass),
198
G_STRUCT_OFFSET (GimpVectorsClass, freeze),
200
gimp_marshal_VOID__VOID,
203
gimp_vectors_signals[THAW] =
204
g_signal_new ("thaw",
205
G_TYPE_FROM_CLASS (klass),
207
G_STRUCT_OFFSET (GimpVectorsClass, thaw),
209
gimp_marshal_VOID__VOID,
212
object_class->finalize = gimp_vectors_finalize;
214
gimp_object_class->get_memsize = gimp_vectors_get_memsize;
216
viewable_class->get_new_preview = gimp_vectors_get_new_preview;
217
viewable_class->default_stock_id = "gimp-path";
219
item_class->is_attached = gimp_vectors_is_attached;
220
item_class->duplicate = gimp_vectors_duplicate;
221
item_class->convert = gimp_vectors_convert;
222
item_class->translate = gimp_vectors_translate;
223
item_class->scale = gimp_vectors_scale;
224
item_class->resize = gimp_vectors_resize;
225
item_class->flip = gimp_vectors_flip;
226
item_class->rotate = gimp_vectors_rotate;
227
item_class->transform = gimp_vectors_transform;
228
item_class->stroke = gimp_vectors_stroke;
229
item_class->default_name = _("Path");
230
item_class->rename_desc = _("Rename Path");
231
item_class->translate_desc = _("Move Path");
232
item_class->scale_desc = _("Scale Path");
233
item_class->resize_desc = _("Resize Path");
234
item_class->flip_desc = _("Flip Path");
235
item_class->rotate_desc = _("Rotate Path");
236
item_class->transform_desc = _("Transform Path");
237
item_class->stroke_desc = _("Stroke Path");
239
klass->freeze = NULL;
240
klass->thaw = gimp_vectors_real_thaw;
242
klass->stroke_add = gimp_vectors_real_stroke_add;
243
klass->stroke_remove = gimp_vectors_real_stroke_remove;
244
klass->stroke_get = gimp_vectors_real_stroke_get;
245
klass->stroke_get_next = gimp_vectors_real_stroke_get_next;
246
klass->stroke_get_length = gimp_vectors_real_stroke_get_length;
248
klass->anchor_get = gimp_vectors_real_anchor_get;
249
klass->anchor_delete = gimp_vectors_real_anchor_delete;
251
klass->get_length = gimp_vectors_real_get_length;
252
klass->get_distance = gimp_vectors_real_get_distance;
253
klass->interpolate = gimp_vectors_real_interpolate;
255
klass->make_bezier = gimp_vectors_real_make_bezier;
259
gimp_vectors_init (GimpVectors *vectors)
261
GimpItem *item = GIMP_ITEM (vectors);
263
item->visible = FALSE;
264
vectors->strokes = NULL;
265
vectors->freeze_count = 0;
269
gimp_vectors_finalize (GObject *object)
271
GimpVectors *vectors = GIMP_VECTORS (object);
273
if (vectors->strokes)
275
g_list_foreach (vectors->strokes, (GFunc) g_object_unref, NULL);
276
g_list_free (vectors->strokes);
277
vectors->strokes = NULL;
280
G_OBJECT_CLASS (parent_class)->finalize (object);
284
gimp_vectors_get_memsize (GimpObject *object,
287
GimpVectors *vectors;
291
vectors = GIMP_VECTORS (object);
293
for (list = vectors->strokes; list; list = g_list_next (list))
294
memsize += (gimp_object_get_memsize (GIMP_OBJECT (list->data), gui_size) +
297
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
302
gimp_vectors_is_attached (GimpItem *item)
304
return (GIMP_IS_IMAGE (item->gimage) &&
305
gimp_container_have (item->gimage->vectors, GIMP_OBJECT (item)));
309
gimp_vectors_duplicate (GimpItem *item,
313
GimpVectors *vectors;
315
GimpVectors *new_vectors;
317
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_VECTORS), NULL);
319
new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type,
322
if (! GIMP_IS_VECTORS (new_item))
325
vectors = GIMP_VECTORS (item);
326
new_vectors = GIMP_VECTORS (new_item);
328
gimp_vectors_copy_strokes (vectors, new_vectors);
334
gimp_vectors_convert (GimpItem *item,
335
GimpImage *dest_image)
337
item->width = dest_image->width;
338
item->height = dest_image->height;
340
GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image);
344
gimp_vectors_translate (GimpItem *item,
349
GimpVectors *vectors = GIMP_VECTORS (item);
352
gimp_vectors_freeze (vectors);
355
gimp_image_undo_push_vectors_mod (gimp_item_get_image (item),
359
for (list = vectors->strokes; list; list = g_list_next (list))
361
GimpStroke *stroke = list->data;
363
gimp_stroke_translate (stroke, offset_x, offset_y);
366
gimp_vectors_thaw (vectors);
370
gimp_vectors_scale (GimpItem *item,
375
GimpInterpolationType interpolation_type,
376
GimpProgress *progress)
378
GimpVectors *vectors = GIMP_VECTORS (item);
379
GimpImage *image = gimp_item_get_image (item);
382
gimp_vectors_freeze (vectors);
384
gimp_image_undo_push_vectors_mod (image, NULL, vectors);
386
for (list = vectors->strokes; list; list = g_list_next (list))
388
GimpStroke *stroke = list->data;
390
gimp_stroke_scale (stroke,
391
(gdouble) new_width / (gdouble) item->width,
392
(gdouble) new_height / (gdouble) item->height);
393
gimp_stroke_translate (stroke, new_offset_x, new_offset_y);
396
GIMP_ITEM_CLASS (parent_class)->scale (item, image->width, image->height,
397
0, 0, interpolation_type, progress);
399
gimp_vectors_thaw (vectors);
403
gimp_vectors_resize (GimpItem *item,
404
GimpContext *context,
410
GimpVectors *vectors = GIMP_VECTORS (item);
411
GimpImage *image = gimp_item_get_image (item);
414
gimp_vectors_freeze (vectors);
416
gimp_image_undo_push_vectors_mod (image, NULL, vectors);
418
for (list = vectors->strokes; list; list = g_list_next (list))
420
GimpStroke *stroke = list->data;
422
gimp_stroke_translate (stroke, offset_x, offset_y);
425
GIMP_ITEM_CLASS (parent_class)->resize (item, context,
426
image->width, image->height, 0, 0);
428
gimp_vectors_thaw (vectors);
432
gimp_vectors_flip (GimpItem *item,
433
GimpContext *context,
434
GimpOrientationType flip_type,
436
gboolean clip_result)
438
GimpVectors *vectors = GIMP_VECTORS (item);
442
gimp_transform_matrix_flip (flip_type, axis, &matrix);
444
gimp_vectors_freeze (vectors);
446
gimp_image_undo_push_vectors_mod (gimp_item_get_image (item),
450
for (list = vectors->strokes; list; list = g_list_next (list))
452
GimpStroke *stroke = list->data;
454
gimp_stroke_transform (stroke, &matrix);
457
gimp_vectors_thaw (vectors);
461
gimp_vectors_rotate (GimpItem *item,
462
GimpContext *context,
463
GimpRotationType rotate_type,
466
gboolean clip_result)
468
GimpVectors *vectors = GIMP_VECTORS (item);
478
case GIMP_ROTATE_180:
481
case GIMP_ROTATE_270:
486
gimp_transform_matrix_rotate_center (center_x, center_y, angle, &matrix);
488
gimp_vectors_freeze (vectors);
490
gimp_image_undo_push_vectors_mod (gimp_item_get_image (item),
494
for (list = vectors->strokes; list; list = g_list_next (list))
496
GimpStroke *stroke = list->data;
498
gimp_stroke_transform (stroke, &matrix);
501
gimp_vectors_thaw (vectors);
505
gimp_vectors_transform (GimpItem *item,
506
GimpContext *context,
507
const GimpMatrix3 *matrix,
508
GimpTransformDirection direction,
509
GimpInterpolationType interpolation_type,
510
gboolean supersample,
511
gint recursion_level,
512
gboolean clip_result,
513
GimpProgress *progress)
515
GimpVectors *vectors = GIMP_VECTORS (item);
516
GimpMatrix3 local_matrix;
519
gimp_vectors_freeze (vectors);
521
gimp_image_undo_push_vectors_mod (gimp_item_get_image (item),
525
local_matrix = *matrix;
527
if (direction == GIMP_TRANSFORM_BACKWARD)
528
gimp_matrix3_invert (&local_matrix);
530
for (list = vectors->strokes; list; list = g_list_next (list))
532
GimpStroke *stroke = list->data;
534
gimp_stroke_transform (stroke, &local_matrix);
537
gimp_vectors_thaw (vectors);
541
gimp_vectors_stroke (GimpItem *item,
542
GimpDrawable *drawable,
543
GimpContext *context,
544
GimpStrokeDesc *stroke_desc)
546
GimpVectors *vectors = GIMP_VECTORS (item);
547
gboolean retval = FALSE;
549
if (! vectors->strokes)
551
g_message (_("Cannot stroke empty path."));
555
switch (stroke_desc->method)
557
case GIMP_STROKE_METHOD_LIBART:
558
gimp_drawable_stroke_vectors (drawable,
559
stroke_desc->stroke_options,
564
case GIMP_STROKE_METHOD_PAINT_CORE:
568
core = g_object_new (stroke_desc->paint_info->paint_type, NULL);
570
retval = gimp_paint_core_stroke_vectors (core, drawable,
571
stroke_desc->paint_options,
574
g_object_unref (core);
579
g_return_val_if_reached (FALSE);
586
gimp_vectors_real_thaw (GimpVectors *vectors)
588
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (vectors));
592
/* public functions */
595
gimp_vectors_new (GimpImage *gimage,
598
GimpVectors *vectors;
600
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
602
vectors = g_object_new (GIMP_TYPE_VECTORS, NULL);
604
gimp_item_configure (GIMP_ITEM (vectors), gimage,
605
0, 0, gimage->width, gimage->height,
612
gimp_vectors_freeze (GimpVectors *vectors)
614
g_return_if_fail (GIMP_IS_VECTORS (vectors));
616
vectors->freeze_count++;
618
if (vectors->freeze_count == 1)
619
g_signal_emit (vectors, gimp_vectors_signals[FREEZE], 0);
623
gimp_vectors_thaw (GimpVectors *vectors)
625
g_return_if_fail (GIMP_IS_VECTORS (vectors));
626
g_return_if_fail (vectors->freeze_count > 0);
628
vectors->freeze_count--;
630
if (vectors->freeze_count == 0)
631
g_signal_emit (vectors, gimp_vectors_signals[THAW], 0);
635
gimp_vectors_copy_strokes (const GimpVectors *src_vectors,
636
GimpVectors *dest_vectors)
638
g_return_if_fail (GIMP_IS_VECTORS (src_vectors));
639
g_return_if_fail (GIMP_IS_VECTORS (dest_vectors));
641
gimp_vectors_freeze (dest_vectors);
643
if (dest_vectors->strokes)
645
g_list_foreach (dest_vectors->strokes, (GFunc) g_object_unref, NULL);
646
g_list_free (dest_vectors->strokes);
649
dest_vectors->strokes = NULL;
651
gimp_vectors_add_strokes (src_vectors, dest_vectors);
653
gimp_vectors_thaw (dest_vectors);
658
gimp_vectors_add_strokes (const GimpVectors *src_vectors,
659
GimpVectors *dest_vectors)
661
GList *current_lstroke;
664
g_return_if_fail (GIMP_IS_VECTORS (src_vectors));
665
g_return_if_fail (GIMP_IS_VECTORS (dest_vectors));
667
gimp_vectors_freeze (dest_vectors);
669
strokes_copy = g_list_copy (src_vectors->strokes);
670
current_lstroke = strokes_copy;
672
while (current_lstroke)
674
current_lstroke->data = gimp_stroke_duplicate (current_lstroke->data);
675
current_lstroke = g_list_next (current_lstroke);
678
dest_vectors->strokes = g_list_concat (dest_vectors->strokes, strokes_copy);
680
gimp_vectors_thaw (dest_vectors);
684
/* Calling the virtual functions */
687
gimp_vectors_stroke_add (GimpVectors *vectors,
690
g_return_if_fail (GIMP_IS_VECTORS (vectors));
691
g_return_if_fail (GIMP_IS_STROKE (stroke));
693
gimp_vectors_freeze (vectors);
695
GIMP_VECTORS_GET_CLASS (vectors)->stroke_add (vectors, stroke);
697
gimp_vectors_thaw (vectors);
701
gimp_vectors_real_stroke_add (GimpVectors *vectors,
704
/* Don't g_list_prepend() here. See ChangeLog 2003-05-21 --Mitch */
706
vectors->strokes = g_list_append (vectors->strokes, stroke);
707
g_object_ref (stroke);
711
gimp_vectors_stroke_remove (GimpVectors *vectors,
714
g_return_if_fail (GIMP_IS_VECTORS (vectors));
715
g_return_if_fail (GIMP_IS_STROKE (stroke));
717
gimp_vectors_freeze (vectors);
719
GIMP_VECTORS_GET_CLASS (vectors)->stroke_remove (vectors, stroke);
721
gimp_vectors_thaw (vectors);
725
gimp_vectors_real_stroke_remove (GimpVectors *vectors,
730
list = g_list_find (vectors->strokes, stroke);
734
vectors->strokes = g_list_delete_link (vectors->strokes, list);
735
g_object_unref (stroke);
741
gimp_vectors_stroke_get (const GimpVectors *vectors,
742
const GimpCoords *coord)
744
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
746
return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get (vectors, coord);
750
gimp_vectors_real_stroke_get (const GimpVectors *vectors,
751
const GimpCoords *coord)
754
gdouble mindist = G_MAXDOUBLE;
755
GimpStroke *minstroke = NULL;
757
for (stroke = vectors->strokes; stroke; stroke = g_list_next (stroke))
759
GimpAnchor *anchor = gimp_stroke_anchor_get (stroke->data, coord);
765
dx = coord->x - anchor->position.x;
766
dy = coord->y - anchor->position.y;
768
if (mindist > dx * dx + dy * dy)
770
mindist = dx * dx + dy * dy;
771
minstroke = GIMP_STROKE (stroke->data);
781
gimp_vectors_stroke_get_next (const GimpVectors *vectors,
782
const GimpStroke *prev)
784
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
786
return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_next (vectors, prev);
790
gimp_vectors_real_stroke_get_next (const GimpVectors *vectors,
791
const GimpStroke *prev)
795
return vectors->strokes ? vectors->strokes->data : NULL;
801
stroke = g_list_find (vectors->strokes, prev);
803
g_return_val_if_fail (stroke != NULL, NULL);
805
return stroke->next ? GIMP_STROKE (stroke->next->data) : NULL;
811
gimp_vectors_stroke_get_length (const GimpVectors *vectors,
812
const GimpStroke *prev)
814
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0);
816
return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_length (vectors, prev);
820
gimp_vectors_real_stroke_get_length (const GimpVectors *vectors,
821
const GimpStroke *prev)
823
g_printerr ("gimp_vectors_stroke_get_length: default implementation\n");
830
gimp_vectors_anchor_get (const GimpVectors *vectors,
831
const GimpCoords *coord,
832
GimpStroke **ret_stroke)
834
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
836
return GIMP_VECTORS_GET_CLASS (vectors)->anchor_get (vectors, coord,
841
gimp_vectors_real_anchor_get (const GimpVectors *vectors,
842
const GimpCoords *coord,
843
GimpStroke **ret_stroke)
845
gdouble dx, dy, mindist;
847
GimpAnchor *anchor = NULL;
848
GimpAnchor *minanchor = NULL;
852
for (stroke = vectors->strokes; stroke; stroke = g_list_next (stroke))
854
anchor = gimp_stroke_anchor_get (GIMP_STROKE (stroke->data), coord);
858
dx = coord->x - anchor->position.x;
859
dy = coord->y - anchor->position.y;
861
if (mindist > dx * dx + dy * dy || mindist < 0)
863
mindist = dx * dx + dy * dy;
867
*ret_stroke = stroke->data;
877
gimp_vectors_anchor_delete (GimpVectors *vectors,
880
g_return_if_fail (GIMP_IS_VECTORS (vectors));
881
g_return_if_fail (anchor != NULL);
883
GIMP_VECTORS_GET_CLASS (vectors)->anchor_delete (vectors, anchor);
887
gimp_vectors_real_anchor_delete (GimpVectors *vectors,
894
gimp_vectors_anchor_select (GimpVectors *vectors,
895
GimpStroke *target_stroke,
903
for (stroke_list = vectors->strokes; stroke_list;
904
stroke_list = g_list_next (stroke_list))
906
stroke = GIMP_STROKE (stroke_list->data);
907
gimp_stroke_anchor_select (stroke,
908
stroke == target_stroke ? anchor : NULL,
909
selected, exclusive);
915
gimp_vectors_get_length (const GimpVectors *vectors,
916
const GimpAnchor *start)
918
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0);
920
return GIMP_VECTORS_GET_CLASS (vectors)->get_length (vectors, start);
924
gimp_vectors_real_get_length (const GimpVectors *vectors,
925
const GimpAnchor *start)
927
g_printerr ("gimp_vectors_get_length: default implementation\n");
934
gimp_vectors_get_distance (const GimpVectors *vectors,
935
const GimpCoords *coord)
937
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0);
939
return GIMP_VECTORS_GET_CLASS (vectors)->get_distance (vectors, coord);
943
gimp_vectors_real_get_distance (const GimpVectors *vectors,
944
const GimpCoords *coord)
946
g_printerr ("gimp_vectors_get_distance: default implementation\n");
952
gimp_vectors_bounds (const GimpVectors *vectors,
958
GArray *stroke_coords;
959
GimpStroke *cur_stroke;
961
gboolean has_strokes = FALSE;
965
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE);
966
g_return_val_if_fail (x1 != NULL, FALSE);
967
g_return_val_if_fail (y1 != NULL, FALSE);
968
g_return_val_if_fail (x2 != NULL, FALSE);
969
g_return_val_if_fail (y2 != NULL, FALSE);
971
for (cur_stroke = gimp_vectors_stroke_get_next (vectors, NULL);
973
cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke))
975
stroke_coords = gimp_stroke_interpolate (cur_stroke, 1.0, &closed);
979
if (! has_strokes && stroke_coords->len > 0)
982
point = g_array_index (stroke_coords, GimpCoords, 0);
987
for (i=0; i < stroke_coords->len; i++)
989
point = g_array_index (stroke_coords, GimpCoords, i);
990
*x1 = MIN (*x1, point.x);
991
*y1 = MIN (*y1, point.y);
992
*x2 = MAX (*x2, point.x);
993
*y2 = MAX (*y2, point.y);
995
g_array_free (stroke_coords, TRUE);
1003
gimp_vectors_interpolate (const GimpVectors *vectors,
1004
const GimpStroke *stroke,
1007
GimpCoords *ret_coords)
1009
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0);
1011
return GIMP_VECTORS_GET_CLASS (vectors)->interpolate (vectors, stroke,
1012
precision, max_points,
1017
gimp_vectors_real_interpolate (const GimpVectors *vectors,
1018
const GimpStroke *stroke,
1021
GimpCoords *ret_coords)
1023
g_printerr ("gimp_vectors_interpolate: default implementation\n");
1030
gimp_vectors_make_bezier (const GimpVectors *vectors)
1032
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
1034
return GIMP_VECTORS_GET_CLASS (vectors)->make_bezier (vectors);
1037
static GimpVectors *
1038
gimp_vectors_real_make_bezier (const GimpVectors *vectors)
1040
g_printerr ("gimp_vectors_make_bezier: default implementation\n");