From 4adf289ed606fa178f8eb85c1e078fa7766257cb Mon Sep 17 00:00:00 2001 From: GMT 1999 Andy Thomas Date: Mon, 22 Mar 1999 00:51:30 +0000 Subject: [PATCH] Changed:- Makefile.am internal_procs.c pathsP.h paths_dialog.c Mon Mar 22 00:38:20 GMT 1999 Andy Thomas 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 --- ChangeLog | 23 ++ app/Makefile.am | 2 + app/gui/paths-dialog.c | 497 ++++++++++++++++++++++--------- app/gui/paths-dialog.h | 4 +- app/internal_procs.c | 12 +- app/pathsP.h | 31 +- app/paths_cmds.c | 656 +++++++++++++++++++++++++++++++++++++++++ app/paths_cmds.h | 35 +++ app/paths_dialog.c | 497 ++++++++++++++++++++++--------- app/paths_dialog.h | 4 +- app/xcf.c | 88 ++++-- app/xcf/xcf.c | 88 ++++-- 12 files changed, 1593 insertions(+), 344 deletions(-) create mode 100644 app/paths_cmds.c create mode 100644 app/paths_cmds.h diff --git a/ChangeLog b/ChangeLog index a2b9005468..a4ea7ebaea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +Mon Mar 22 00:38:20 GMT 1999 Andy Thomas + + 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 * app/disp_callbacks.c app/edit_selection.c app/move.c: diff --git a/app/Makefile.am b/app/Makefile.am index 49203048de..4a67bf0a86 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -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 \ diff --git a/app/gui/paths-dialog.c b/app/gui/paths-dialog.c index 37f4556325..b87ad7ab18 100644 --- a/app/gui/paths-dialog.c +++ b/app/gui/paths-dialog.c @@ -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); +} diff --git a/app/gui/paths-dialog.h b/app/gui/paths-dialog.h index 9b1044e143..1c485c9805 100644 --- a/app/gui/paths-dialog.h +++ b/app/gui/paths-dialog.h @@ -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__ */ diff --git a/app/internal_procs.c b/app/internal_procs.c index 86cf52641d..5bd49ae0a4 100644 --- a/app/internal_procs.c +++ b/app/internal_procs.c @@ -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); diff --git a/app/pathsP.h b/app/pathsP.h index 155db13557..cba368eb5b 100644 --- a/app/pathsP.h +++ b/app/pathsP.h @@ -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__ */ diff --git a/app/paths_cmds.c b/app/paths_cmds.c new file mode 100644 index 0000000000..0c1eec4602 --- /dev/null +++ b/app/paths_cmds.c @@ -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 +#include +#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 } }, +}; diff --git a/app/paths_cmds.h b/app/paths_cmds.h new file mode 100644 index 0000000000..573f31925e --- /dev/null +++ b/app/paths_cmds.h @@ -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__ + + + diff --git a/app/paths_dialog.c b/app/paths_dialog.c index 37f4556325..b87ad7ab18 100644 --- a/app/paths_dialog.c +++ b/app/paths_dialog.c @@ -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); +} diff --git a/app/paths_dialog.h b/app/paths_dialog.h index 9b1044e143..1c485c9805 100644 --- a/app/paths_dialog.h +++ b/app/paths_dialog.h @@ -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__ */ diff --git a/app/xcf.c b/app/xcf.c index 9680195d4c..f30ef6722b 100644 --- a/app/xcf.c +++ b/app/xcf.c @@ -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); diff --git a/app/xcf/xcf.c b/app/xcf/xcf.c index 9680195d4c..f30ef6722b 100644 --- a/app/xcf/xcf.c +++ b/app/xcf/xcf.c @@ -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);