app/vectors/Makefile.am new files implementing a compatibility API for

2003-05-22  Michael Natterer  <mitch@gimp.org>

	* 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.
This commit is contained in:
Michael Natterer 2003-05-22 19:02:38 +00:00 committed by Michael Natterer
parent 5beeeeb978
commit f7351b0bbb
9 changed files with 506 additions and 567 deletions

View File

@ -1,3 +1,25 @@
2003-05-22 Michael Natterer <mitch@gimp.org>
* 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 <sven@gimp.org>
* plug-ins/helpbrowser/Makefile.am

View File

@ -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) \

View File

@ -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;
}
}

View File

@ -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

View File

@ -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 <mitch@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 "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;
}

View File

@ -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 <mitch@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.
*/
#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__ */

View File

@ -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

View File

@ -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;

View File

@ -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