Changed:- Makefile.am internal_procs.c pathsP.h paths_dialog.c

Mon Mar 22 00:38:20 GMT 1999 Andy Thomas <alt@gimp.org>

	Changed:-
	* Makefile.am
	* internal_procs.c
	* pathsP.h
	* paths_dialog.c
	* paths_dialog.h
	* xcf.c

	New:-
	* paths_cmds.c
	* paths_cmds.h

	PDB functions for paths. (More to follow).
	Functions are:-
		gimp_path_list
		gimp_path_get_points
		gimp_path_get_current
		gimp_path_set_current
		gimp_path_set_points
		gimp_path_stroke_current
This commit is contained in:
GMT 1999 Andy Thomas
1999-03-22 00:51:30 +00:00
committed by Andy Thomas
parent 8b9d185c23
commit 4adf289ed6
12 changed files with 1593 additions and 344 deletions

View File

@ -1,3 +1,26 @@
Mon Mar 22 00:38:20 GMT 1999 Andy Thomas <alt@gimp.org>
Changed:-
* Makefile.am
* internal_procs.c
* pathsP.h
* paths_dialog.c
* paths_dialog.h
* xcf.c
New:-
* paths_cmds.c
* paths_cmds.h
PDB functions for paths. (More to follow).
Functions are:-
gimp_path_list
gimp_path_get_points
gimp_path_get_current
gimp_path_set_current
gimp_path_set_points
gimp_path_stroke_current
Sun Mar 21 15:29:38 GMT 1999 Adam D. Moss <adam@gimp.org>
* app/disp_callbacks.c app/edit_selection.c app/move.c:

View File

@ -276,6 +276,8 @@ gimp_SOURCES = \
parasitelist.h \
parasitelistF.h \
parasitelistP.h \
paths_cmds.c \
paths_cmds.h \
paths_dialog.h \
paths_dialog.c \
pathsP.h \

View File

