diff --git a/ChangeLog b/ChangeLog index 5cfb42b3a8..e6798880fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2003-05-22 Michael Natterer + + * app/vectors/Makefile.am + * app/vectors/gimpvectors-compat.[ch]: new files implementing a + compatibility API for converting old XCF and PDB point arrays + to GimpVectors and vice versa. + + * app/xcf/xcf-load.c + * app/xcf/xcf-save.c + * tools/pdbgen/pdb/paths.pdb: use the new functions instead of + having slightly different, but equally ugly code twice. + + * app/xcf/xcf-load.c: cleaned up path loading a lot. Removed the + path_point loading utility functions. + + * app/pdb/paths_cmds.c: regenerated. + + * app/Makefile.am: link vectors/libappvectors.a after + xcf/libappxcf.a so the compat functions (which are not needed in + vectors/) are found. Also reverted an accidentially checked in + change to the libgimpwidgets link order. + 2003-05-22 Sven Neumann * plug-ins/helpbrowser/Makefile.am diff --git a/app/Makefile.am b/app/Makefile.am index 84bb92bcc2..be778c64fa 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -77,7 +77,6 @@ INCLUDES = \ gimp_1_3_LDADD = \ $(gimp_exp) \ - $(top_builddir)/libgimpwidgets/libgimpwidgets-$(LT_RELEASE).la \ config/libappconfig.a \ gui/libappgui.a \ display/libappdisplay.a \ @@ -87,8 +86,8 @@ gimp_1_3_LDADD = \ pdb/libapppdb.a \ paint/libapppaint.a \ text/libapptext.a \ - vectors/libappvectors.a \ xcf/libappxcf.a \ + vectors/libappvectors.a \ file/libappfile.a \ plug-in/libappplug-in.a \ paint-funcs/libapppaint-funcs.a \ @@ -97,6 +96,7 @@ gimp_1_3_LDADD = \ $(top_builddir)/libgimpmath/libgimpmath-$(LT_RELEASE).la \ $(top_builddir)/libgimpbase/libgimpbase-$(LT_RELEASE).la \ $(top_builddir)/libgimpmodule/libgimpmodule-$(LT_RELEASE).la \ + $(top_builddir)/libgimpwidgets/libgimpwidgets-$(LT_RELEASE).la \ $(GTK_LIBS) \ $(PANGOFT2_LIBS) \ $(LIBART_LIBS) \ diff --git a/app/pdb/paths_cmds.c b/app/pdb/paths_cmds.c index 04c2eec5af..d1b1df93da 100644 --- a/app/pdb/paths_cmds.c +++ b/app/pdb/paths_cmds.c @@ -39,6 +39,7 @@ #include "paint/gimppaintoptions.h" #include "vectors/gimpanchor.h" #include "vectors/gimpbezierstroke.h" +#include "vectors/gimpvectors-compat.h" #include "vectors/gimpvectors.h" static ProcRecord path_list_proc; @@ -356,7 +357,7 @@ path_get_points_invoker (Gimp *gimp, gint32 path_type = 0; gint32 path_closed = 0; gint32 num_points = 0; - gdouble *points = NULL; + gdouble *points_pairs = NULL; GimpVectors *vectors; gimage = gimp_image_get_by_ID (gimp, args[0].value.pdb_int); @@ -373,79 +374,33 @@ path_get_points_invoker (Gimp *gimp, if (vectors) { - GList *list; - GimpStroke *stroke; - gdouble *curr_point; + GimpVectorsCompatPoint *points; - path_type = 1; - path_closed = FALSE; /* FIXME */ + path_type = 1; /* BEZIER (1.2 compat) */ - for (list = vectors->strokes; list; list = g_list_next (list)) + points = gimp_vectors_compat_get_points (vectors, &num_points, + &path_closed); + + if (points) { - gint num_anchors; + gdouble *curr_point; + gint i; - stroke = (GimpStroke *) list->data; + points_pairs = g_new0 (gdouble, num_points * 3); - num_anchors = g_list_length (stroke->anchors); - - if (list->next && (num_anchors % 3) != 0) - num_anchors++; - - num_points += num_anchors; - } - - points = g_new0 (gdouble, num_points * 3); - - curr_point = points; - - for (list = vectors->strokes; list; list = g_list_next (list)) - { - GList *anchors; - - stroke = (GimpStroke *) list->data; - - for (anchors = stroke->anchors; - anchors; - anchors = g_list_next (anchors)) + for (i = 0, curr_point = points_pairs; + i < num_points; + i++, curr_point += 3) { - GimpAnchor *anchor = anchors->data; - gdouble anchor_type = 1.0; - - switch (anchor->type) - { - case GIMP_ANCHOR_ANCHOR: - if (list->prev && ! anchors->prev) - anchor_type = 3.0; /* new stroke start */ - else - anchor_type = 1.0; /* ordinary anchor */ - break; - - case GIMP_ANCHOR_CONTROL: - anchor_type = 2.0; - break; - } - - curr_point[0] = anchor->position.x; - curr_point[1] = anchor->position.y; - curr_point[2] = anchor_type; - - curr_point += 3; - - /* FIXME */ - if (! anchors->next && list->next) - { - /* create a fake closed segment */ - - anchor = (GimpAnchor *) stroke->anchors->data; - - curr_point[0] = anchor->position.x; - curr_point[1] = anchor->position.y; - curr_point[2] = 2.0; - - curr_point += 3; - } + curr_point[0] = points[i].x; + curr_point[1] = points[i].y; + curr_point[2] = points[i].type; } + + g_free (points); } + else + success = FALSE; } else success = FALSE; @@ -458,7 +413,7 @@ path_get_points_invoker (Gimp *gimp, return_args[1].value.pdb_int = path_type; return_args[2].value.pdb_int = path_closed; return_args[3].value.pdb_int = num_points; - return_args[4].value.pdb_pointer = points; + return_args[4].value.pdb_pointer = points_pairs; } return return_args; @@ -528,7 +483,7 @@ path_set_points_invoker (Gimp *gimp, gint32 ptype; gint32 num_path_points = 0; gdouble *points_pairs; - gboolean pclosed = FALSE; + gboolean closed = FALSE; gimage = gimp_image_get_by_ID (gimp, args[0].value.pdb_int); if (! GIMP_IS_IMAGE (gimage)) @@ -549,79 +504,40 @@ path_set_points_invoker (Gimp *gimp, if (success) { if ((num_path_points / 3) % 3 == 0) - pclosed = TRUE; + closed = TRUE; else if ((num_path_points / 3) % 3 != 2) success = FALSE; if (success) { - GimpVectors *vectors; - GimpCoords *coords; - GimpCoords *curr_coord; - gint num_coords; - gdouble *curr_point_pair; + GimpVectors *vectors; + gdouble *curr_point_pair; + GimpVectorsCompatPoint *points; + gint n_points; + gint i; - vectors = gimp_vectors_new (gimage, pname); + n_points = num_path_points / 3; - num_coords = num_path_points / 3; - coords = g_new0 (GimpCoords, num_coords + 1); + points = g_new0 (GimpVectorsCompatPoint, n_points); - curr_coord = coords; - curr_point_pair = points_pairs; - - while (num_coords > 0) + for (i = 0, curr_point_pair = points_pairs; + i < n_points; + i++, curr_point_pair += 3) { - GimpStroke *stroke; - GimpCoords *next_stroke; - gint num_stroke_coords; - - for (next_stroke = curr_coord; - num_coords > 0; - next_stroke++, num_coords--, curr_point_pair += 3) - { - next_stroke->x = curr_point_pair[0]; - next_stroke->y = curr_point_pair[1]; - next_stroke->pressure = 1.0; - next_stroke->xtilt = 0.5; - next_stroke->ytilt = 0.5; - next_stroke->wheel = 0.5; - - if (next_stroke != curr_coord && curr_point_pair[2] == 3.0) - break; - } - - num_stroke_coords = next_stroke - curr_coord; - - if (num_coords == 0 && ! pclosed) - num_stroke_coords++; - - { - GimpCoords temp_coords; - gint i; - - temp_coords = curr_coord[num_stroke_coords - 1]; - - for (i = num_stroke_coords - 1; i >= 0; i--) - curr_coord[i] = curr_coord[i - 1]; - - if (num_coords > 0 || pclosed) - curr_coord[0] = temp_coords; - else - curr_coord[0] = curr_coord[1]; - } - - stroke = gimp_bezier_stroke_new_from_coords (curr_coord, - num_stroke_coords, - num_coords > 0 || pclosed); - gimp_vectors_stroke_add (vectors, stroke); - g_object_unref (stroke); - - curr_coord = next_stroke; + points[i].x = curr_point_pair[0]; + points[i].y = curr_point_pair[1]; + points[i].type = curr_point_pair[2]; } - g_free (coords); + vectors = gimp_vectors_compat_new (gimage, pname, points, n_points, + closed); - gimp_image_add_vectors (gimage, vectors, 0); + g_free (points); + + if (vectors) + gimp_image_add_vectors (gimage, vectors, 0); + else + success = FALSE; } } diff --git a/app/vectors/Makefile.am b/app/vectors/Makefile.am index edbc3683c3..2359155382 100644 --- a/app/vectors/Makefile.am +++ b/app/vectors/Makefile.am @@ -22,6 +22,8 @@ libappvectors_a_SOURCES = \ gimpstroke.c \ gimpvectors.c \ gimpvectors.h \ + gimpvectors-compat.c \ + gimpvectors-compat.h \ gimpvectors-preview.c \ gimpvectors-preview.h diff --git a/app/vectors/gimpvectors-compat.c b/app/vectors/gimpvectors-compat.c new file mode 100644 index 0000000000..143e95ad21 --- /dev/null +++ b/app/vectors/gimpvectors-compat.c @@ -0,0 +1,223 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpvectors-compat.c + * Copyright (C) 2003 Michael Natterer + * + * 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 + +#include "vectors-types.h" + +#include "core/gimpimage.h" + +#include "gimpanchor.h" +#include "gimpbezierstroke.h" +#include "gimpvectors.h" +#include "gimpvectors-compat.h" + + +enum +{ + GIMP_VECTORS_COMPAT_ANCHOR = 1, + GIMP_VECTORS_COMPAT_CONTROL = 2, + GIMP_VECTORS_COMPAT_NEW_STROKE = 3 +}; + + + +GimpVectors * +gimp_vectors_compat_new (GimpImage *gimage, + const gchar *name, + GimpVectorsCompatPoint *points, + gint n_points, + gboolean closed) +{ + GimpVectors *vectors; + GimpStroke *stroke; + GimpCoords *coords; + GimpCoords *curr_stroke; + GimpCoords *curr_coord; + gint i; + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL); + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (points != NULL, NULL); + g_return_val_if_fail (n_points > 0, NULL); + + vectors = gimp_vectors_new (gimage, name); + + coords = g_new0 (GimpCoords, n_points + 1); + + curr_stroke = curr_coord = coords; + + /* skip the first control point, will set it later */ + curr_coord++; + + for (i = 0; i < n_points; i++) + { + curr_coord->x = points[i].x; + curr_coord->y = points[i].y; + curr_coord->pressure = 1.0; + curr_coord->xtilt = 0.5; + curr_coord->ytilt = 0.5; + curr_coord->wheel = 0.5; + + /* copy the first anchor to be the first control point */ + if (curr_coord == curr_stroke + 1) + *curr_stroke = *curr_coord; + + /* found new stroke start */ + if (points[i].type == GIMP_VECTORS_COMPAT_NEW_STROKE) + { + /* copy the last control point to the beginning of the stroke */ + *curr_stroke = *(curr_coord - 1); + + stroke = + gimp_bezier_stroke_new_from_coords (curr_stroke, + curr_coord - curr_stroke - 1, + TRUE); + gimp_vectors_stroke_add (vectors, stroke); + g_object_unref (stroke); + + /* start a new stroke */ + curr_stroke = curr_coord - 1; + + /* copy the first anchor to be the first control point */ + *curr_stroke = *curr_coord; + } + + curr_coord++; + } + + if (closed) + { + /* copy the last control point to the beginning of the stroke */ + curr_coord--; + *curr_stroke = *curr_coord; + } + + stroke = gimp_bezier_stroke_new_from_coords (curr_stroke, + curr_coord - curr_stroke , + closed); + gimp_vectors_stroke_add (vectors, stroke); + g_object_unref (stroke); + + g_free (coords); + + return vectors; +} + +GimpVectorsCompatPoint * +gimp_vectors_compat_get_points (GimpVectors *vectors, + guint32 *n_points, + guint32 *closed) +{ + GimpVectorsCompatPoint *points; + GList *strokes; + gint i; + + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); + g_return_val_if_fail (n_points != NULL, NULL); + g_return_val_if_fail (closed != NULL, NULL); + + *n_points = 0; + *closed = FALSE; + + for (strokes = vectors->strokes; strokes; strokes = g_list_next (strokes)) + { + GimpStroke *stroke = strokes->data; + gint n_anchors; + + if (! stroke->closed && strokes->next) + { + g_warning ("gimp_vectors_compat_get_points(): convert failed"); + + *n_points = 0; + + return NULL; + } + + n_anchors = g_list_length (stroke->anchors); + + if (! stroke->closed) + n_anchors--; + + *n_points += n_anchors; + + if (! strokes->next) + *closed = stroke->closed; + } + + points = g_new0 (GimpVectorsCompatPoint, *n_points); + + i = 0; + + for (strokes = vectors->strokes; + strokes; + strokes = g_list_next (strokes)) + { + GimpStroke *stroke = strokes->data; + GList *anchors; + + for (anchors = stroke->anchors; + anchors; + anchors = g_list_next (anchors)) + { + GimpAnchor *anchor = anchors->data; + + /* skip the first anchor, will add it at the end if needed */ + if (! anchors->prev) + continue; + + switch (anchor->type) + { + case GIMP_ANCHOR_ANCHOR: + if (strokes->prev && anchors->prev == stroke->anchors) + points[i].type = GIMP_VECTORS_COMPAT_NEW_STROKE; + else + points[i].type = GIMP_VECTORS_COMPAT_ANCHOR; + break; + + case GIMP_ANCHOR_CONTROL: + points[i].type = GIMP_VECTORS_COMPAT_CONTROL; + break; + } + + points[i].x = anchor->position.x; + points[i].y = anchor->position.y; + + i++; + + /* write the skipped control point */ + if (! anchors->next && stroke->closed) + { + anchor = (GimpAnchor *) stroke->anchors->data; + + points[i].type = GIMP_VECTORS_COMPAT_CONTROL; + points[i].x = anchor->position.x; + points[i].y = anchor->position.y; + + i++; + } + } + } + + return points; +} diff --git a/app/vectors/gimpvectors-compat.h b/app/vectors/gimpvectors-compat.h new file mode 100644 index 0000000000..2319d85143 --- /dev/null +++ b/app/vectors/gimpvectors-compat.h @@ -0,0 +1,47 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpvectors-compat.h + * Copyright (C) 2003 Michael Natterer + * + * 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. + */ + +#ifndef __GIMP_VECTORS_COMPAT_H__ +#define __GIMP_VECTORS_COMPAT_H__ + + +typedef struct _GimpVectorsCompatPoint GimpVectorsCompatPoint; + +struct _GimpVectorsCompatPoint +{ + guint32 type; + gdouble x; + gdouble y; +}; + + +GimpVectors * gimp_vectors_compat_new (GimpImage *gimage, + const gchar *name, + GimpVectorsCompatPoint *points, + gint n_points, + gboolean closed); + +GimpVectorsCompatPoint * gimp_vectors_compat_get_points (GimpVectors *vectors, + guint32 *n_points, + guint32 *closed); + + +#endif /* __GIMP_VECTORS_COMPAT_H__ */ diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index ba7fd42e43..cc5ac8d713 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -46,8 +46,8 @@ #include "core/gimpparasitelist.h" #include "core/gimpunit.h" -#include "vectors/gimpbezierstroke.h" #include "vectors/gimpvectors.h" +#include "vectors/gimpvectors-compat.h" #include "xcf-private.h" #include "xcf-load.h" @@ -57,55 +57,40 @@ #include "gimp-intl.h" -typedef struct _XcfPathPoint PathPoint; - -struct _XcfPathPoint -{ - guint32 type; - gdouble x; - gdouble y; -}; - - -static gboolean xcf_load_image_props (XcfInfo *info, - GimpImage *gimage); -static gboolean xcf_load_layer_props (XcfInfo *info, - GimpImage *gimage, - GimpLayer *layer, - gboolean *apply_mask, - gboolean *edit_mask, - gboolean *show_mask); -static gboolean xcf_load_channel_props (XcfInfo *info, - GimpImage *gimage, - GimpChannel *channel); -static gboolean xcf_load_prop (XcfInfo *info, - PropType *prop_type, - guint32 *prop_size); -static GimpLayer * xcf_load_layer (XcfInfo *info, - GimpImage *gimage); -static GimpChannel * xcf_load_channel (XcfInfo *info, - GimpImage *gimage); -static GimpLayerMask * xcf_load_layer_mask (XcfInfo *info, - GimpImage *gimage); -static gboolean xcf_load_hierarchy (XcfInfo *info, - TileManager *tiles); -static gboolean xcf_load_level (XcfInfo *info, - TileManager *tiles); -static gboolean xcf_load_tile (XcfInfo *info, - Tile *tile); -static gboolean xcf_load_tile_rle (XcfInfo *info, - Tile *tile, - gint data_length); -static GimpParasite * xcf_load_parasite (XcfInfo *info); -static gboolean xcf_load_old_paths (XcfInfo *info, - GimpImage *gimage); -static gboolean xcf_load_old_path (XcfInfo *info, - GimpImage *gimage); -static PathPoint * xcf_load_old_path_point1 (XcfInfo *info, - GimpCoords *coords); -static PathPoint * xcf_load_old_path_point (XcfInfo *info, - GimpCoords *coords); - +static gboolean xcf_load_image_props (XcfInfo *info, + GimpImage *gimage); +static gboolean xcf_load_layer_props (XcfInfo *info, + GimpImage *gimage, + GimpLayer *layer, + gboolean *apply_mask, + gboolean *edit_mask, + gboolean *show_mask); +static gboolean xcf_load_channel_props (XcfInfo *info, + GimpImage *gimage, + GimpChannel *channel); +static gboolean xcf_load_prop (XcfInfo *info, + PropType *prop_type, + guint32 *prop_size); +static GimpLayer * xcf_load_layer (XcfInfo *info, + GimpImage *gimage); +static GimpChannel * xcf_load_channel (XcfInfo *info, + GimpImage *gimage); +static GimpLayerMask * xcf_load_layer_mask (XcfInfo *info, + GimpImage *gimage); +static gboolean xcf_load_hierarchy (XcfInfo *info, + TileManager *tiles); +static gboolean xcf_load_level (XcfInfo *info, + TileManager *tiles); +static gboolean xcf_load_tile (XcfInfo *info, + Tile *tile); +static gboolean xcf_load_tile_rle (XcfInfo *info, + Tile *tile, + gint data_length); +static GimpParasite * xcf_load_parasite (XcfInfo *info); +static gboolean xcf_load_old_paths (XcfInfo *info, + GimpImage *gimage); +static gboolean xcf_load_old_path (XcfInfo *info, + GimpImage *gimage); #ifdef SWAP_FROM_FILE static gboolean xcf_swap_func (gint fd, @@ -1337,19 +1322,16 @@ static gboolean xcf_load_old_path (XcfInfo *info, GimpImage *gimage) { - gchar *name; - guint32 locked; - guint8 state; - guint32 closed; - guint32 num_points; - guint32 version; /* changed from num_paths */ - GimpTattoo tattoo = 0; - GSList *pts_list = NULL; - GSList *free_list = NULL; - GimpVectors *vectors; - GimpCoords *coords; - GimpCoords *curr_coord; - gint num_coords; + gchar *name; + guint32 locked; + guint8 state; + guint32 closed; + guint32 num_points; + guint32 version; /* changed from num_paths */ + GimpTattoo tattoo = 0; + GimpVectors *vectors; + GimpVectorsCompatPoint *points; + gint i; info->cp += xcf_read_string (info->fp, &name, 1); info->cp += xcf_read_int32 (info->fp, &locked, 1); @@ -1358,188 +1340,77 @@ xcf_load_old_path (XcfInfo *info, info->cp += xcf_read_int32 (info->fp, &num_points, 1); info->cp += xcf_read_int32 (info->fp, &version, 1); - g_print ("num_points: %d closed: %d\n", num_points, closed); - - vectors = gimp_vectors_new (gimage, name); - - GIMP_ITEM (vectors)->linked = locked; - - coords = g_new0 (GimpCoords, num_points + 1); - num_coords = num_points; - - curr_coord = coords; - - if (version == 1) - { - while (num_points-- > 0) - { - PathPoint *bpt; - /* Read in a path */ - bpt = xcf_load_old_path_point1 (info, curr_coord++); - pts_list = g_slist_append (pts_list, bpt); - } - } - else if (version == 2) + if (version == 2) { guint32 dummy; /* Had extra type field and points are stored as doubles */ info->cp += xcf_read_int32 (info->fp, (guint32 *) &dummy, 1); - - while (num_points-- > 0) - { - PathPoint *bpt; - /* Read in a path */ - bpt = xcf_load_old_path_point (info, curr_coord++); - pts_list = g_slist_append (pts_list, bpt); - } } else if (version == 3) { guint32 dummy; /* Has extra tatto field */ - info->cp += xcf_read_int32 (info->fp, (guint32 *) &dummy, 1); + info->cp += xcf_read_int32 (info->fp, (guint32 *) &dummy, 1); info->cp += xcf_read_int32 (info->fp, (guint32 *) &tattoo, 1); - - while (num_points-- > 0) - { - PathPoint *bpt; - /* Read in a path */ - bpt = xcf_load_old_path_point (info, curr_coord++); - pts_list = g_slist_append (pts_list, bpt); - } } - else + else if (version != 1) { g_warning ("Unknown path type. Possibly corrupt XCF file"); + + return FALSE; } - g_print ("\n"); - + g_print ("num_points: %d closed: %d\n", num_points, closed); + + points = g_new0 (GimpVectorsCompatPoint, num_points); + + for (i = 0; i < num_points; i++) + { + if (version == 1) + { + gint32 x; + gint32 y; + + info->cp += xcf_read_int32 (info->fp, &points[i].type, 1); + info->cp += xcf_read_int32 (info->fp, (guint32 *) &x, 1); + info->cp += xcf_read_int32 (info->fp, (guint32 *) &y, 1); + + points[i].x = x; + points[i].y = y; + } + else + { + gfloat x; + gfloat y; + + info->cp += xcf_read_int32 (info->fp, &points[i].type, 1); + info->cp += xcf_read_float (info->fp, &x, 1); + info->cp += xcf_read_float (info->fp, &y, 1); + + g_print ("path point type: %d (at %f, %f)\n", points[i].type, x, y); + + points[i].x = x; + points[i].y = y; + } + } + + vectors = gimp_vectors_compat_new (gimage, name, points, num_points, closed); + + g_free (points); + + GIMP_ITEM (vectors)->linked = locked; + if (tattoo) GIMP_ITEM (vectors)->tattoo = tattoo; - curr_coord = coords; - - free_list = pts_list; - - while (num_coords > 0) - { - GimpStroke *stroke; - GimpCoords *next_stroke; - gint num_stroke_coords; - - for (next_stroke = curr_coord; - num_coords > 0 && pts_list; - next_stroke++, num_coords--, pts_list = g_slist_next (pts_list)) - { - PathPoint *bpt = pts_list->data; - - if (next_stroke != curr_coord && bpt->type == 3) - break; - } - - num_stroke_coords = next_stroke - curr_coord; - - if (num_coords == 0 && ! closed) - num_stroke_coords++; - - { - GimpCoords temp_coords; - gint i; - - temp_coords = curr_coord[num_stroke_coords - 1]; - - for (i = num_stroke_coords - 1; i >= 0; i--) - curr_coord[i] = curr_coord[i - 1]; - - if (num_coords > 0 || closed) - curr_coord[0] = temp_coords; - else - curr_coord[0] = curr_coord[1]; - } - - stroke = gimp_bezier_stroke_new_from_coords (curr_coord, - num_stroke_coords, - num_coords > 0 || closed); - gimp_vectors_stroke_add (vectors, stroke); - g_object_unref (stroke); - - curr_coord = next_stroke; - } - - g_free (coords); - g_slist_foreach (free_list, (GFunc) g_free, NULL); - g_slist_free (free_list); - gimp_image_add_vectors (gimage, vectors, gimp_container_num_children (gimage->vectors)); return TRUE; } -static PathPoint* -xcf_load_old_path_point1 (XcfInfo *info, - GimpCoords *coords) -{ - PathPoint *ptr; - guint32 type; - gint32 x; - gint32 y; - - info->cp += xcf_read_int32 (info->fp, &type, 1); - info->cp += xcf_read_int32 (info->fp, (guint32 *) &x, 1); - info->cp += xcf_read_int32 (info->fp, (guint32 *) &y, 1); - - ptr = g_new0 (PathPoint, 1); - - ptr->type = type; - ptr->x = x; - ptr->y = y; - - coords->x = x; - coords->y = y; - coords->pressure = 1.0; - coords->xtilt = 0.5; - coords->ytilt = 0.5; - coords->wheel = 0.5; - - return ptr; -} - -static PathPoint * -xcf_load_old_path_point (XcfInfo *info, - GimpCoords *coords) -{ - PathPoint *ptr; - guint32 type; - gfloat x; - gfloat y; - - info->cp += xcf_read_int32 (info->fp, &type, 1); - info->cp += xcf_read_float (info->fp, &x, 1); - info->cp += xcf_read_float (info->fp, &y, 1); - - g_print ("path point type: %d (at %f, %f)\n", type, x, y); - - ptr = g_new0 (PathPoint, 1); - - ptr->type = type; - ptr->x = x; - ptr->y = y; - - coords->x = x; - coords->y = y; - coords->pressure = 1.0; - coords->xtilt = 0.5; - coords->ytilt = 0.5; - coords->wheel = 0.5; - - return ptr; -} - - #ifdef SWAP_FROM_FILE static gboolean diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c index 3f8b1762ed..a25ac4b920 100644 --- a/app/xcf/xcf-save.c +++ b/app/xcf/xcf-save.c @@ -43,9 +43,8 @@ #include "core/gimpparasitelist.h" #include "core/gimpunit.h" -#include "vectors/gimpanchor.h" -#include "vectors/gimpstroke.h" #include "vectors/gimpvectors.h" +#include "vectors/gimpvectors-compat.h" #include "xcf-private.h" #include "xcf-read.h" @@ -1407,22 +1406,23 @@ xcf_save_old_paths (XcfInfo *info, GIMP_OBJECT (active_vectors)); xcf_write_int32_check_error (info->fp, &active_index, 1); - xcf_write_int32_check_error (info->fp, &num_paths, 1); + xcf_write_int32_check_error (info->fp, &num_paths, 1); for (list = GIMP_LIST (gimage->vectors)->list; list; list = g_list_next (list)) { - GimpVectors *vectors = list->data; - gchar *name; - guint32 locked; - guint8 state; - guint32 num_points = 0; - guint32 closed = FALSE; - guint32 version; - guint32 pathtype; - guint32 tattoo; - GList *strokes; + GimpVectors *vectors = list->data; + gchar *name; + guint32 locked; + guint8 state; + guint32 num_points; + guint32 closed; + guint32 version; + guint32 pathtype; + guint32 tattoo; + GimpVectorsCompatPoint *points; + gint i; /* * name (string) @@ -1436,29 +1436,13 @@ xcf_save_old_paths (XcfInfo *info, * then each point. */ - for (strokes = vectors->strokes; strokes; strokes = g_list_next (strokes)) - { - GimpStroke *stroke = strokes->data; - gint n_anchors; - - g_assert (stroke->closed || ! strokes->next); - - n_anchors = g_list_length (stroke->anchors); - - if (! stroke->closed) - n_anchors--; - - num_points += n_anchors; - - if (! strokes->next) - closed = stroke->closed; - } + points = gimp_vectors_compat_get_points (vectors, &num_points, &closed); name = (gchar *) gimp_object_get_name (GIMP_OBJECT (vectors)); locked = gimp_item_get_linked (GIMP_ITEM (vectors)); - state = closed ? 4 : 2; + state = closed ? 4 : 2; /* EDIT : ADD (editing state, 1.2 compat) */ version = 3; - pathtype = 1; + pathtype = 1; /* BEZIER (1.2 compat) */ tattoo = gimp_item_get_tattoo (GIMP_ITEM (vectors)); xcf_write_string_check_error (info->fp, &name, 1); @@ -1470,67 +1454,26 @@ xcf_save_old_paths (XcfInfo *info, xcf_write_int32_check_error (info->fp, &pathtype, 1); xcf_write_int32_check_error (info->fp, &tattoo, 1); - for (strokes = vectors->strokes; - strokes; - strokes = g_list_next (strokes)) + for (i = 0; i < num_points; i++) { - GimpStroke *stroke = strokes->data; - GList *anchors; + gfloat x; + gfloat y; - for (anchors = stroke->anchors; - anchors; - anchors = g_list_next (anchors)) - { - GimpAnchor *anchor = anchors->data; - guint32 type; - gfloat x; - gfloat y; + x = points[i].x; + y = points[i].y; - /* skip the first anchor, will add it at the end if needed */ - if (! anchors->prev) - continue; + /* + * type (gint) + * x (gfloat) + * y (gfloat) + */ - /* type (gint32) - * x (float) - * y (float) - */ - - switch (anchor->type) - { - case GIMP_ANCHOR_ANCHOR: - if (strokes->prev && anchors->prev == stroke->anchors) - type = 3; /* new stroke marker */ - else - type = 1; /* ordinary anchor */ - break; - - case GIMP_ANCHOR_CONTROL: - type = 2; - break; - } - - x = anchor->position.x; - y = anchor->position.y; - - xcf_write_int32_check_error (info->fp, &type, 1); - xcf_write_float_check_error (info->fp, &x, 1); - xcf_write_float_check_error (info->fp, &y, 1); - - /* write the skipped control point */ - if (! anchors->next && stroke->closed) - { - anchor = (GimpAnchor *) stroke->anchors->data; - - type = 2; - x = anchor->position.x; - y = anchor->position.y; - - xcf_write_int32_check_error (info->fp, &type, 1); - xcf_write_float_check_error (info->fp, &x, 1); - xcf_write_float_check_error (info->fp, &y, 1); - } - } + xcf_write_int32_check_error (info->fp, &points[i].type, 1); + xcf_write_float_check_error (info->fp, &x, 1); + xcf_write_float_check_error (info->fp, &y, 1); } + + g_free (points); } return TRUE; diff --git a/tools/pdbgen/pdb/paths.pdb b/tools/pdbgen/pdb/paths.pdb index ce0490876f..10296ef586 100644 --- a/tools/pdbgen/pdb/paths.pdb +++ b/tools/pdbgen/pdb/paths.pdb @@ -99,7 +99,7 @@ HELP (type 1 paths) the type can either be (1.0 = BEZIER_ANCHOR, 2.0 = BEZIER_CONTROL). Note all points are returned in pixel resolution', - alias => 'points', init => 1, + init => 1, array => { name => 'num_path_point_details', desc => 'The number of points returned. Each point is made up of (x, y, pnt_type) of floats', @@ -114,79 +114,33 @@ HELP if (vectors) { - GList *list; - GimpStroke *stroke; - gdouble *curr_point; + GimpVectorsCompatPoint *points; - path_type = 1; - path_closed = FALSE; /* FIXME */ + path_type = 1; /* BEZIER (1.2 compat) */ - for (list = vectors->strokes; list; list = g_list_next (list)) + points = gimp_vectors_compat_get_points (vectors, &num_points, + &path_closed); + + if (points) { - gint num_anchors; + gdouble *curr_point; + gint i; - stroke = (GimpStroke *) list->data; + points_pairs = g_new0 (gdouble, num_points * 3); - num_anchors = g_list_length (stroke->anchors); - - if (list->next && (num_anchors % 3) != 0) - num_anchors++; - - num_points += num_anchors; - } - - points = g_new0 (gdouble, num_points * 3); - - curr_point = points; - - for (list = vectors->strokes; list; list = g_list_next (list)) - { - GList *anchors; - - stroke = (GimpStroke *) list->data; - - for (anchors = stroke->anchors; - anchors; - anchors = g_list_next (anchors)) + for (i = 0, curr_point = points_pairs; + i < num_points; + i++, curr_point += 3) { - GimpAnchor *anchor = anchors->data; - gdouble anchor_type = 1.0; - - switch (anchor->type) - { - case GIMP_ANCHOR_ANCHOR: - if (list->prev && ! anchors->prev) - anchor_type = 3.0; /* new stroke start */ - else - anchor_type = 1.0; /* ordinary anchor */ - break; - - case GIMP_ANCHOR_CONTROL: - anchor_type = 2.0; - break; - } - - curr_point[0] = anchor->position.x; - curr_point[1] = anchor->position.y; - curr_point[2] = anchor_type; - - curr_point += 3; - - /* FIXME */ - if (! anchors->next && list->next) - { - /* create a fake closed segment */ - - anchor = (GimpAnchor *) stroke->anchors->data; - - curr_point[0] = anchor->position.x; - curr_point[1] = anchor->position.y; - curr_point[2] = 2.0; - - curr_point += 3; - } + curr_point[0] = points[i].x; + curr_point[1] = points[i].y; + curr_point[2] = points[i].type; } + + g_free (points); } + else + success = FALSE; } else success = FALSE; @@ -306,83 +260,44 @@ HELP $inargs[0]->{desc} = 'The ID of the image to set the paths in'; %invoke = ( - vars => [ 'gboolean pclosed = FALSE' ], + vars => [ 'gboolean closed = FALSE' ], code => <<'CODE' { if ((num_path_points / 3) % 3 == 0) - pclosed = TRUE; + closed = TRUE; else if ((num_path_points / 3) % 3 != 2) success = FALSE; if (success) { - GimpVectors *vectors; - GimpCoords *coords; - GimpCoords *curr_coord; - gint num_coords; - gdouble *curr_point_pair; + GimpVectors *vectors; + gdouble *curr_point_pair; + GimpVectorsCompatPoint *points; + gint n_points; + gint i; - vectors = gimp_vectors_new (gimage, pname); + n_points = num_path_points / 3; - num_coords = num_path_points / 3; - coords = g_new0 (GimpCoords, num_coords + 1); + points = g_new0 (GimpVectorsCompatPoint, n_points); - curr_coord = coords; - curr_point_pair = points_pairs; - - while (num_coords > 0) + for (i = 0, curr_point_pair = points_pairs; + i < n_points; + i++, curr_point_pair += 3) { - GimpStroke *stroke; - GimpCoords *next_stroke; - gint num_stroke_coords; - - for (next_stroke = curr_coord; - num_coords > 0; - next_stroke++, num_coords--, curr_point_pair += 3) - { - next_stroke->x = curr_point_pair[0]; - next_stroke->y = curr_point_pair[1]; - next_stroke->pressure = 1.0; - next_stroke->xtilt = 0.5; - next_stroke->ytilt = 0.5; - next_stroke->wheel = 0.5; - - if (next_stroke != curr_coord && curr_point_pair[2] == 3.0) - break; - } - - num_stroke_coords = next_stroke - curr_coord; - - if (num_coords == 0 && ! pclosed) - num_stroke_coords++; - - { - GimpCoords temp_coords; - gint i; - - temp_coords = curr_coord[num_stroke_coords - 1]; - - for (i = num_stroke_coords - 1; i >= 0; i--) - curr_coord[i] = curr_coord[i - 1]; - - if (num_coords > 0 || pclosed) - curr_coord[0] = temp_coords; - else - curr_coord[0] = curr_coord[1]; - } - - stroke = gimp_bezier_stroke_new_from_coords (curr_coord, - num_stroke_coords, - num_coords > 0 || pclosed); - gimp_vectors_stroke_add (vectors, stroke); - g_object_unref (stroke); - - curr_coord = next_stroke; + points[i].x = curr_point_pair[0]; + points[i].y = curr_point_pair[1]; + points[i].type = curr_point_pair[2]; } - g_free (coords); + vectors = gimp_vectors_compat_new (gimage, pname, points, n_points, + closed); - gimp_image_add_vectors (gimage, vectors, 0); + g_free (points); + + if (vectors) + gimp_image_add_vectors (gimage, vectors, 0); + else + success = FALSE; } } CODE @@ -701,7 +616,7 @@ CODE "core/gimppaintinfo.h" "core/gimptoolinfo.h" "paint/gimppaintcore-stroke.h" "paint/gimppaintoptions.h" "vectors/gimpanchor.h" "vectors/gimpbezierstroke.h" - "vectors/gimpvectors.h"); + "vectors/gimpvectors.h" "vectors/gimpvectors-compat.h"); @procs = qw(path_list path_get_current path_set_current path_delete path_get_points path_set_points