@ -99,7 +99,7 @@ static PATHSLISTP paths_dialog = NULL;
typedef struct {
GdkPixmap *paths_pixmap;
GString *text;
BZPATHP bzp;
PATHP bzp;
} PATHWIDGET, *PATHWIDGETP;
static gint path_widget_preview_events (GtkWidget *, GdkEvent *);
@ -116,8 +116,8 @@ static void paths_dialog_stroke_path_callback(GtkWidget *w,gpointer client_data)
static void paths_dialog_path_to_sel_callback(GtkWidget *w,gpointer client_data);
static void paths_dialog_destroy_cb (GimpImage *image);
static void paths_update_paths(gpointer data,gint row);
static GSList * bzpoints_copy(GSList *list);
static void bzpoints_free(GSList *list);
static GSList * pathpoints_copy(GSList *list);
static void pathpoints_free(GSList *list);
static void paths_update_preview(BezierSelect *bezier_sel);
static void paths_dialog_preview_extents (void);
static void paths_dialog_new_point_callback (GtkWidget *, gpointer);
@ -369,33 +369,34 @@ clear_pathwidget(gpointer data)
}
static void
bzpoint_free(gpointer data,gpointer user_data)
pathpoint_free(gpointer data,gpointer user_data)
{
BZPOINTP bzpoint = data;
g_free(bzpoint);
PATHPOINTP pathpoint = data;
g_free(pathpoint);
}
static void
bzpath_free(gpointer data,gpointer user_data)
path_free(gpointer data,gpointer user_data)
{
BZPATHP bzp = data;
PATHP bzp = data;
g_return_if_fail(bzp != NULL);
g_string_free(bzp->name,TRUE);
bzpoints_free(bzp->bezier_details);
pathpoints_free(bzp->path_details);
g_free(bzp);
}
static BZPATHP
static PATHP
bzpath_dialog_new(gint name_seed, gpointer udata)
{
BZPATHP bzp = g_new0(BZPATH,1);
PATHP bzp = g_new0(PATH,1);
GString *s = g_string_new (NULL);
g_string_sprintf (s, "path %d",name_seed);
bzp->pathtype = BEZIER;
bzp->name = s;
bzp->bezier_details = (GSList *)udata; /* If called via button/menu this will be NULL */
bzp->path_details = (GSList *)udata; /* If called via button/menu this will be NULL */
return bzp;
}
@ -452,7 +453,7 @@ unique_name(gchar *cstr)
while(tlist)
{
gchar *test_str = ((BZPATHP)(tlist->data))->name->str;
gchar *test_str = ((PATHP)(tlist->data))->name->str;
if(strcmp(cstr,test_str) == 0)
{
unique = FALSE;
@ -476,7 +477,7 @@ unique_name(gchar *cstr)
while(tlist)
{
copy_test = ((BZPATHP)(tlist->data))->name->str;
copy_test = ((PATHP)(tlist->data))->name->str;
if(strcmp(copy_cstr,copy_test) == 0)
{
g_free(copy_cstr);
@ -491,51 +492,52 @@ unique_name(gchar *cstr)
return copy_cstr;
}
static BZPATHP
bzpath_copy(BZPATHP bzp)
static PATHP
path_copy(PATHP p)
{
BZPATHP bzp_copy = g_new0(BZPATH,1);
PATHP p_copy = g_new0(PATH,1);
gchar *ext;
ext = unique_name(bzp->name->str);
bzp_copy->name = g_string_new(ext);
ext = unique_name(p->name->str);
p_copy->name = g_string_new(ext);
g_free(ext);
bzp_copy->closed = bzp->closed;
bzp_copy->state = bzp->state;
bzp_copy->bezier_details = bzpoints_copy(bzp->bezier_details);
p_copy->closed = p->closed;
p_copy->state = p->state;
p_copy->pathtype = p->pathtype;
p_copy->path_details = pathpoints_copy(p->path_details);
return bzp_copy;
return p_copy;
}
static void
bzpath_close(BZPATHP bzp)
path_close(PATHP bzp)
{
BZPOINTP pdata;
BZPOINTP bzpoint;
PATHPOINTP pdata;
PATHPOINTP pathpoint;
/* bzpaths are only really closed when converted to the BezierSelect ones */
bzp->closed = 1;
/* first point */
pdata = (BZPOINTP)bzp->bezier_details->data;
pdata = (PATHPOINTP)bzp->path_details->data;
if(g_slist_length(bzp->bezier_details) < 5)
if(g_slist_length(bzp->path_details) < 5)
{
int i;
for (i = 0 ; i < 2 ; i++)
{
bzpoint = g_new0(BZPOINT,1);
bzpoint->type = (i & 1)?BEZIER_ANCHOR:BEZIER_CONTROL;
bzpoint->x = pdata->x+i;
bzpoint->y = pdata->y+i;
bzp->bezier_details = g_slist_append(bzp->bezier_details,bzpoint);
pathpoint = g_new0(PATHPOINT,1);
pathpoint->type = (i & 1)?BEZIER_ANCHOR:BEZIER_CONTROL;
pathpoint->x = pdata->x+i;
pathpoint->y = pdata->y+i;
bzp->path_details = g_slist_append(bzp->path_details,pathpoint);
}
}
bzpoint = g_new0(BZPOINT,1);
pdata = (BZPOINTP)bzp->bezier_details->data;
bzpoint->type = BEZIER_CONTROL;
bzpoint->x = pdata->x;
bzpoint->y = pdata->y;
bzp->bezier_details = g_slist_append(bzp->bezier_details,bzpoint);
pathpoint = g_new0(PATHPOINT,1);
pdata = (PATHPOINTP)bzp->path_details->data;
pathpoint->type = BEZIER_CONTROL;
pathpoint->x = pdata->x;
pathpoint->y = pdata->y;
bzp->path_details = g_slist_append(bzp->path_details,pathpoint);
}
static void
@ -546,17 +548,17 @@ beziersel_free(BezierSelect *bezier_sel)
}
static BezierSelect *
bzpath_to_beziersel(BZPATHP bzp)
path_to_beziersel(PATHP bzp)
{
BezierSelect *bezier_sel;
GSList *list;
if(!bzp)
{
g_warning("bzpath_to_beziersel:: NULL bzp");
g_warning("path_to_beziersel:: NULL bzp");
}
list = bzp->bezier_details;
list = bzp->path_details;
bezier_sel = g_new0 (BezierSelect,1);
bezier_sel->num_points = 0;
@ -569,9 +571,9 @@ bzpath_to_beziersel(BZPATHP bzp)
while(list)
{
BZPOINTP pdata;
pdata = (BZPOINTP)list->data;
bezier_add_point(bezier_sel,pdata->type,pdata->x,pdata->y);
PATHPOINTP pdata;
pdata = (PATHPOINTP)list->data;
bezier_add_point(bezier_sel,(gint)pdata->type,(gint)pdata->x,pdata->y);
list = g_slist_next(list);
}
@ -592,7 +594,7 @@ pathimagelist_free(PATHIMAGELISTP iml)
g_return_if_fail(iml != NULL);
if(iml->bz_paths)
{
g_slist_foreach(iml->bz_paths,bzpath_free,NULL);
g_slist_foreach(iml->bz_paths,path_free,NULL);
g_slist_free(iml->bz_paths);
}
g_free(iml);
@ -664,7 +666,7 @@ clear_pixmap_preview(PATHWIDGETP pwidget)
}
/* insrow == -1 -> append else insert at insrow */
void paths_add_path(BZPATHP bzp,gint insrow)
void paths_add_path(PATHP bzp,gint insrow)
{
/* Create a new entry in the list */
PATHWIDGETP pwidget;
@ -826,7 +828,7 @@ paths_select_row(GtkWidget *widget,
gpointer data)
{
PATHWIDGETP pwidget;
BZPATHP bzp;
PATHP bzp;
BezierSelect * bsel;
GDisplay *gdisp;
@ -841,11 +843,11 @@ paths_select_row(GtkWidget *widget,
paths_dialog->current_path_list->last_selected_row = row;
paths_dialog->been_selected = TRUE;
bzp = (BZPATHP)g_slist_nth_data(paths_dialog->current_path_list->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(paths_dialog->current_path_list->bz_paths,row);
g_return_if_fail(bzp != NULL);
bsel = bzpath_to_beziersel(bzp);
bsel = path_to_beziersel(bzp);
gdisp = gdisplays_check_valid(paths_dialog->current_path_list->gdisp,
paths_dialog->gimage);
if(!gdisp)
@ -992,12 +994,12 @@ paths_dialog_update (GimpImage* gimage)
static void
paths_update_paths(gpointer data,gint row)
{
BZPATHP bzp;
PATHP bzp;
BezierSelect * bezier_sel;
paths_add_path((bzp = (BZPATHP)data),-1);
paths_add_path((bzp = (PATHP)data),-1);
/* Now fudge the drawing....*/
bezier_sel = bzpath_to_beziersel(bzp);
bezier_sel = path_to_beziersel(bzp);
paths_dialog->current_path_list->last_selected_row = row;
paths_update_preview(bezier_sel);
beziersel_free(bezier_sel);
@ -1121,7 +1123,7 @@ paths_list_events (GtkWidget *widget,
}
static PATHIMAGELISTP
bzpath_add_to_current(PATHIMAGELISTP pip,BZPATHP bzp,GimpImage *gimage,gint pos)
path_add_to_current(PATHIMAGELISTP pip,PATHP bzp,GimpImage *gimage,gint pos)
{
/* add bzp to current list */
if(!pip)
@ -1141,29 +1143,38 @@ bzpath_add_to_current(PATHIMAGELISTP pip,BZPATHP bzp,GimpImage *gimage,gint pos)
return pip;
}
static BZPATHP
static PATHP
paths_dialog_new_path(PATHIMAGELISTP *plp,gpointer points,GimpImage *gimage,gint pos)
{
static gint nseed = 0;
BZPATHP bzp = bzpath_dialog_new(nseed++,points);
*plp = bzpath_add_to_current(*plp,bzp,gimage,pos);
PATHP bzp = bzpath_dialog_new(nseed++,points);
*plp = path_add_to_current(*plp,bzp,gimage,pos);
return(bzp);
}
static void
paths_dialog_new_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp = paths_dialog_new_path(&paths_dialog->current_path_list,
PATHP bzp = paths_dialog_new_path(&paths_dialog->current_path_list,
NULL,
paths_dialog->gimage,
paths_dialog->selected_row_num);
paths_add_path(bzp,paths_dialog->selected_row_num);
/* Enable the buttons!*/
paths_ops_button_set_sensitive(DUP_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(DEL_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(STROKE_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(PATH_TO_SEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_NEW_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_DEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_ADD_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_EDIT_BUTTON,TRUE);
}
static void
paths_dialog_delete_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
gboolean new_sz;
gint row = paths_dialog->selected_row_num;
@ -1176,12 +1187,12 @@ paths_dialog_delete_path_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure & delete its content */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Remove from list */
plp->bz_paths = g_slist_remove(plp->bz_paths,bzp);
new_sz = (g_slist_length(plp->bz_paths) > 0);
bzpath_free(bzp,NULL);
path_free(bzp,NULL);
/* If now empty free everything up */
if(!plp->bz_paths || g_slist_length(plp->bz_paths) == 0)
@ -1210,7 +1221,7 @@ paths_dialog_delete_path_callback (GtkWidget * widget, gpointer udata)
static void
paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
BezierSelect * bezier_sel;
gint row = paths_dialog->selected_row_num;
@ -1224,15 +1235,15 @@ paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Insert at the current position */
bzp = bzpath_copy(bzp);
bzp = path_copy(bzp);
plp->bz_paths = g_slist_insert(plp->bz_paths,bzp,row);
paths_add_path(bzp,row);
/* Now fudge the drawing....*/
bezier_sel = bzpath_to_beziersel(bzp);
bezier_sel = path_to_beziersel(bzp);
tmprow = paths_dialog->current_path_list->last_selected_row;
paths_dialog->current_path_list->last_selected_row = row;
paths_update_preview(bezier_sel);
@ -1243,7 +1254,7 @@ paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
static void
paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
BezierSelect * bezier_sel;
GDisplay * gdisp;
@ -1257,7 +1268,7 @@ paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Now do the stroke....*/
gdisp = gdisplays_check_valid(paths_dialog->current_path_list->gdisp,
@ -1265,17 +1276,17 @@ paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
if(!bzp->closed)
{
BZPATHP bzpcopy = bzpath_copy(bzp);
PATHP bzpcopy = path_copy(bzp);
/* Close it */
bzpath_close(bzpcopy);
bezier_sel = bzpath_to_beziersel(bzpcopy);
bzpath_free(bzpcopy,NULL);
path_close(bzpcopy);
bezier_sel = path_to_beziersel(bzpcopy);
path_free(bzpcopy,NULL);
bezier_to_selection (bezier_sel, gdisp);
beziersel_free(bezier_sel);
}
else
{
bezier_sel = bzpath_to_beziersel(bzp);
bezier_sel = path_to_beziersel(bzp);
bezier_to_selection (bezier_sel, gdisp);
beziersel_free(bezier_sel);
}
@ -1284,10 +1295,8 @@ paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
static void
paths_dialog_stroke_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
BezierSelect * bezier_sel;
GDisplay * gdisp;
gint row = paths_dialog->selected_row_num;
g_return_if_fail(paths_dialog->current_path_list != NULL);
@ -1298,14 +1307,10 @@ paths_dialog_stroke_path_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Now do the stroke....*/
gdisp = gdisplays_check_valid(paths_dialog->current_path_list->gdisp,
paths_dialog->gimage);
bezier_sel = bzpath_to_beziersel(bzp);
bezier_stroke (bezier_sel, gdisp, SUBDIVIDE, !bzp->closed);
beziersel_free(bezier_sel);
paths_stroke(paths_dialog->gimage,paths_dialog->current_path_list,bzp);
}
static void
@ -1368,45 +1373,45 @@ paths_dialog_destroy_cb (GimpImage *gimage)
/* Functions used from the bezier code .. tie in with this code */
static void
bzpoints_free(GSList *list)
pathpoints_free(GSList *list)
{
if(!list)
return;
g_slist_foreach(list,bzpoint_free,NULL);
g_slist_foreach(list,pathpoint_free,NULL);
g_slist_free(list);
}
static GSList *
bzpoints_create(BezierSelect *sel)
pathpoints_create(BezierSelect *sel)
{
gint i;
GSList *list = NULL;
BZPOINTP bzpoint;
PATHPOINTP pathpoint;
BezierPoint *pts = (BezierPoint *) sel->points;
for (i=0; i< sel->num_points; i++)
{
bzpoint = bzpoint_new(pts->type,pts->x,pts->y);
list = g_slist_append(list,bzpoint);
pathpoint = pathpoint_new(pts->type,(gdouble)pts->x,(gdouble)pts->y);
list = g_slist_append(list,pathpoint);
pts = pts->next;
}
return(list);
}
static GSList *
bzpoints_copy(GSList *list)
pathpoints_copy(GSList *list)
{
GSList *slcopy = NULL;
BZPOINTP pdata;
BZPOINTP bzpoint;
PATHPOINTP pdata;
PATHPOINTP pathpoint;
while(list)
{
bzpoint = g_new0(BZPOINT,1);
pdata = (BZPOINTP)list->data;
bzpoint->type = pdata->type;
bzpoint->x = pdata->x;
bzpoint->y = pdata->y;
slcopy = g_slist_append(slcopy,bzpoint);
pathpoint = g_new0(PATHPOINT,1);
pdata = (PATHPOINTP)list->data;
pathpoint->type = pdata->type;
pathpoint->x = pdata->x;
pathpoint->y = pdata->y;
slcopy = g_slist_append(slcopy,pathpoint);
list = g_slist_next(list);
}
return slcopy;
@ -1415,16 +1420,16 @@ bzpoints_copy(GSList *list)
static void
paths_update_bzpath(PATHIMAGELISTP plp,BezierSelect *bezier_sel)
{
BZPATHP bzp;
PATHP p;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,plp->last_selected_row);
p = (PATHP)g_slist_nth_data(plp->bz_paths,plp->last_selected_row);
if(bzp->bezier_details)
bzpoints_free(bzp->bezier_details);
if(p->path_details)
pathpoints_free(p->path_details);
bzp->bezier_details = bzpoints_create(bezier_sel);
bzp->closed = bezier_sel->closed;
bzp->state = bezier_sel->state;
p->path_details = pathpoints_create(bezier_sel);
p->closed = bezier_sel->closed;
p->state = bezier_sel->state;
}
static gboolean
@ -1570,7 +1575,7 @@ paths_first_button_press(BezierSelect *bezier_sel,GDisplay * gdisp)
All this of course depends on the fact that gdisp is the same
as before.
*/
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
if(paths_dialog)
@ -1589,7 +1594,7 @@ paths_first_button_press(BezierSelect *bezier_sel,GDisplay * gdisp)
if(!paths_replaced_current(plp,bezier_sel))
{
bzp = paths_dialog_new_path(&plp,bzpoints_create(bezier_sel),gdisp->gimage,-1);
bzp = paths_dialog_new_path(&plp,pathpoints_create(bezier_sel),gdisp->gimage,-1);
bzp->closed = bezier_sel->closed;
bzp->state = bezier_sel->state;
if(paths_dialog && paths_dialog->gimage == gdisp->gimage)
@ -1641,35 +1646,37 @@ paths_new_bezier_select_tool()
/**************************************************************/
BZPOINTP
bzpoint_new(gint type,
gint x,
gint y)
PATHPOINTP
pathpoint_new(gint type,
gdouble x,
gdouble y)
{
BZPOINTP bzpoint = g_new0(BZPOINT,1);
PATHPOINTP pathpoint = g_new0(PATHPOINT,1);
bzpoint->type = type;
bzpoint->x = x;
bzpoint->y = y;
return(bzpoint);
pathpoint->type = type;
pathpoint->x = x;
pathpoint->y = y;
return(pathpoint);
}
BZPATHP
bzpath_new(GSList * bezier_details,
PATHP
path_new(PathType ptype,
GSList * path_details,
gint closed,
gint state,
gint locked,
gchar * name)
{
BZPATHP bzpath = g_new0(BZPATH,1);
PATHP path = g_new0(PATH,1);
bzpath->bezier_details = bezier_details;
bzpath->closed = closed;
bzpath->state = state;
bzpath->locked = locked;
bzpath->name = g_string_new(name);
path->path_details = path_details;
path->closed = closed;
path->state = state;
path->locked = locked;
path->name = g_string_new(name);
path->pathtype = ptype;
return bzpath;
return path;
}
PathsList *
@ -1700,22 +1707,22 @@ pathsList_new(GimpImage * gimage,
static GtkWidget *file_dlg = 0;
static int load_store;
static void path_write_current_to_file(FILE *f,BZPATHP bzp)
static void path_write_current_to_file(FILE *f,PATHP bzp)
{
GSList *list = bzp->bezier_details;
BZPOINTP pdata;
GSList *list = bzp->path_details;
PATHPOINTP pdata;
fprintf(f, "Name: %s\n", bzp->name->str);
fprintf(f, "#POINTS: %d\n", g_slist_length(bzp->bezier_details));
fprintf(f, "#POINTS: %d\n", g_slist_length(bzp->path_details));
fprintf(f, "CLOSED: %d\n", bzp->closed==1?1:0);
fprintf(f, "DRAW: %d\n", 0);
fprintf(f, "STATE: %d\n", bzp->state);
while(list)
{
pdata = (BZPOINTP)list->data;
fprintf(f,"TYPE: %d X: %d Y: %d\n", pdata->type, pdata->x, pdata->y);
pdata = (PATHPOINTP)list->data;
fprintf(f,"TYPE: %d X: %d Y: %d\n", pdata->type, (gint)pdata->x, (gint)pdata->y);
list = g_slist_next(list);
}
}
@ -1726,7 +1733,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
GtkFileSelection *fs;
FILE *f;
char* filename;
BZPATHP bzpath;
PATHP bzpath;
GSList * pts_list = NULL;
PATHIMAGELISTP plp;
gint row = paths_dialog->selected_row_num;
@ -1769,7 +1776,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
for(i=0; i< val; i++)
{
BZPOINTP bpt;
PATHPOINTP bpt;
readfields = fscanf(f,"TYPE: %d X: %d Y: %d\n", &type, &x, &y);
if(readfields != 3)
{
@ -1777,20 +1784,21 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
gtk_widget_hide (file_dlg);
return;
}
bpt = bzpoint_new(type, x, y);
bpt = pathpoint_new(type, (gdouble)x, (gdouble)y);
pts_list = g_slist_append(pts_list,bpt);
}
bzpath = bzpath_new(pts_list,
closed,
state,
0, /* Can't be locked */
txt);
bzpath = path_new(BEZIER,
pts_list,
closed,
state,
0, /* Can't be locked */
txt);
g_free(txtstart);
paths_dialog->current_path_list =
bzpath_add_to_current(paths_dialog->current_path_list,
path_add_to_current(paths_dialog->current_path_list,
bzpath,
paths_dialog->gimage,
row);
@ -1813,7 +1821,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
}
else
{
BZPATHP bzp;
PATHP bzp;
/* Get current selection... ignore if none */
if(paths_dialog->selected_row_num < 0)
@ -1821,7 +1829,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
f = fopen(filename, "wb");
if (NULL == f)
@ -1905,3 +1913,212 @@ paths_dialog_export_path_callback (GtkWidget * widget, gpointer udata)
/* Export the path to a file */
path_store_callback();
}
/*************************************/
/* PDB function aids */
/*************************************/
/* Return TRUE if setting the path worked, else false */
gboolean
paths_set_path(GimpImage * gimage,
gchar * pname)
{
gint row = 0;
gboolean found = FALSE;
GSList *tlist;
PATHIMAGELISTP plp;
/* Get bzpath structure */
plp = (PATHIMAGELISTP)gimp_image_get_paths(gimage);
if(!plp)
return FALSE;
tlist = plp->bz_paths;
while(tlist)
{
gchar *test_str = ((PATHP)(tlist->data))->name->str;
if(strcmp(pname,test_str) == 0)
{
found = TRUE;
break;
}
row++;
tlist = g_slist_next(tlist);
}
if(!found)
return FALSE;
if(paths_dialog)
{
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
row,
0);
}
else
{
plp->last_selected_row = row;
}
return TRUE;
}
/* Set a path with the given set of points. */
/* We assume that there are enough points */
/* Return TRUE if path created OK. */
gboolean
paths_set_path_points(GimpImage * gimage,
gchar * pname,
gint ptype,
gint pclosed,
gint num_pnts,
gdouble * pnts)
{
PathsList *plist = gimp_image_get_paths(gimage);
GSList *pts_list = NULL;
PATHP bzpath;
gint pcount = 0;
if(num_pnts < 6 ||
(pclosed && ((num_pnts/2) % 3)) ||
(!pclosed && ((num_pnts/2) % 3) != 2))
{
g_warning(_("wrong number of points\n"));
return FALSE;
}
if(ptype != BEZIER)
ptype = BEZIER;
while(num_pnts)
{
PATHPOINTP bpt;
gint type;
gdouble x;
gdouble y;
if((pcount/2)%3)
type = BEZIER_CONTROL;
else
type = BEZIER_ANCHOR;
x = pnts[pcount++];
y = pnts[pcount++];
/* printf("New point type = %s, x = %d y= %d\n", */
/* (type==BEZIER_CONTROL)?"CNTL":"ANCH", */
/* (int)x, */
/* (int)y); */
bpt = pathpoint_new(type, (gdouble)x, (gdouble)y);
pts_list = g_slist_append(pts_list,bpt);
num_pnts -= 2;
}
if(!plist)
{
GSList *bzp_list = NULL;
/* No paths at all.... create one & rename */
bzpath = path_new(ptype,
pts_list,
pclosed,
(pclosed)?BEZIER_EDIT:BEZIER_ADD,/*state,*/
0, /* Can't be locked */
pname);
bzp_list = g_slist_append(bzp_list,bzpath);
plist = pathsList_new(gimage,0,bzp_list);
gimp_image_set_paths(gimage,plist);
}
else
{
GSList *tlist;
PATHP pp = NULL;
gint row = 0;
/* Check if name already exists.. if so delete all points assoc with it
* if not create a new one with the passed name.
*/
tlist = plist->bz_paths;
while(tlist)
{
gchar *test_str = ((PATHP)(tlist->data))->name->str;
if(strcmp(pname,test_str) == 0)
{
pp = (PATHP)(tlist->data);
break;
}
tlist = g_slist_next(tlist);
row++;
}
if(pp)
{
pathpoints_free(pp->path_details);
pp->path_details = pts_list;
pp->pathtype = ptype;
pp->closed = pclosed;
pp->locked = 0;
if(paths_dialog)
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
row,
0);
return TRUE;
}
else
{
bzpath = path_new(ptype,
pts_list,
pclosed,
(pclosed)?BEZIER_EDIT:BEZIER_ADD,/*state,*/
0, /* Can't be locked */
pname);
path_add_to_current(plist,bzpath,gimage,-1);
}
}
if(paths_dialog)
{
paths_dialog->current_path_list =
path_add_to_current(paths_dialog->current_path_list,
bzpath,
paths_dialog->gimage,
0);
paths_add_path(bzpath,0);
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
paths_dialog->current_path_list->last_selected_row,
0);
paths_ops_button_set_sensitive(DUP_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(DEL_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(STROKE_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(PATH_TO_SEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_ADD_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_DEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_NEW_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_EDIT_BUTTON,TRUE);
}
return TRUE;
}
void
paths_stroke(GimpImage *gimage,PathsList *pl,PATHP bzp)
{
BezierSelect * bezier_sel;
GDisplay * gdisp;
gdisp = gdisplays_check_valid(pl->gdisp,gimage);
bezier_sel = path_to_beziersel(bzp);
bezier_stroke (bezier_sel, gdisp, SUBDIVIDE, !bzp->closed);
beziersel_free(bezier_sel);
}

View File

@ -25,7 +25,7 @@ void paths_dialog_update (GimpImage*);
void paths_newpoint_current(BezierSelect *, GDisplay *);
void paths_first_button_press(BezierSelect *,GDisplay *);
void paths_new_bezier_select_tool(void);
BZPATHP paths_get_bzpaths(void);
void paths_set_bzpaths(GImage*,BZPATHP);
PATHP paths_get_bzpaths(void);
void paths_set_bzpaths(GImage*,PATHP);
#endif /* __PATHS_DIALOG_H__ */

View File

@ -60,6 +60,7 @@
#include "internal_procs.h"
#include "paintbrush.h"
#include "palette.h"
#include "paths_cmds.h"
#include "patterns.h"
#include "pattern_select.h"
#include "pencil.h"
@ -82,7 +83,7 @@ internal_procs_init ()
{
gfloat pcount = 0;
/* grep -c procedural_db_register internal_procs.c */
gfloat total_pcount = 258;
gfloat total_pcount = 264;
app_init_update_status(_("Internal Procedures"), _("Tool procedures"),
pcount/total_pcount);
@ -421,6 +422,15 @@ internal_procs_init ()
procedural_db_register (&gimp_attach_parasite_proc); pcount++;
procedural_db_register (&gimp_detach_parasite_proc); pcount++;
/* paths procedures */
procedural_db_register (&path_list_proc); pcount++;
procedural_db_register (&path_get_points_proc); pcount++;
procedural_db_register (&path_get_current_proc); pcount++;
procedural_db_register (&path_set_current_proc); pcount++;
procedural_db_register (&path_set_points_proc); pcount++;
procedural_db_register (&path_stroke_current_proc); pcount++;
app_init_update_status(NULL, _("Procedural database"),
pcount/total_pcount);

View File

@ -24,17 +24,18 @@
typedef struct {
guint32 type;
gint32 x;
gint32 y;
} BZPOINT, *BZPOINTP;
gdouble x;
gdouble y;
} PATHPOINT, *PATHPOINTP;
typedef struct {
GSList * bezier_details;
gboolean closed;
guint32 state;
guint32 locked; /* Only bottom bit used */
GSList * path_details;
guint32 pathtype; /* Only beziers to start with */
gboolean closed;
guint32 state;
guint32 locked; /* Only bottom bit used */
GString * name;
} BZPATH, *BZPATHP;
} PATH, *PATHP;
typedef struct {
GimpImage * gimage;
@ -52,8 +53,16 @@ typedef struct {
gint32 last_selected_row;
} PATHIMAGELIST, *PATHIMAGELISTP, PathsList;
BZPOINTP bzpoint_new(gint,gint,gint);
BZPATHP bzpath_new(GSList *,gint,gint,gint,gchar *);
PathsList * pathsList_new(GimpImage *,gint,GSList *);
typedef enum {
BEZIER = 1,
} PathType;
PATHPOINTP pathpoint_new(gint,gdouble,gdouble);
PATHP path_new(PathType,GSList *,gint,gint,gint,gchar *);
PathsList * pathsList_new(GimpImage *,gint,GSList *);
gboolean paths_set_path(GimpImage *,gchar *);
gboolean paths_set_path_points(GimpImage *,gchar *,gint,gint,gint,gdouble *);
void paths_stroke(GimpImage *,PathsList *,PATHP);
#endif /* __PATHSP_H__ */

656
app/paths_cmds.c Normal file
View File

@ -0,0 +1,656 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1999 Andy Thomas alt@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.
* Some of this code is based on the layers_dialog box code.
*/
#include <stdio.h>
#include <stdlib.h>
#include "appenv.h"
#include "general.h"
#include "gimage.h"
#include "pathsP.h"
#include "paths_cmds.h"
#include "libgimp/gimpintl.h"
static int success;
/* These are the PDB functions that interact with the PATHS structures. */
/* List the paths that an image has */
static Argument *
path_list_invoker (Argument *args)
{
Argument *return_args;
gchar **paths_list;
gint num_paths;
GImage *gimage;
gint int_value;
gimage = NULL;
success = TRUE;
if (success)
{
int_value = args[0].value.pdb_int;
if ((gimage = gimage_get_ID (int_value)) == NULL)
success = FALSE;
}
return_args = procedural_db_return_args (&path_list_proc, success);
if (success)
{
PathsList *plist = gimage->paths;
if(plist && plist->bz_paths)
{
gint count = 0;
GSList *pl = plist->bz_paths;
num_paths = g_slist_length(plist->bz_paths);
return_args[1].value.pdb_int = num_paths;
paths_list = g_malloc(sizeof(gchar *) * num_paths);
while(pl)
{
PATHP pptr = pl->data;
paths_list[count++] = g_strdup(pptr->name->str);
pl = g_slist_next(pl);
}
return_args[2].value.pdb_pointer = paths_list;
}
else
{
return_args[1].value.pdb_int = 0;
return_args[2].value.pdb_pointer = NULL;
}
}
return return_args;
}
/* The procedure definition */
ProcArg path_list_in_args[] =
{
{ PDB_IMAGE,
"image",
"the image to list the paths from"
},
};
ProcArg path_list_out_args[] =
{
{ PDB_INT32,
"num_paths",
"The number of paths returned"
},
{ PDB_STRINGARRAY,
"paths_list",
"list of the paths belonging to this image"
}
};
ProcRecord path_list_proc =
{
"gimp_path_list",
"List the paths associated with the passed image",
"List the paths associated with the passed image",
"Andy Thomas",
"Andy Thomas",
"1999",
PDB_INTERNAL,
/* Input arguments */
sizeof(path_list_in_args)/sizeof(path_list_in_args[0]),
path_list_in_args,
/* Output arguments */
sizeof(path_list_out_args)/sizeof(path_list_out_args[0]),
path_list_out_args,
/* Exec method */
{ { path_list_invoker } },
};
/* Get the points the named path is composed of */
static Argument *
path_get_points_invoker (Argument *args)
{
Argument *return_args = NULL;
GImage *gimage;
gchar *pname;
gint int_value;
gimage = NULL;
success = TRUE;
int_value = args[0].value.pdb_int;
if ((gimage = gimage_get_ID (int_value)) == NULL)
success = FALSE;
if (success)
{
/* Get the path with the given name */
PathsList *plist = gimage->paths;
pname = args[1].value.pdb_pointer;
if(pname && plist && plist->bz_paths)
{
GSList *pl = plist->bz_paths;
PATHP pptr = NULL;
while(pl)
{
pptr = pl->data;
if(strcmp(pname,pptr->name->str) == 0)
{
/* Found the path */
break;
}
pl = g_slist_next(pl);
pptr = NULL;
}
if(pl && pptr)
{
gint num_pdetails;
gdouble *pnts;
GSList *points_list;
gint pcount = 0;
return_args = procedural_db_return_args (&path_get_points_proc, success);
/* Get the details for this path */
return_args[1].value.pdb_int = pptr->pathtype;
return_args[2].value.pdb_int = pptr->closed;
points_list = pptr->path_details;
if(points_list)
{
num_pdetails = g_slist_length(points_list);
return_args[3].value.pdb_int = num_pdetails*3; /* 3 floats for each point */
pnts = g_malloc(sizeof(gdouble)*3*num_pdetails);
/* fill points and types in */
while(points_list)
{
PATHPOINTP ppoint = points_list->data;
pnts[pcount] = ppoint->x;
pnts[pcount+1] = ppoint->y;
pnts[pcount+2] = (gfloat)ppoint->type; /* Bit of fiddle but should be understandable why it was done */
pcount += 3;
points_list = g_slist_next(points_list);
}
}
else
{
return_args[3].value.pdb_int = 0;
pnts = NULL;
}
return_args[4].value.pdb_pointer = pnts;
}
else
{
success = FALSE;
}
}
else
{
success = FALSE;
}
}
if(!success)
{
return_args = procedural_db_return_args (&path_get_points_proc, success);
}
return return_args;
}
/* The procedure definition */
ProcArg path_get_points_in_args[] =
{
{ PDB_IMAGE,
"image",
"the image to list the paths from"
},
{ PDB_STRING,
"pathname",
"the name of the path whose points should be listed"
},
};
ProcArg path_get_points_out_args[] =
{
{ PDB_INT32,
"paths_type",
"The type of the path. Currently only one type (1 = Bezier) is supported"
},
{ PDB_INT32,
"pathclosed",
"Return if the path is closed. {0=path open, 1= path closed}"
},
{ PDB_INT32,
"num_path_point_details",
"The number of point returned. Each point is made up of (x,y,pnt_type) of floats"
},
{ PDB_FLOATARRAY,
"points_pairs",
"The points in the path represented as 3 floats. The first is the x pos, next is the y pos, last is the type of the pnt. The type field is dependant on the path type. For beziers (type 1 paths) the type can either be {1.0= BEZIER_ANCHOR, 2.0= BEZIER_CONTROL}. Note all points are returned in pixel resolution"
}
};
ProcRecord path_get_points_proc =
{
"gimp_path_get_points",
"List the points associated with the named path",
"List the points associated with the named path",
"Andy Thomas",
"Andy Thomas",
"1999",
PDB_INTERNAL,
/* Input arguments */
sizeof(path_get_points_in_args)/sizeof(path_get_points_in_args[0]),
path_get_points_in_args,
/* Output arguments */
sizeof(path_get_points_out_args)/sizeof(path_get_points_out_args[0]),
path_get_points_out_args,
/* Exec method */
{ { path_get_points_invoker } },
};
/* Get the name of the current path (of the passed image) */
static Argument *
path_get_current_invoker (Argument *args)
{
Argument *return_args = NULL;
GImage *gimage;
gint int_value;
gimage = NULL;
success = TRUE;
int_value = args[0].value.pdb_int;
if ((gimage = gimage_get_ID (int_value)) == NULL)
success = FALSE;
if (success)
{
/* Get the path with the given name */
PathsList *plist = gimage->paths;
if(plist && plist->bz_paths)
{
PATHP pptr = NULL;
if(plist->last_selected_row >= 0)
{
pptr = (PATHP)g_slist_nth_data(plist->bz_paths,plist->last_selected_row);
return_args = procedural_db_return_args (&path_get_current_proc, success);
return_args[1].value.pdb_pointer = g_strdup(pptr->name->str);
}
else
{
success = FALSE;
}
}
else
{
success = FALSE;
}
}
if(!success)
{
return_args = procedural_db_return_args (&path_get_points_proc, success);
}
return return_args;
}
/* The procedure definition */
ProcArg path_get_current_in_args[] =
{
{ PDB_IMAGE,
"image",
"the image to get the current paths from"
}
};
ProcArg path_get_current_out_args[] =
{
{ PDB_STRING,
"current_path_name",
"The name of the current path"
}
};
ProcRecord path_get_current_proc =
{
"gimp_path_get_current",
"The name of the current path. Error if no paths",
"The name of the current path. Error if no paths",
"Andy Thomas",
"Andy Thomas",
"1999",
PDB_INTERNAL,
/* Input arguments */
sizeof(path_get_current_in_args)/sizeof(path_get_current_in_args[0]),
path_get_current_in_args,
/* Output arguments */
sizeof(path_get_current_out_args)/sizeof(path_get_current_out_args[0]),
path_get_current_out_args,
/* Exec method */
{ { path_get_current_invoker } },
};
/* Set the name of the current path (of the passed image) */
static Argument *
path_set_current_invoker (Argument *args)
{
Argument *return_args = NULL;
GImage *gimage;
gint int_value;
gchar *pname;
gimage = NULL;
success = TRUE;
int_value = args[0].value.pdb_int;
if ((gimage = gimage_get_ID (int_value)) == NULL)
success = FALSE;
if (success)
{
/* Set the current path to the given name */
pname = args[1].value.pdb_pointer;
if(pname && paths_set_path(gimage,pname))
{
success = TRUE;
}
else
{
success = FALSE;
}
}
return_args = procedural_db_return_args (&path_set_current_proc, success);
return return_args;
}
/* The procedure definition */
ProcArg path_set_current_in_args[] =
{
{ PDB_IMAGE,
"image",
"the image to set the current paths"
},
{ PDB_STRING,
"set_current_path_name",
"The name of the path to set the current path to"
}
};
/* NO out args.. Either works or errors. */
ProcRecord path_set_current_proc =
{
"gimp_path_set_current",
"The name path to set to the current. Error if path does not exist.",
"The name path to set to the current. Error if path does not exist.",
"Andy Thomas",
"Andy Thomas",
"1999",
PDB_INTERNAL,
/* Input arguments */
sizeof(path_set_current_in_args)/sizeof(path_set_current_in_args[0]),
path_set_current_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { path_set_current_invoker } },
};
/* Set a path up from the given points */
/* Currently only the creation of bezier curves is allowed.
* The type parameter must be set to (1) to indicate a BEZIER type curve.
*/
/* For BEZIERS..
*
* Note the that points must be given in the following order...
* ACCACCACC ...
* The last control point is missing for non closed curves.
*/
static Argument *
path_set_points_invoker (Argument *args)
{
Argument *return_args = NULL;
GImage *gimage;
gchar *pname;
gint int_value;
gint ptype;
gint numpoints;
gint pclosed = FALSE;
gdouble *pnts;
gimage = NULL;
success = TRUE;
int_value = args[0].value.pdb_int;
if ((gimage = gimage_get_ID (int_value)) == NULL)
success = FALSE;
if (success)
{
pname = args[1].value.pdb_pointer;
ptype = args[2].value.pdb_int;
numpoints = args[3].value.pdb_int;
if((numpoints/2)%3 == 0)
pclosed = TRUE;
else if ((numpoints/2)%3 != 2)
success = FALSE;
pnts = args[4].value.pdb_pointer;
}
if(success)
{
if(paths_set_path_points(gimage,pname,ptype,pclosed,numpoints,pnts))
return_args = procedural_db_return_args (&path_get_points_proc, success);
else
success = FALSE;
}
else
{
success = FALSE;
}
if(!success)
{
return_args = procedural_db_return_args (&path_get_points_proc, success);
}
return return_args;
}
/* The procedure definition */
ProcArg path_set_points_in_args[] =
{
{ PDB_IMAGE,
"image",
"the image to list the paths from"
},
{ PDB_STRING,
"pathname",
"the name of the path to create (if it exists then all current points are removed). This will not be set as the current path.You will have to do a gimp_set_current_path after creating the path to make it current."
},
{ PDB_INT32,
"path_type",
"The type of the path. Currently only one type (1 = Bezier) is supported"
},
{ PDB_INT32,
"num_path_points",
"The number of points in the path. Each point is made up of (x,y) of floats. "
"Currently only the creation of bezier curves is allowed. "
"The type parameter must be set to (1) to indicate a BEZIER type curve.\n"
"For BEZIERS.\n"
"Note the that points must be given in the following order... "
"ACCACCAC ... "
"If the path is not closed the last control point is missed off. "
"Points consist of three control points (control/anchor/control) "
"so for a curve that is not closed there must be at least two points passed (2 x,y pairs). "
"If num_path_pnts%3 = 0 then the path is assumed to be closed and the points are ACCACCACCACC."
},
{ PDB_FLOATARRAY,
"points_pairs",
"The points in the path represented as 2 floats. The first is the x pos, next is the y pos. The order of points define there types (see num_path_points comment)."
}
};
/* No Out args */
ProcRecord path_set_points_proc =
{
"gimp_path_set_points",
"Set the points associated with the named path",
"Set the points associated with the named path",
"Andy Thomas",
"Andy Thomas",
"1999",
PDB_INTERNAL,
/* Input arguments */
sizeof(path_set_points_in_args)/sizeof(path_set_points_in_args[0]),
path_set_points_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { path_set_points_invoker } },
};
/* Stroke the current path */
/* Note it will ONLY do the current path.. */
static Argument *
path_stroke_current_invoker (Argument *args)
{
Argument *return_args = NULL;
GImage *gimage;
gint int_value;
gimage = NULL;
success = TRUE;
int_value = args[0].value.pdb_int;
if ((gimage = gimage_get_ID (int_value)) == NULL)
success = FALSE;
if (success)
{
/* Get the path with the given name */
PathsList *plist = gimage->paths;
if(plist && plist->bz_paths)
{
GSList *pl = plist->bz_paths;
PATHP pptr = NULL;
if(plist->last_selected_row >= 0 &&
(pptr = (PATHP)g_slist_nth_data(plist->bz_paths,plist->last_selected_row)))
{
/* Found the path to stroke.. */
paths_stroke(gimage,plist,pptr);
}
else
{
success = FALSE;
}
}
else
{
success = FALSE;
}
}
return_args = procedural_db_return_args (&path_set_current_proc, success);
return return_args;
}
/* The procedure definition */
ProcArg path_stroke_current_in_args[] =
{
{ PDB_IMAGE,
"image",
"the image which contains the path to stroke"
},
};
/* NO out args.. Either works or errors. */
ProcRecord path_stroke_current_proc =
{
"gimp_path_stroke_current",
"Stroke the current path in the passed image",
"Stroke the current path in the passed image",
"Andy Thomas",
"Andy Thomas",
"1999",
PDB_INTERNAL,
/* Input arguments */
sizeof(path_stroke_current_in_args)/sizeof(path_stroke_current_in_args[0]),
path_stroke_current_in_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { path_stroke_current_invoker } },
};

35
app/paths_cmds.h Normal file
View File

@ -0,0 +1,35 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1999 Andy Thomas alt@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.
* Some of this code is based on the layers_dialog box code.
*/
#ifndef __PATHS_CMDS_H__
#define __PATHS_CMDS_H__
#include "procedural_db.h"
extern ProcRecord path_list_proc;
extern ProcRecord path_get_points_proc;
extern ProcRecord path_get_current_proc;
extern ProcRecord path_set_current_proc;
extern ProcRecord path_set_points_proc;
extern ProcRecord path_stroke_current_proc;
#endif __PATHS_CMDS_H__

View File

@ -99,7 +99,7 @@ static PATHSLISTP paths_dialog = NULL;
typedef struct {
GdkPixmap *paths_pixmap;
GString *text;
BZPATHP bzp;
PATHP bzp;
} PATHWIDGET, *PATHWIDGETP;
static gint path_widget_preview_events (GtkWidget *, GdkEvent *);
@ -116,8 +116,8 @@ static void paths_dialog_stroke_path_callback(GtkWidget *w,gpointer client_data)
static void paths_dialog_path_to_sel_callback(GtkWidget *w,gpointer client_data);
static void paths_dialog_destroy_cb (GimpImage *image);
static void paths_update_paths(gpointer data,gint row);
static GSList * bzpoints_copy(GSList *list);
static void bzpoints_free(GSList *list);
static GSList * pathpoints_copy(GSList *list);
static void pathpoints_free(GSList *list);
static void paths_update_preview(BezierSelect *bezier_sel);
static void paths_dialog_preview_extents (void);
static void paths_dialog_new_point_callback (GtkWidget *, gpointer);
@ -369,33 +369,34 @@ clear_pathwidget(gpointer data)
}
static void
bzpoint_free(gpointer data,gpointer user_data)
pathpoint_free(gpointer data,gpointer user_data)
{
BZPOINTP bzpoint = data;
g_free(bzpoint);
PATHPOINTP pathpoint = data;
g_free(pathpoint);
}
static void
bzpath_free(gpointer data,gpointer user_data)
path_free(gpointer data,gpointer user_data)
{
BZPATHP bzp = data;
PATHP bzp = data;
g_return_if_fail(bzp != NULL);
g_string_free(bzp->name,TRUE);
bzpoints_free(bzp->bezier_details);
pathpoints_free(bzp->path_details);
g_free(bzp);
}
static BZPATHP
static PATHP
bzpath_dialog_new(gint name_seed, gpointer udata)
{
BZPATHP bzp = g_new0(BZPATH,1);
PATHP bzp = g_new0(PATH,1);
GString *s = g_string_new (NULL);
g_string_sprintf (s, "path %d",name_seed);
bzp->pathtype = BEZIER;
bzp->name = s;
bzp->bezier_details = (GSList *)udata; /* If called via button/menu this will be NULL */
bzp->path_details = (GSList *)udata; /* If called via button/menu this will be NULL */
return bzp;
}
@ -452,7 +453,7 @@ unique_name(gchar *cstr)
while(tlist)
{
gchar *test_str = ((BZPATHP)(tlist->data))->name->str;
gchar *test_str = ((PATHP)(tlist->data))->name->str;
if(strcmp(cstr,test_str) == 0)
{
unique = FALSE;
@ -476,7 +477,7 @@ unique_name(gchar *cstr)
while(tlist)
{
copy_test = ((BZPATHP)(tlist->data))->name->str;
copy_test = ((PATHP)(tlist->data))->name->str;
if(strcmp(copy_cstr,copy_test) == 0)
{
g_free(copy_cstr);
@ -491,51 +492,52 @@ unique_name(gchar *cstr)
return copy_cstr;
}
static BZPATHP
bzpath_copy(BZPATHP bzp)
static PATHP
path_copy(PATHP p)
{
BZPATHP bzp_copy = g_new0(BZPATH,1);
PATHP p_copy = g_new0(PATH,1);
gchar *ext;
ext = unique_name(bzp->name->str);
bzp_copy->name = g_string_new(ext);
ext = unique_name(p->name->str);
p_copy->name = g_string_new(ext);
g_free(ext);
bzp_copy->closed = bzp->closed;
bzp_copy->state = bzp->state;
bzp_copy->bezier_details = bzpoints_copy(bzp->bezier_details);
p_copy->closed = p->closed;
p_copy->state = p->state;
p_copy->pathtype = p->pathtype;
p_copy->path_details = pathpoints_copy(p->path_details);
return bzp_copy;
return p_copy;
}
static void
bzpath_close(BZPATHP bzp)
path_close(PATHP bzp)
{
BZPOINTP pdata;
BZPOINTP bzpoint;
PATHPOINTP pdata;
PATHPOINTP pathpoint;
/* bzpaths are only really closed when converted to the BezierSelect ones */
bzp->closed = 1;
/* first point */
pdata = (BZPOINTP)bzp->bezier_details->data;
pdata = (PATHPOINTP)bzp->path_details->data;
if(g_slist_length(bzp->bezier_details) < 5)
if(g_slist_length(bzp->path_details) < 5)
{
int i;
for (i = 0 ; i < 2 ; i++)
{
bzpoint = g_new0(BZPOINT,1);
bzpoint->type = (i & 1)?BEZIER_ANCHOR:BEZIER_CONTROL;
bzpoint->x = pdata->x+i;
bzpoint->y = pdata->y+i;
bzp->bezier_details = g_slist_append(bzp->bezier_details,bzpoint);
pathpoint = g_new0(PATHPOINT,1);
pathpoint->type = (i & 1)?BEZIER_ANCHOR:BEZIER_CONTROL;
pathpoint->x = pdata->x+i;
pathpoint->y = pdata->y+i;
bzp->path_details = g_slist_append(bzp->path_details,pathpoint);
}
}
bzpoint = g_new0(BZPOINT,1);
pdata = (BZPOINTP)bzp->bezier_details->data;
bzpoint->type = BEZIER_CONTROL;
bzpoint->x = pdata->x;
bzpoint->y = pdata->y;
bzp->bezier_details = g_slist_append(bzp->bezier_details,bzpoint);
pathpoint = g_new0(PATHPOINT,1);
pdata = (PATHPOINTP)bzp->path_details->data;
pathpoint->type = BEZIER_CONTROL;
pathpoint->x = pdata->x;
pathpoint->y = pdata->y;
bzp->path_details = g_slist_append(bzp->path_details,pathpoint);
}
static void
@ -546,17 +548,17 @@ beziersel_free(BezierSelect *bezier_sel)
}
static BezierSelect *
bzpath_to_beziersel(BZPATHP bzp)
path_to_beziersel(PATHP bzp)
{
BezierSelect *bezier_sel;
GSList *list;
if(!bzp)
{
g_warning("bzpath_to_beziersel:: NULL bzp");
g_warning("path_to_beziersel:: NULL bzp");
}
list = bzp->bezier_details;
list = bzp->path_details;
bezier_sel = g_new0 (BezierSelect,1);
bezier_sel->num_points = 0;
@ -569,9 +571,9 @@ bzpath_to_beziersel(BZPATHP bzp)
while(list)
{
BZPOINTP pdata;
pdata = (BZPOINTP)list->data;
bezier_add_point(bezier_sel,pdata->type,pdata->x,pdata->y);
PATHPOINTP pdata;
pdata = (PATHPOINTP)list->data;
bezier_add_point(bezier_sel,(gint)pdata->type,(gint)pdata->x,pdata->y);
list = g_slist_next(list);
}
@ -592,7 +594,7 @@ pathimagelist_free(PATHIMAGELISTP iml)
g_return_if_fail(iml != NULL);
if(iml->bz_paths)
{
g_slist_foreach(iml->bz_paths,bzpath_free,NULL);
g_slist_foreach(iml->bz_paths,path_free,NULL);
g_slist_free(iml->bz_paths);
}
g_free(iml);
@ -664,7 +666,7 @@ clear_pixmap_preview(PATHWIDGETP pwidget)
}
/* insrow == -1 -> append else insert at insrow */
void paths_add_path(BZPATHP bzp,gint insrow)
void paths_add_path(PATHP bzp,gint insrow)
{
/* Create a new entry in the list */
PATHWIDGETP pwidget;
@ -826,7 +828,7 @@ paths_select_row(GtkWidget *widget,
gpointer data)
{
PATHWIDGETP pwidget;
BZPATHP bzp;
PATHP bzp;
BezierSelect * bsel;
GDisplay *gdisp;
@ -841,11 +843,11 @@ paths_select_row(GtkWidget *widget,
paths_dialog->current_path_list->last_selected_row = row;
paths_dialog->been_selected = TRUE;
bzp = (BZPATHP)g_slist_nth_data(paths_dialog->current_path_list->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(paths_dialog->current_path_list->bz_paths,row);
g_return_if_fail(bzp != NULL);
bsel = bzpath_to_beziersel(bzp);
bsel = path_to_beziersel(bzp);
gdisp = gdisplays_check_valid(paths_dialog->current_path_list->gdisp,
paths_dialog->gimage);
if(!gdisp)
@ -992,12 +994,12 @@ paths_dialog_update (GimpImage* gimage)
static void
paths_update_paths(gpointer data,gint row)
{
BZPATHP bzp;
PATHP bzp;
BezierSelect * bezier_sel;
paths_add_path((bzp = (BZPATHP)data),-1);
paths_add_path((bzp = (PATHP)data),-1);
/* Now fudge the drawing....*/
bezier_sel = bzpath_to_beziersel(bzp);
bezier_sel = path_to_beziersel(bzp);
paths_dialog->current_path_list->last_selected_row = row;
paths_update_preview(bezier_sel);
beziersel_free(bezier_sel);
@ -1121,7 +1123,7 @@ paths_list_events (GtkWidget *widget,
}
static PATHIMAGELISTP
bzpath_add_to_current(PATHIMAGELISTP pip,BZPATHP bzp,GimpImage *gimage,gint pos)
path_add_to_current(PATHIMAGELISTP pip,PATHP bzp,GimpImage *gimage,gint pos)
{
/* add bzp to current list */
if(!pip)
@ -1141,29 +1143,38 @@ bzpath_add_to_current(PATHIMAGELISTP pip,BZPATHP bzp,GimpImage *gimage,gint pos)
return pip;
}
static BZPATHP
static PATHP
paths_dialog_new_path(PATHIMAGELISTP *plp,gpointer points,GimpImage *gimage,gint pos)
{
static gint nseed = 0;
BZPATHP bzp = bzpath_dialog_new(nseed++,points);
*plp = bzpath_add_to_current(*plp,bzp,gimage,pos);
PATHP bzp = bzpath_dialog_new(nseed++,points);
*plp = path_add_to_current(*plp,bzp,gimage,pos);
return(bzp);
}
static void
paths_dialog_new_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp = paths_dialog_new_path(&paths_dialog->current_path_list,
PATHP bzp = paths_dialog_new_path(&paths_dialog->current_path_list,
NULL,
paths_dialog->gimage,
paths_dialog->selected_row_num);
paths_add_path(bzp,paths_dialog->selected_row_num);
/* Enable the buttons!*/
paths_ops_button_set_sensitive(DUP_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(DEL_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(STROKE_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(PATH_TO_SEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_NEW_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_DEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_ADD_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_EDIT_BUTTON,TRUE);
}
static void
paths_dialog_delete_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
gboolean new_sz;
gint row = paths_dialog->selected_row_num;
@ -1176,12 +1187,12 @@ paths_dialog_delete_path_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure & delete its content */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Remove from list */
plp->bz_paths = g_slist_remove(plp->bz_paths,bzp);
new_sz = (g_slist_length(plp->bz_paths) > 0);
bzpath_free(bzp,NULL);
path_free(bzp,NULL);
/* If now empty free everything up */
if(!plp->bz_paths || g_slist_length(plp->bz_paths) == 0)
@ -1210,7 +1221,7 @@ paths_dialog_delete_path_callback (GtkWidget * widget, gpointer udata)
static void
paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
BezierSelect * bezier_sel;
gint row = paths_dialog->selected_row_num;
@ -1224,15 +1235,15 @@ paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Insert at the current position */
bzp = bzpath_copy(bzp);
bzp = path_copy(bzp);
plp->bz_paths = g_slist_insert(plp->bz_paths,bzp,row);
paths_add_path(bzp,row);
/* Now fudge the drawing....*/
bezier_sel = bzpath_to_beziersel(bzp);
bezier_sel = path_to_beziersel(bzp);
tmprow = paths_dialog->current_path_list->last_selected_row;
paths_dialog->current_path_list->last_selected_row = row;
paths_update_preview(bezier_sel);
@ -1243,7 +1254,7 @@ paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
static void
paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
BezierSelect * bezier_sel;
GDisplay * gdisp;
@ -1257,7 +1268,7 @@ paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Now do the stroke....*/
gdisp = gdisplays_check_valid(paths_dialog->current_path_list->gdisp,
@ -1265,17 +1276,17 @@ paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
if(!bzp->closed)
{
BZPATHP bzpcopy = bzpath_copy(bzp);
PATHP bzpcopy = path_copy(bzp);
/* Close it */
bzpath_close(bzpcopy);
bezier_sel = bzpath_to_beziersel(bzpcopy);
bzpath_free(bzpcopy,NULL);
path_close(bzpcopy);
bezier_sel = path_to_beziersel(bzpcopy);
path_free(bzpcopy,NULL);
bezier_to_selection (bezier_sel, gdisp);
beziersel_free(bezier_sel);
}
else
{
bezier_sel = bzpath_to_beziersel(bzp);
bezier_sel = path_to_beziersel(bzp);
bezier_to_selection (bezier_sel, gdisp);
beziersel_free(bezier_sel);
}
@ -1284,10 +1295,8 @@ paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
static void
paths_dialog_stroke_path_callback (GtkWidget * widget, gpointer udata)
{
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
BezierSelect * bezier_sel;
GDisplay * gdisp;
gint row = paths_dialog->selected_row_num;
g_return_if_fail(paths_dialog->current_path_list != NULL);
@ -1298,14 +1307,10 @@ paths_dialog_stroke_path_callback (GtkWidget * widget, gpointer udata)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
/* Now do the stroke....*/
gdisp = gdisplays_check_valid(paths_dialog->current_path_list->gdisp,
paths_dialog->gimage);
bezier_sel = bzpath_to_beziersel(bzp);
bezier_stroke (bezier_sel, gdisp, SUBDIVIDE, !bzp->closed);
beziersel_free(bezier_sel);
paths_stroke(paths_dialog->gimage,paths_dialog->current_path_list,bzp);
}
static void
@ -1368,45 +1373,45 @@ paths_dialog_destroy_cb (GimpImage *gimage)
/* Functions used from the bezier code .. tie in with this code */
static void
bzpoints_free(GSList *list)
pathpoints_free(GSList *list)
{
if(!list)
return;
g_slist_foreach(list,bzpoint_free,NULL);
g_slist_foreach(list,pathpoint_free,NULL);
g_slist_free(list);
}
static GSList *
bzpoints_create(BezierSelect *sel)
pathpoints_create(BezierSelect *sel)
{
gint i;
GSList *list = NULL;
BZPOINTP bzpoint;
PATHPOINTP pathpoint;
BezierPoint *pts = (BezierPoint *) sel->points;
for (i=0; i< sel->num_points; i++)
{
bzpoint = bzpoint_new(pts->type,pts->x,pts->y);
list = g_slist_append(list,bzpoint);
pathpoint = pathpoint_new(pts->type,(gdouble)pts->x,(gdouble)pts->y);
list = g_slist_append(list,pathpoint);
pts = pts->next;
}
return(list);
}
static GSList *
bzpoints_copy(GSList *list)
pathpoints_copy(GSList *list)
{
GSList *slcopy = NULL;
BZPOINTP pdata;
BZPOINTP bzpoint;
PATHPOINTP pdata;
PATHPOINTP pathpoint;
while(list)
{
bzpoint = g_new0(BZPOINT,1);
pdata = (BZPOINTP)list->data;
bzpoint->type = pdata->type;
bzpoint->x = pdata->x;
bzpoint->y = pdata->y;
slcopy = g_slist_append(slcopy,bzpoint);
pathpoint = g_new0(PATHPOINT,1);
pdata = (PATHPOINTP)list->data;
pathpoint->type = pdata->type;
pathpoint->x = pdata->x;
pathpoint->y = pdata->y;
slcopy = g_slist_append(slcopy,pathpoint);
list = g_slist_next(list);
}
return slcopy;
@ -1415,16 +1420,16 @@ bzpoints_copy(GSList *list)
static void
paths_update_bzpath(PATHIMAGELISTP plp,BezierSelect *bezier_sel)
{
BZPATHP bzp;
PATHP p;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,plp->last_selected_row);
p = (PATHP)g_slist_nth_data(plp->bz_paths,plp->last_selected_row);
if(bzp->bezier_details)
bzpoints_free(bzp->bezier_details);
if(p->path_details)
pathpoints_free(p->path_details);
bzp->bezier_details = bzpoints_create(bezier_sel);
bzp->closed = bezier_sel->closed;
bzp->state = bezier_sel->state;
p->path_details = pathpoints_create(bezier_sel);
p->closed = bezier_sel->closed;
p->state = bezier_sel->state;
}
static gboolean
@ -1570,7 +1575,7 @@ paths_first_button_press(BezierSelect *bezier_sel,GDisplay * gdisp)
All this of course depends on the fact that gdisp is the same
as before.
*/
BZPATHP bzp;
PATHP bzp;
PATHIMAGELISTP plp;
if(paths_dialog)
@ -1589,7 +1594,7 @@ paths_first_button_press(BezierSelect *bezier_sel,GDisplay * gdisp)
if(!paths_replaced_current(plp,bezier_sel))
{
bzp = paths_dialog_new_path(&plp,bzpoints_create(bezier_sel),gdisp->gimage,-1);
bzp = paths_dialog_new_path(&plp,pathpoints_create(bezier_sel),gdisp->gimage,-1);
bzp->closed = bezier_sel->closed;
bzp->state = bezier_sel->state;
if(paths_dialog && paths_dialog->gimage == gdisp->gimage)
@ -1641,35 +1646,37 @@ paths_new_bezier_select_tool()
/**************************************************************/
BZPOINTP
bzpoint_new(gint type,
gint x,
gint y)
PATHPOINTP
pathpoint_new(gint type,
gdouble x,
gdouble y)
{
BZPOINTP bzpoint = g_new0(BZPOINT,1);
PATHPOINTP pathpoint = g_new0(PATHPOINT,1);
bzpoint->type = type;
bzpoint->x = x;
bzpoint->y = y;
return(bzpoint);
pathpoint->type = type;
pathpoint->x = x;
pathpoint->y = y;
return(pathpoint);
}
BZPATHP
bzpath_new(GSList * bezier_details,
PATHP
path_new(PathType ptype,
GSList * path_details,
gint closed,
gint state,
gint locked,
gchar * name)
{
BZPATHP bzpath = g_new0(BZPATH,1);
PATHP path = g_new0(PATH,1);
bzpath->bezier_details = bezier_details;
bzpath->closed = closed;
bzpath->state = state;
bzpath->locked = locked;
bzpath->name = g_string_new(name);
path->path_details = path_details;
path->closed = closed;
path->state = state;
path->locked = locked;
path->name = g_string_new(name);
path->pathtype = ptype;
return bzpath;
return path;
}
PathsList *
@ -1700,22 +1707,22 @@ pathsList_new(GimpImage * gimage,
static GtkWidget *file_dlg = 0;
static int load_store;
static void path_write_current_to_file(FILE *f,BZPATHP bzp)
static void path_write_current_to_file(FILE *f,PATHP bzp)
{
GSList *list = bzp->bezier_details;
BZPOINTP pdata;
GSList *list = bzp->path_details;
PATHPOINTP pdata;
fprintf(f, "Name: %s\n", bzp->name->str);
fprintf(f, "#POINTS: %d\n", g_slist_length(bzp->bezier_details));
fprintf(f, "#POINTS: %d\n", g_slist_length(bzp->path_details));
fprintf(f, "CLOSED: %d\n", bzp->closed==1?1:0);
fprintf(f, "DRAW: %d\n", 0);
fprintf(f, "STATE: %d\n", bzp->state);
while(list)
{
pdata = (BZPOINTP)list->data;
fprintf(f,"TYPE: %d X: %d Y: %d\n", pdata->type, pdata->x, pdata->y);
pdata = (PATHPOINTP)list->data;
fprintf(f,"TYPE: %d X: %d Y: %d\n", pdata->type, (gint)pdata->x, (gint)pdata->y);
list = g_slist_next(list);
}
}
@ -1726,7 +1733,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
GtkFileSelection *fs;
FILE *f;
char* filename;
BZPATHP bzpath;
PATHP bzpath;
GSList * pts_list = NULL;
PATHIMAGELISTP plp;
gint row = paths_dialog->selected_row_num;
@ -1769,7 +1776,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
for(i=0; i< val; i++)
{
BZPOINTP bpt;
PATHPOINTP bpt;
readfields = fscanf(f,"TYPE: %d X: %d Y: %d\n", &type, &x, &y);
if(readfields != 3)
{
@ -1777,20 +1784,21 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
gtk_widget_hide (file_dlg);
return;
}
bpt = bzpoint_new(type, x, y);
bpt = pathpoint_new(type, (gdouble)x, (gdouble)y);
pts_list = g_slist_append(pts_list,bpt);
}
bzpath = bzpath_new(pts_list,
closed,
state,
0, /* Can't be locked */
txt);
bzpath = path_new(BEZIER,
pts_list,
closed,
state,
0, /* Can't be locked */
txt);
g_free(txtstart);
paths_dialog->current_path_list =
bzpath_add_to_current(paths_dialog->current_path_list,
path_add_to_current(paths_dialog->current_path_list,
bzpath,
paths_dialog->gimage,
row);
@ -1813,7 +1821,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
}
else
{
BZPATHP bzp;
PATHP bzp;
/* Get current selection... ignore if none */
if(paths_dialog->selected_row_num < 0)
@ -1821,7 +1829,7 @@ static void file_ok_callback(GtkWidget * widget, gpointer client_data)
/* Get bzpath structure */
plp = paths_dialog->current_path_list;
bzp = (BZPATHP)g_slist_nth_data(plp->bz_paths,row);
bzp = (PATHP)g_slist_nth_data(plp->bz_paths,row);
f = fopen(filename, "wb");
if (NULL == f)
@ -1905,3 +1913,212 @@ paths_dialog_export_path_callback (GtkWidget * widget, gpointer udata)
/* Export the path to a file */
path_store_callback();
}
/*************************************/
/* PDB function aids */
/*************************************/
/* Return TRUE if setting the path worked, else false */
gboolean
paths_set_path(GimpImage * gimage,
gchar * pname)
{
gint row = 0;
gboolean found = FALSE;
GSList *tlist;
PATHIMAGELISTP plp;
/* Get bzpath structure */
plp = (PATHIMAGELISTP)gimp_image_get_paths(gimage);
if(!plp)
return FALSE;
tlist = plp->bz_paths;
while(tlist)
{
gchar *test_str = ((PATHP)(tlist->data))->name->str;
if(strcmp(pname,test_str) == 0)
{
found = TRUE;
break;
}
row++;
tlist = g_slist_next(tlist);
}
if(!found)
return FALSE;
if(paths_dialog)
{
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
row,
0);
}
else
{
plp->last_selected_row = row;
}
return TRUE;
}
/* Set a path with the given set of points. */
/* We assume that there are enough points */
/* Return TRUE if path created OK. */
gboolean
paths_set_path_points(GimpImage * gimage,
gchar * pname,
gint ptype,
gint pclosed,
gint num_pnts,
gdouble * pnts)
{
PathsList *plist = gimp_image_get_paths(gimage);
GSList *pts_list = NULL;
PATHP bzpath;
gint pcount = 0;
if(num_pnts < 6 ||
(pclosed && ((num_pnts/2) % 3)) ||
(!pclosed && ((num_pnts/2) % 3) != 2))
{
g_warning(_("wrong number of points\n"));
return FALSE;
}
if(ptype != BEZIER)
ptype = BEZIER;
while(num_pnts)
{
PATHPOINTP bpt;
gint type;
gdouble x;
gdouble y;
if((pcount/2)%3)
type = BEZIER_CONTROL;
else
type = BEZIER_ANCHOR;
x = pnts[pcount++];
y = pnts[pcount++];
/* printf("New point type = %s, x = %d y= %d\n", */
/* (type==BEZIER_CONTROL)?"CNTL":"ANCH", */
/* (int)x, */
/* (int)y); */
bpt = pathpoint_new(type, (gdouble)x, (gdouble)y);
pts_list = g_slist_append(pts_list,bpt);
num_pnts -= 2;
}
if(!plist)
{
GSList *bzp_list = NULL;
/* No paths at all.... create one & rename */
bzpath = path_new(ptype,
pts_list,
pclosed,
(pclosed)?BEZIER_EDIT:BEZIER_ADD,/*state,*/
0, /* Can't be locked */
pname);
bzp_list = g_slist_append(bzp_list,bzpath);
plist = pathsList_new(gimage,0,bzp_list);
gimp_image_set_paths(gimage,plist);
}
else
{
GSList *tlist;
PATHP pp = NULL;
gint row = 0;
/* Check if name already exists.. if so delete all points assoc with it
* if not create a new one with the passed name.
*/
tlist = plist->bz_paths;
while(tlist)
{
gchar *test_str = ((PATHP)(tlist->data))->name->str;
if(strcmp(pname,test_str) == 0)
{
pp = (PATHP)(tlist->data);
break;
}
tlist = g_slist_next(tlist);
row++;
}
if(pp)
{
pathpoints_free(pp->path_details);
pp->path_details = pts_list;
pp->pathtype = ptype;
pp->closed = pclosed;
pp->locked = 0;
if(paths_dialog)
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
row,
0);
return TRUE;
}
else
{
bzpath = path_new(ptype,
pts_list,
pclosed,
(pclosed)?BEZIER_EDIT:BEZIER_ADD,/*state,*/
0, /* Can't be locked */
pname);
path_add_to_current(plist,bzpath,gimage,-1);
}
}
if(paths_dialog)
{
paths_dialog->current_path_list =
path_add_to_current(paths_dialog->current_path_list,
bzpath,
paths_dialog->gimage,
0);
paths_add_path(bzpath,0);
gtk_clist_select_row(GTK_CLIST(paths_dialog->paths_list),
paths_dialog->current_path_list->last_selected_row,
0);
paths_ops_button_set_sensitive(DUP_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(DEL_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(STROKE_PATH_BUTTON,TRUE);
paths_ops_button_set_sensitive(PATH_TO_SEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_ADD_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_DEL_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_NEW_BUTTON,TRUE);
point_ops_button_set_sensitive(POINT_EDIT_BUTTON,TRUE);
}
return TRUE;
}
void
paths_stroke(GimpImage *gimage,PathsList *pl,PATHP bzp)
{
BezierSelect * bezier_sel;
GDisplay * gdisp;
gdisp = gdisplays_check_valid(pl->gdisp,gimage);
bezier_sel = path_to_beziersel(bzp);
bezier_stroke (bezier_sel, gdisp, SUBDIVIDE, !bzp->closed);
beziersel_free(bezier_sel);
}

View File

@ -25,7 +25,7 @@ void paths_dialog_update (GimpImage*);
void paths_newpoint_current(BezierSelect *, GDisplay *);
void paths_first_button_press(BezierSelect *,GDisplay *);
void paths_new_bezier_select_tool(void);
BZPATHP paths_get_bzpaths(void);
void paths_set_bzpaths(GImage*,BZPATHP);
PATHP paths_get_bzpaths(void);
void paths_set_bzpaths(GImage*,PATHP);
#endif /* __PATHS_DIALOG_H__ */

View File

@ -703,9 +703,11 @@ static Parasite *read_a_parasite(XcfInfo *info)
static void write_bz_point(gpointer pptr, gpointer iptr)
{
BZPOINTP bpt = (BZPOINTP)pptr;
PATHPOINTP bpt = (PATHPOINTP)pptr;
XcfInfo *info = (XcfInfo *)iptr;
gfloat xfloat = (gfloat)bpt->x;
gfloat yfloat = (gfloat)bpt->y;
/* (all gint)
* type
* x
@ -713,13 +715,13 @@ static void write_bz_point(gpointer pptr, gpointer iptr)
*/
info->cp += xcf_write_int32(info->fp, &bpt->type,1);
info->cp += xcf_write_int32(info->fp, (guint32*)&bpt->x,1);
info->cp += xcf_write_int32(info->fp, (guint32*)&bpt->y,1);
info->cp += xcf_write_float(info->fp, &xfloat,1);
info->cp += xcf_write_float(info->fp, &yfloat,1);
}
static BZPOINTP read_bz_point(XcfInfo *info)
static PATHPOINTP v1read_bz_point(XcfInfo *info)
{
BZPOINTP ptr;
PATHPOINTP ptr;
guint32 type;
gint32 x;
gint32 y;
@ -728,19 +730,35 @@ static BZPOINTP read_bz_point(XcfInfo *info)
info->cp += xcf_read_int32(info->fp, (guint32*)&x,1);
info->cp += xcf_read_int32(info->fp, (guint32*)&y,1);
ptr = bzpoint_new(type,x,y);
ptr = pathpoint_new(type,(gdouble)x,(gdouble)y);
return (ptr);
}
static PATHPOINTP read_bz_point(XcfInfo *info)
{
PATHPOINTP 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);
ptr = pathpoint_new(type,(gdouble)x,(gdouble)y);
return (ptr);
}
static void write_one_path(gpointer pptr, gpointer iptr)
{
BZPATHP bzp = (BZPATHP)pptr;
PATHP bzp = (PATHP)pptr;
XcfInfo *info = (XcfInfo *)iptr;
guint8 state = (gchar)bzp->state;
guint32 num_points;
guint32 num_paths;
guint32 closed;
guint32 version;
/*
* name (string)
@ -757,40 +775,62 @@ static void write_one_path(gpointer pptr, gpointer iptr)
info->cp += xcf_write_int8(info->fp, &state,1);
closed = bzp->closed;
info->cp += xcf_write_int32(info->fp, &closed,1);
num_points = g_slist_length(bzp->bezier_details);
num_points = g_slist_length(bzp->path_details);
info->cp += xcf_write_int32(info->fp, &num_points,1);
num_paths = 1;
info->cp += xcf_write_int32(info->fp, &num_paths,1);
g_slist_foreach(bzp->bezier_details,write_bz_point,info);
version = 2;
info->cp += xcf_write_int32(info->fp, &version,1);
info->cp += xcf_write_int32(info->fp, &bzp->pathtype,1);
g_slist_foreach(bzp->path_details,write_bz_point,info);
}
static BZPATHP read_one_path(XcfInfo *info)
static PATHP read_one_path(XcfInfo *info)
{
BZPATHP bzp;
PATHP bzp;
gchar *name;
guint32 locked;
guint8 state;
guint32 closed;
guint32 num_points;
guint32 num_paths;
guint32 version; /* changed from num_paths */
GSList *pts_list = NULL;
PathType ptype;
info->cp += xcf_read_string(info->fp, &name, 1);
info->cp += xcf_read_int32(info->fp, &locked,1);
info->cp += xcf_read_int8(info->fp, &state,1);
info->cp += xcf_read_int32(info->fp, &closed,1);
info->cp += xcf_read_int32(info->fp, &num_points,1);
info->cp += xcf_read_int32(info->fp, &num_paths,1);
info->cp += xcf_read_int32(info->fp, &version,1);
while(num_points-- > 0)
if(version == 1)
{
BZPOINTP bpt;
/* Read in a path */
bpt = read_bz_point(info);
pts_list = g_slist_append(pts_list,bpt);
ptype = BEZIER;
while(num_points-- > 0)
{
PATHPOINTP bpt;
/* Read in a path */
bpt = v1read_bz_point(info);
pts_list = g_slist_append(pts_list,bpt);
}
}
else if(version == 2)
{
/* Had extra type field and points are stored as doubles */
info->cp += xcf_read_int32(info->fp, (guint32 *)&ptype,1);
while(num_points-- > 0)
{
PATHPOINTP bpt;
/* Read in a path */
bpt = read_bz_point(info);
pts_list = g_slist_append(pts_list,bpt);
}
}
else
{
g_warning("Unknown path type..Possibly corrupt XCF file");
}
bzp = bzpath_new(pts_list,closed,(gint)state,locked,name);
bzp = path_new(ptype,pts_list,closed,(gint)state,locked,name);
return(bzp);
}
@ -824,7 +864,7 @@ static PathsList * read_bzpaths(GImage *gimage, XcfInfo *info)
while(num_paths-- > 0)
{
BZPATHP bzp;
PATHP bzp;
/* Read in a path */
bzp = read_one_path(info);
bzp_list = g_slist_append(bzp_list,bzp);

View File

@ -703,9 +703,11 @@ static Parasite *read_a_parasite(XcfInfo *info)
static void write_bz_point(gpointer pptr, gpointer iptr)
{
BZPOINTP bpt = (BZPOINTP)pptr;
PATHPOINTP bpt = (PATHPOINTP)pptr;
XcfInfo *info = (XcfInfo *)iptr;
gfloat xfloat = (gfloat)bpt->x;
gfloat yfloat = (gfloat)bpt->y;
/* (all gint)
* type
* x
@ -713,13 +715,13 @@ static void write_bz_point(gpointer pptr, gpointer iptr)
*/
info->cp += xcf_write_int32(info->fp, &bpt->type,1);
info->cp += xcf_write_int32(info->fp, (guint32*)&bpt->x,1);
info->cp += xcf_write_int32(info->fp, (guint32*)&bpt->y,1);
info->cp += xcf_write_float(info->fp, &xfloat,1);
info->cp += xcf_write_float(info->fp, &yfloat,1);
}
static BZPOINTP read_bz_point(XcfInfo *info)
static PATHPOINTP v1read_bz_point(XcfInfo *info)
{
BZPOINTP ptr;
PATHPOINTP ptr;
guint32 type;
gint32 x;
gint32 y;
@ -728,19 +730,35 @@ static BZPOINTP read_bz_point(XcfInfo *info)
info->cp += xcf_read_int32(info->fp, (guint32*)&x,1);
info->cp += xcf_read_int32(info->fp, (guint32*)&y,1);
ptr = bzpoint_new(type,x,y);
ptr = pathpoint_new(type,(gdouble)x,(gdouble)y);
return (ptr);
}
static PATHPOINTP read_bz_point(XcfInfo *info)
{
PATHPOINTP 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);
ptr = pathpoint_new(type,(gdouble)x,(gdouble)y);
return (ptr);
}
static void write_one_path(gpointer pptr, gpointer iptr)
{
BZPATHP bzp = (BZPATHP)pptr;
PATHP bzp = (PATHP)pptr;
XcfInfo *info = (XcfInfo *)iptr;
guint8 state = (gchar)bzp->state;
guint32 num_points;
guint32 num_paths;
guint32 closed;
guint32 version;
/*
* name (string)
@ -757,40 +775,62 @@ static void write_one_path(gpointer pptr, gpointer iptr)
info->cp += xcf_write_int8(info->fp, &state,1);
closed = bzp->closed;
info->cp += xcf_write_int32(info->fp, &closed,1);
num_points = g_slist_length(bzp->bezier_details);
num_points = g_slist_length(bzp->path_details);
info->cp += xcf_write_int32(info->fp, &num_points,1);
num_paths = 1;
info->cp += xcf_write_int32(info->fp, &num_paths,1);
g_slist_foreach(bzp->bezier_details,write_bz_point,info);
version = 2;
info->cp += xcf_write_int32(info->fp, &version,1);
info->cp += xcf_write_int32(info->fp, &bzp->pathtype,1);
g_slist_foreach(bzp->path_details,write_bz_point,info);
}
static BZPATHP read_one_path(XcfInfo *info)
static PATHP read_one_path(XcfInfo *info)
{
BZPATHP bzp;
PATHP bzp;
gchar *name;
guint32 locked;
guint8 state;
guint32 closed;
guint32 num_points;
guint32 num_paths;
guint32 version; /* changed from num_paths */
GSList *pts_list = NULL;
PathType ptype;
info->cp += xcf_read_string(info->fp, &name, 1);
info->cp += xcf_read_int32(info->fp, &locked,1);
info->cp += xcf_read_int8(info->fp, &state,1);
info->cp += xcf_read_int32(info->fp, &closed,1);
info->cp += xcf_read_int32(info->fp, &num_points,1);
info->cp += xcf_read_int32(info->fp, &num_paths,1);
info->cp += xcf_read_int32(info->fp, &version,1);
while(num_points-- > 0)
if(version == 1)
{
BZPOINTP bpt;
/* Read in a path */
bpt = read_bz_point(info);
pts_list = g_slist_append(pts_list,bpt);
ptype = BEZIER;
while(num_points-- > 0)
{
PATHPOINTP bpt;
/* Read in a path */
bpt = v1read_bz_point(info);
pts_list = g_slist_append(pts_list,bpt);
}
}
else if(version == 2)
{
/* Had extra type field and points are stored as doubles */
info->cp += xcf_read_int32(info->fp, (guint32 *)&ptype,1);
while(num_points-- > 0)
{
PATHPOINTP bpt;
/* Read in a path */
bpt = read_bz_point(info);
pts_list = g_slist_append(pts_list,bpt);
}
}
else
{
g_warning("Unknown path type..Possibly corrupt XCF file");
}
bzp = bzpath_new(pts_list,closed,(gint)state,locked,name);
bzp = path_new(ptype,pts_list,closed,(gint)state,locked,name);
return(bzp);
}
@ -824,7 +864,7 @@ static PathsList * read_bzpaths(GImage *gimage, XcfInfo *info)
while(num_paths-- > 0)
{
BZPATHP bzp;
PATHP bzp;
/* Read in a path */
bzp = read_one_path(info);
bzp_list = g_slist_append(bzp_list,bzp);