Iscissors was using rect_select_cursor_update which is totally wrong since

2000-03-02  Michael Natterer  <mitch@gimp.org>

	* app/iscissors.c: Iscissors was using rect_select_cursor_update
	which is totally wrong since the oper_update_func tool method was
	introduced (in fact it didn't even give correct feedback before).

	Added oper_update_func, modifier_key_func, cursor_update_func for
	Iscissors which give correct cursor_update feedback now. The only
	remaining inconsistency occurs when a curve is closed: There's no
	way to find out if the mouse is over a control point/line or
	outside (without touching the Iscissors engine, which I didn't
	want to do because I don't understand how it works ;-).
This commit is contained in:
Michael Natterer
2000-03-02 20:09:12 +00:00
committed by Michael Natterer
parent 2b1a1cf9bb
commit 6e48bd16b7
4 changed files with 1222 additions and 729 deletions

View File

@ -1,3 +1,16 @@
2000-03-02 Michael Natterer <mitch@gimp.org>
* app/iscissors.c: Iscissors was using rect_select_cursor_update
which is totally wrong since the oper_update_func tool method was
introduced (in fact it didn't even give correct feedback before).
Added oper_update_func, modifier_key_func, cursor_update_func for
Iscissors which give correct cursor_update feedback now. The only
remaining inconsistency occurs when a curve is closed: There's no
way to find out if the mouse is over a control point/line or
outside (without touching the Iscissors engine, which I didn't
want to do because I don't understand how it works ;-).
2000-03-02 Michael Natterer <mitch@gimp.org>
* app/channel_ops.c: s/"Fill Options"/"Fill Type"/

View File

@ -36,9 +36,12 @@
#include <stdlib.h>
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include "appenv.h"
#include "draw_core.h"
#include "channel_pvt.h"
#include "cursorutil.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -47,7 +50,6 @@
#include "iscissors.h"
#include "edit_selection.h"
#include "paint_funcs.h"
#include "rect_select.h"
#include "selection_options.h"
#include "temp_buf.h"
#include "tools.h"
@ -77,7 +79,8 @@ struct _ICurve
};
/* The possible states... */
typedef enum {
typedef enum
{
NO_ACTION,
SEED_PLACEMENT,
SEED_ADJUSTMENT,
@ -85,7 +88,8 @@ typedef enum {
} Iscissors_state;
/* The possible drawing states... */
typedef enum {
typedef enum
{
DRAW_NOTHING = 0x0,
DRAW_CURRENT_SEED = 0x1,
DRAW_CURVE = 0x2,
@ -99,9 +103,11 @@ struct _iscissors
{
DrawCore *core; /* Core select object */
int x, y; /* upper left hand coordinate */
int ix, iy; /* initial coordinates */
int nx, ny; /* new coordinates */
SelectOps op;
gint x, y; /* upper left hand coordinate */
gint ix, iy; /* initial coordinates */
gint nx, ny; /* new coordinates */
TempBuf *dp_buf; /* dynamic programming buffer */
@ -203,23 +209,23 @@ static GdkPoint curve_points [MAX_POINTS];
/* temporary convolution buffers -- */
D(static unsigned int sent0 = 0xd0d0d0d0);
static unsigned char maxgrad_conv0 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent1 = 0xd1d1d1d1);
static unsigned char maxgrad_conv1 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent2 = 0xd2d2d2d2);
static unsigned char maxgrad_conv2 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent3 = 0xd3d3d3d3);
D(static guint sent0 = 0xd0d0d0d0);
static guchar maxgrad_conv0 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent1 = 0xd1d1d1d1);
static guchar maxgrad_conv1 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent2 = 0xd2d2d2d2);
static guchar maxgrad_conv2 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent3 = 0xd3d3d3d3);
static int horz_deriv [9] =
static gint horz_deriv [9] =
{
1, 0, -1,
2, 0, -2,
1, 0, -1,
};
static int vert_deriv [9] =
static gint vert_deriv [9] =
{
1, 2, 1,
0, 0, 0,
@ -228,7 +234,7 @@ static int vert_deriv [9] =
#ifdef USE_LAPLACIAN
static int laplacian [9] =
static gint laplacian [9] =
{
-1, -1, -1,
-1, 8, -1,
@ -236,17 +242,17 @@ static int laplacian [9] =
};
#endif
static int blur_32 [9] =
static gint blur_32 [9] =
{
1, 1, 1,
1, 24, 1,
1, 1, 1,
};
static float distance_weights [GRADIENT_SEARCH * GRADIENT_SEARCH];
static gfloat distance_weights [GRADIENT_SEARCH * GRADIENT_SEARCH];
static int diagonal_weight [256];
static int direction_value [256][4];
static gint diagonal_weight [256];
static gint direction_value [256][4];
static gboolean initialized = FALSE;
static Tile *cur_tile = NULL;
@ -263,26 +269,46 @@ static IScissorsOptions *iscissors_options = NULL;
static void iscissors_button_press (Tool *, GdkEventButton *, gpointer);
static void iscissors_button_release (Tool *, GdkEventButton *, gpointer);
static void iscissors_motion (Tool *, GdkEventMotion *, gpointer);
static void iscissors_oper_update (Tool *, GdkEventMotion *, gpointer);
static void iscissors_modifier_update (Tool *, GdkEventKey *, gpointer);
static void iscissors_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void iscissors_control (Tool *, ToolAction, gpointer);
static void iscissors_reset (Iscissors *);
static void iscissors_draw (Tool *);
static void iscissors_reset (Iscissors *iscissors);
static void iscissors_draw (Tool *tool);
static TileManager * gradient_map_new (GImage *gimage);
static void find_optimal_path (TileManager *, TempBuf *, int, int,
int, int, int, int);
static void find_max_gradient (Iscissors *, GImage *, int *, int *);
static void calculate_curve (Tool *, ICurve *);
static void iscissors_draw_curve (GDisplay *, Iscissors *, ICurve *);
static void iscissors_free_icurves (GSList *);
static void iscissors_free_buffers (Iscissors *);
static int clicked_on_vertex (Tool *);
static int clicked_on_curve (Tool *);
static void find_optimal_path (TileManager *gradient_map,
TempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys);
static void find_max_gradient (Iscissors *iscissors,
GImage *gimage,
gint *x,
gint *y);
static void calculate_curve (Tool *tool,
ICurve *curve);
static void iscissors_draw_curve (GDisplay *gdisp,
Iscissors *iscissors,
ICurve *curve);
static void iscissors_free_icurves (GSList *list);
static void iscissors_free_buffers (Iscissors *iscissors);
static gint clicked_on_vertex (Tool *tool);
static gint clicked_on_curve (Tool *tool);
static void precalculate_arrays (void);
static GPtrArray *plot_pixels (Iscissors *, TempBuf *,
int, int, int, int, int, int);
static GPtrArray * plot_pixels (Iscissors *iscissors,
TempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye);
static void
iscissors_options_reset (void)
@ -322,6 +348,7 @@ tools_new_iscissors (void)
private = g_new (Iscissors, 1);
private->core = draw_core_new (iscissors_draw);
private->op = -1;
private->curves = NULL;
private->dp_buf = NULL;
private->state = NO_ACTION;
@ -335,7 +362,9 @@ tools_new_iscissors (void)
tool->button_press_func = iscissors_button_press;
tool->button_release_func = iscissors_button_release;
tool->motion_func = iscissors_motion;
tool->cursor_update_func = rect_select_cursor_update;
tool->oper_update_func = iscissors_oper_update;
tool->modifier_key_func = iscissors_modifier_update;
tool->cursor_update_func = iscissors_cursor_update;
tool->control_func = iscissors_control;
iscissors_reset (private);
@ -375,8 +404,7 @@ iscissors_button_press (Tool *tool,
GDisplay *gdisp;
GimpDrawable *drawable;
Iscissors *iscissors;
int grab_pointer = 0;
int replace, op;
gboolean grab_pointer = FALSE;
gdisp = (GDisplay *) gdisp_ptr;
iscissors = (Iscissors *) tool->private;
@ -404,20 +432,23 @@ iscissors_button_press (Tool *tool,
/* XXX what's this supposed to do? */
if (!(bevent->state & GDK_SHIFT_MASK) &&
!(bevent->state & GDK_CONTROL_MASK))
if (selection_point_inside (gdisp->select, gdisp_ptr, bevent->x, bevent->y))
if (selection_point_inside (gdisp->select, gdisp_ptr,
bevent->x, bevent->y))
{
init_edit_selection (tool, gdisp->select, gdisp_ptr, bevent->x, bevent->y);
init_edit_selection (tool, gdisp->select, gdisp_ptr,
bevent->x, bevent->y);
return;
}
#endif
iscissors->state = SEED_PLACEMENT;
iscissors->draw = DRAW_CURRENT_SEED;
grab_pointer = 1;
grab_pointer = TRUE;
if (! (bevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -437,31 +468,18 @@ iscissors_button_press (Tool *tool,
iscissors->state = SEED_ADJUSTMENT;
iscissors->draw = DRAW_ACTIVE_CURVE;
draw_core_resume (iscissors->core, tool);
grab_pointer = 1;
grab_pointer = TRUE;
}
/* If the iscissors is connected, check if the click was inside */
else if (iscissors->connected && iscissors->mask &&
channel_value (iscissors->mask, iscissors->x, iscissors->y))
{
/* Undraw the curve */
tool->state = INACTIVE;
iscissors->draw = DRAW_CURVE;
draw_core_stop (iscissors->core, tool);
replace = 0;
if (bevent->state & GDK_SHIFT_MASK)
op = ADD;
else if (bevent->state & GDK_CONTROL_MASK)
op = SUB;
else
{
op = ADD;
replace = 1;
}
if (replace)
if (iscissors->op == SELECTION_REPLACE)
gimage_mask_clear (gdisp->gimage);
else
gimage_mask_undo (gdisp->gimage);
@ -471,28 +489,25 @@ iscissors_button_press (Tool *tool,
gimage_get_mask (gdisp->gimage),
((SelectionOptions *) iscissors_options)->feather_radius,
((SelectionOptions *) iscissors_options)->feather_radius,
op, 0, 0);
iscissors->op, 0, 0);
else
channel_combine_mask (gimage_get_mask (gdisp->gimage),
iscissors->mask, op, 0, 0);
iscissors->mask, iscissors->op, 0, 0);
iscissors_reset (iscissors);
selection_start (gdisp->select, TRUE);
gdisplays_flush ();
}
/* if we're not connected, we're adding a new point */
else if (!iscissors->connected)
{
iscissors->state = SEED_PLACEMENT;
iscissors->draw = DRAW_CURRENT_SEED;
grab_pointer = 1;
grab_pointer = TRUE;
draw_core_resume (iscissors->core, tool);
}
break;
}
if (grab_pointer)
@ -505,7 +520,8 @@ iscissors_button_press (Tool *tool,
static void
iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
iscissors_convert (Iscissors *iscissors,
gpointer gdisp_ptr)
{
GDisplay *gdisp = (GDisplay *) gdisp_ptr;
ScanConverter *sc;
@ -514,8 +530,8 @@ iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
GSList *list;
ICurve *icurve;
guint packed;
int i;
int index;
gint i;
gint index;
sc = scan_converter_new (gdisp->gimage->width, gdisp->gimage->height, 1);
@ -551,7 +567,6 @@ iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
}
static void
iscissors_button_release (Tool *tool,
GdkEventButton *bevent,
@ -586,6 +601,7 @@ iscissors_button_release (Tool *tool,
default:
break;
}
draw_core_stop (iscissors->core, tool);
/* First take care of the case where the user "cancels" the action */
@ -615,7 +631,7 @@ iscissors_button_release (Tool *tool,
if (iscissors->ix != iscissors->x ||
iscissors->iy != iscissors->y)
{
curve = g_malloc (sizeof (ICurve));
curve = g_new (ICurve, 1);
curve->x1 = iscissors->ix;
curve->y1 = iscissors->iy;
@ -699,6 +715,7 @@ iscissors_motion (Tool *tool,
if (! (mevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -714,6 +731,7 @@ iscissors_motion (Tool *tool,
if (! (mevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -819,7 +837,6 @@ iscissors_draw (Tool *tool)
gdk_draw_arc (iscissors->core->win, iscissors->core->gc, 1,
txn - POINT_HALFWIDTH, tyn - POINT_HALFWIDTH,
POINT_WIDTH, POINT_WIDTH, 0, 23040);
}
}
@ -831,8 +848,8 @@ iscissors_draw_curve (GDisplay *gdisp,
{
gpointer *point;
guint len;
int tx, ty;
int npts;
gint tx, ty;
gint npts;
guint32 coords;
/* Uh, this shouldn't happen, but it does. So we ignore it.
@ -867,6 +884,135 @@ iscissors_draw_curve (GDisplay *gdisp,
curve_points, npts);
}
static void
iscissors_oper_update (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
GDisplay *gdisp;
gint x, y;
iscissors = (Iscissors *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&x, &y, FALSE, FALSE);
if (iscissors->connected && iscissors->mask &&
channel_value (iscissors->mask, x, y))
{
if (mevent->state & GDK_SHIFT_MASK &&
mevent->state & GDK_CONTROL_MASK)
{
iscissors->op = SELECTION_INTERSECT;
}
else if (mevent->state & GDK_SHIFT_MASK)
{
iscissors->op = SELECTION_ADD;
}
else if (mevent->state & GDK_CONTROL_MASK)
{
iscissors->op = SELECTION_SUB;
}
else
{
iscissors->op = SELECTION_REPLACE;
}
}
else
{
iscissors->op = -1;
}
}
static void
iscissors_modifier_update (Tool *tool,
GdkEventKey *kevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
SelectOps op;
iscissors = (Iscissors *) tool->private;
op = iscissors->op;
if (op == -1)
return;
switch (kevent->keyval)
{
case GDK_Shift_L: case GDK_Shift_R:
if (op == SELECTION_REPLACE)
op = SELECTION_ADD;
else if (op == SELECTION_ADD)
op = SELECTION_REPLACE;
else if (op == SELECTION_SUB)
op = SELECTION_INTERSECT;
else
op = SELECTION_SUB;
break;
case GDK_Control_L: case GDK_Control_R:
if (op == SELECTION_REPLACE)
op = SELECTION_SUB;
else if (op == SELECTION_ADD)
op = SELECTION_INTERSECT;
else if (op == SELECTION_SUB)
op = SELECTION_REPLACE;
else
op = SELECTION_ADD;
break;
}
iscissors->op = op;
}
static void
iscissors_cursor_update (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
GDisplay *gdisp;
iscissors = (Iscissors *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
if (iscissors->op != -1)
{
switch (iscissors->op)
{
case SELECTION_ADD:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_ADD_CURSOR);
break;
case SELECTION_SUB:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_SUBTRACT_CURSOR);
break;
case SELECTION_INTERSECT:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_INTERSECT_CURSOR);
break;
default:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_CURSOR);
break;
}
}
else
{
switch (iscissors->state)
{
case WAITING:
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE_POINT_CURSOR);
break;
case SEED_PLACEMENT:
case SEED_ADJUSTMENT:
default:
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE_CURSOR);
break;
}
}
}
static void
iscissors_control (Tool *tool,
@ -1004,8 +1150,7 @@ iscissors_free_buffers (Iscissors * iscissors)
/* XXX need some scan-conversion routines from somewhere. maybe. ? */
static int
static gboolean
clicked_on_vertex (Tool *tool)
{
Iscissors * iscissors;
@ -1033,14 +1178,14 @@ clicked_on_vertex (Tool *tool)
{
iscissors->curve1 = curve;
if (curves_found++)
return 1;
return TRUE;
}
else if (abs (curve->x2 - iscissors->x) < POINT_HALFWIDTH &&
abs (curve->y2 - iscissors->y) < POINT_HALFWIDTH)
{
iscissors->curve2 = curve;
if (curves_found++)
return 1;
return TRUE;
}
list = g_slist_next (list);
@ -1052,7 +1197,7 @@ clicked_on_vertex (Tool *tool)
*/
if (curves_found == 1)
{
return 0;
return FALSE;
}
/* no vertices were found at the cursor click point. Now check whether
@ -1063,16 +1208,16 @@ clicked_on_vertex (Tool *tool)
}
static int
static gboolean
clicked_on_curve (Tool *tool)
{
Iscissors *iscissors;
GSList *list, *new_link;
gpointer *pt;
int len;
gint len;
ICurve *curve, *new_curve;
guint32 coords;
int tx, ty;
gint tx, ty;
iscissors = (Iscissors *) tool->private;
@ -1126,21 +1271,21 @@ clicked_on_curve (Tool *tool)
/* Redraw the curve */
draw_core_resume (iscissors->core, tool);
return 1;
return TRUE;
}
}
list = g_slist_next (list);
}
return 0;
return FALSE;
}
static void
precalculate_arrays (void)
{
int i;
gint i;
for (i = 0; i < 256; i++)
{
@ -1168,17 +1313,17 @@ precalculate_arrays (void)
}
static void
calculate_curve (Tool *tool, ICurve *curve)
calculate_curve (Tool *tool,
ICurve *curve)
{
GDisplay *gdisp;
Iscissors *iscissors;
int x, y, dir;
int xs, ys, xe, ye;
int x1, y1, x2, y2;
int width, height;
int ewidth, eheight;
gint x, y, dir;
gint xs, ys, xe, ye;
gint x1, y1, x2, y2;
gint width, height;
gint ewidth, eheight;
TRC (("calculate_curve(%p, %p)\n", tool, curve));
@ -1284,15 +1429,16 @@ calculate_curve (Tool *tool, ICurve *curve)
x += dir;
}
}
}
/* badly need to get a replacement - this is _way_ too expensive */
static int
gradient_map_value (TileManager *map, int x, int y,
guint8 *grad, guint8 *dir)
static gboolean
gradient_map_value (TileManager *map,
gint x,
gint y,
guint8 *grad,
guint8 *dir)
{
static int cur_tilex;
static int cur_tiley;
@ -1306,7 +1452,7 @@ gradient_map_value (TileManager *map, int x, int y,
tile_release (cur_tile, FALSE);
cur_tile = tile_manager_get_tile (map, x, y, TRUE, FALSE);
if (!cur_tile)
return 0;
return FALSE;
cur_tilex = x / TILE_WIDTH;
cur_tiley = y / TILE_HEIGHT;
}
@ -1314,14 +1460,18 @@ gradient_map_value (TileManager *map, int x, int y,
p = tile_data_pointer (cur_tile, x % TILE_WIDTH, y % TILE_HEIGHT);
*grad = p[0];
*dir = p[1];
return 1;
return TRUE;
}
static int
static gint
calculate_link (TileManager *gradient_map,
int x, int y, guint32 pixel, int link)
gint x,
gint y,
guint32 pixel,
gint link)
{
int value = 0;
gint value = 0;
guint8 grad1, dir1, grad2, dir2;
if (!gradient_map_value (gradient_map, x, y, &grad1, &dir1))
@ -1356,22 +1506,26 @@ calculate_link (TileManager *gradient_map,
static GPtrArray *
plot_pixels (Iscissors *iscissors, TempBuf *dp_buf,
int x1, int y1,
int xs, int ys,
int xe, int ye)
plot_pixels (Iscissors *iscissors,
TempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye)
{
int x, y;
gint x, y;
guint32 coords;
int link;
int width;
unsigned int * data;
gint link;
gint width;
guint *data;
GPtrArray *list;
width = dp_buf->width;
/* Start the data pointer at the correct location */
data = (unsigned int *)temp_buf_data(dp_buf) + (ye - y1) * width + (xe - x1);
data = (guint *) temp_buf_data (dp_buf) + (ye - y1) * width + (xe - x1);
x = xe;
y = ye;
@ -1397,28 +1551,32 @@ plot_pixels (Iscissors *iscissors, TempBuf *dp_buf,
}
#define PACK(x, y) ((((y) & 0xff) << 8) | ((x) & 0xff))
#define OFFSET(pixel) ((gint8)((pixel) & 0xff) + \
((gint8)(((pixel) & 0xff00) >> 8)) * dp_buf->width)
static void
find_optimal_path (TileManager *gradient_map, TempBuf *dp_buf,
int x1, int y1, int x2, int y2,
int xs, int ys)
find_optimal_path (TileManager *gradient_map,
TempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys)
{
int i, j, k;
int x, y;
int link;
int linkdir;
int dirx, diry;
int min_cost;
int new_cost;
int offset;
int cum_cost [8];
int link_cost [8];
int pixel_cost [8];
gint i, j, k;
gint x, y;
gint link;
gint linkdir;
gint dirx, diry;
gint min_cost;
gint new_cost;
gint offset;
gint cum_cost [8];
gint link_cost [8];
gint pixel_cost [8];
guint32 pixel [8];
guint32 * data, *d;
@ -1543,18 +1701,18 @@ find_optimal_path (TileManager *gradient_map, TempBuf *dp_buf,
}
/* Called to fill in a newly referenced tile in the gradient map */
static void
gradmap_tile_validate (TileManager *tm, Tile *tile)
gradmap_tile_validate (TileManager *tm,
Tile *tile)
{
static gboolean first_gradient = TRUE;
int x, y;
int dw, dh;
int sw, sh;
int i, j;
int b;
float gradient;
gint x, y;
gint dw, dh;
gint sw, sh;
gint i, j;
gint b;
gfloat gradient;
guint8 *gradmap;
guint8 *tiledata;
guint8 *datah, *datav;
@ -1567,7 +1725,7 @@ gradmap_tile_validate (TileManager *tm, Tile *tile)
if (first_gradient)
{
int radius = GRADIENT_SEARCH >> 1;
gint radius = GRADIENT_SEARCH >> 1;
/* compute the distance weights */
for (i = 0; i < GRADIENT_SEARCH; i++)
for (j = 0; j < GRADIENT_SEARCH; j++)
@ -1653,7 +1811,7 @@ gradmap_tile_validate (TileManager *tm, Tile *tile)
/* then 1 byte direction */
if (gradient > MIN_GRADIENT)
{
float direction;
gfloat direction;
if (!hmax)
direction = (vmax > 0) ? G_PI_2 : -G_PI_2;
else
@ -1700,17 +1858,20 @@ gradient_map_new (GImage *gimage)
}
static void
find_max_gradient (Iscissors *iscissors, GImage *gimage, int *x, int *y)
find_max_gradient (Iscissors *iscissors,
GImage *gimage,
gint *x,
gint *y)
{
PixelRegion srcPR;
int radius;
int i, j;
int endx, endy;
int sx, sy, cx, cy;
int x1, y1, x2, y2;
gint radius;
gint i, j;
gint endx, endy;
gint sx, sy, cx, cy;
gint x1, y1, x2, y2;
void *pr;
guint8 *gradient;
float g, max_gradient;
gfloat g, max_gradient;
TRC (("find_max_gradient(%d, %d)\n", *x, *y));
@ -1768,5 +1929,4 @@ find_max_gradient (Iscissors *iscissors, GImage *gimage, int *x, int *y)
TRC (("done: find_max_gradient(%d, %d)\n", *x, *y));
}
/* End of iscissors.c */

View File

@ -36,9 +36,12 @@
#include <stdlib.h>
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include "appenv.h"
#include "draw_core.h"
#include "channel_pvt.h"
#include "cursorutil.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -47,7 +50,6 @@
#include "iscissors.h"
#include "edit_selection.h"
#include "paint_funcs.h"
#include "rect_select.h"
#include "selection_options.h"
#include "temp_buf.h"
#include "tools.h"
@ -77,7 +79,8 @@ struct _ICurve
};
/* The possible states... */
typedef enum {
typedef enum
{
NO_ACTION,
SEED_PLACEMENT,
SEED_ADJUSTMENT,
@ -85,7 +88,8 @@ typedef enum {
} Iscissors_state;
/* The possible drawing states... */
typedef enum {
typedef enum
{
DRAW_NOTHING = 0x0,
DRAW_CURRENT_SEED = 0x1,
DRAW_CURVE = 0x2,
@ -99,9 +103,11 @@ struct _iscissors
{
DrawCore *core; /* Core select object */
int x, y; /* upper left hand coordinate */
int ix, iy; /* initial coordinates */
int nx, ny; /* new coordinates */
SelectOps op;
gint x, y; /* upper left hand coordinate */
gint ix, iy; /* initial coordinates */
gint nx, ny; /* new coordinates */
TempBuf *dp_buf; /* dynamic programming buffer */
@ -203,23 +209,23 @@ static GdkPoint curve_points [MAX_POINTS];
/* temporary convolution buffers -- */
D(static unsigned int sent0 = 0xd0d0d0d0);
static unsigned char maxgrad_conv0 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent1 = 0xd1d1d1d1);
static unsigned char maxgrad_conv1 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent2 = 0xd2d2d2d2);
static unsigned char maxgrad_conv2 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent3 = 0xd3d3d3d3);
D(static guint sent0 = 0xd0d0d0d0);
static guchar maxgrad_conv0 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent1 = 0xd1d1d1d1);
static guchar maxgrad_conv1 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent2 = 0xd2d2d2d2);
static guchar maxgrad_conv2 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent3 = 0xd3d3d3d3);
static int horz_deriv [9] =
static gint horz_deriv [9] =
{
1, 0, -1,
2, 0, -2,
1, 0, -1,
};
static int vert_deriv [9] =
static gint vert_deriv [9] =
{
1, 2, 1,
0, 0, 0,
@ -228,7 +234,7 @@ static int vert_deriv [9] =
#ifdef USE_LAPLACIAN
static int laplacian [9] =
static gint laplacian [9] =
{
-1, -1, -1,
-1, 8, -1,
@ -236,17 +242,17 @@ static int laplacian [9] =
};
#endif
static int blur_32 [9] =
static gint blur_32 [9] =
{
1, 1, 1,
1, 24, 1,
1, 1, 1,
};
static float distance_weights [GRADIENT_SEARCH * GRADIENT_SEARCH];
static gfloat distance_weights [GRADIENT_SEARCH * GRADIENT_SEARCH];
static int diagonal_weight [256];
static int direction_value [256][4];
static gint diagonal_weight [256];
static gint direction_value [256][4];
static gboolean initialized = FALSE;
static Tile *cur_tile = NULL;
@ -263,26 +269,46 @@ static IScissorsOptions *iscissors_options = NULL;
static void iscissors_button_press (Tool *, GdkEventButton *, gpointer);
static void iscissors_button_release (Tool *, GdkEventButton *, gpointer);
static void iscissors_motion (Tool *, GdkEventMotion *, gpointer);
static void iscissors_oper_update (Tool *, GdkEventMotion *, gpointer);
static void iscissors_modifier_update (Tool *, GdkEventKey *, gpointer);
static void iscissors_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void iscissors_control (Tool *, ToolAction, gpointer);
static void iscissors_reset (Iscissors *);
static void iscissors_draw (Tool *);
static void iscissors_reset (Iscissors *iscissors);
static void iscissors_draw (Tool *tool);
static TileManager * gradient_map_new (GImage *gimage);
static void find_optimal_path (TileManager *, TempBuf *, int, int,
int, int, int, int);
static void find_max_gradient (Iscissors *, GImage *, int *, int *);
static void calculate_curve (Tool *, ICurve *);
static void iscissors_draw_curve (GDisplay *, Iscissors *, ICurve *);
static void iscissors_free_icurves (GSList *);
static void iscissors_free_buffers (Iscissors *);
static int clicked_on_vertex (Tool *);
static int clicked_on_curve (Tool *);
static void find_optimal_path (TileManager *gradient_map,
TempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys);
static void find_max_gradient (Iscissors *iscissors,
GImage *gimage,
gint *x,
gint *y);
static void calculate_curve (Tool *tool,
ICurve *curve);
static void iscissors_draw_curve (GDisplay *gdisp,
Iscissors *iscissors,
ICurve *curve);
static void iscissors_free_icurves (GSList *list);
static void iscissors_free_buffers (Iscissors *iscissors);
static gint clicked_on_vertex (Tool *tool);
static gint clicked_on_curve (Tool *tool);
static void precalculate_arrays (void);
static GPtrArray *plot_pixels (Iscissors *, TempBuf *,
int, int, int, int, int, int);
static GPtrArray * plot_pixels (Iscissors *iscissors,
TempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye);
static void
iscissors_options_reset (void)
@ -322,6 +348,7 @@ tools_new_iscissors (void)
private = g_new (Iscissors, 1);
private->core = draw_core_new (iscissors_draw);
private->op = -1;
private->curves = NULL;
private->dp_buf = NULL;
private->state = NO_ACTION;
@ -335,7 +362,9 @@ tools_new_iscissors (void)
tool->button_press_func = iscissors_button_press;
tool->button_release_func = iscissors_button_release;
tool->motion_func = iscissors_motion;
tool->cursor_update_func = rect_select_cursor_update;
tool->oper_update_func = iscissors_oper_update;
tool->modifier_key_func = iscissors_modifier_update;
tool->cursor_update_func = iscissors_cursor_update;
tool->control_func = iscissors_control;
iscissors_reset (private);
@ -375,8 +404,7 @@ iscissors_button_press (Tool *tool,
GDisplay *gdisp;
GimpDrawable *drawable;
Iscissors *iscissors;
int grab_pointer = 0;
int replace, op;
gboolean grab_pointer = FALSE;
gdisp = (GDisplay *) gdisp_ptr;
iscissors = (Iscissors *) tool->private;
@ -404,20 +432,23 @@ iscissors_button_press (Tool *tool,
/* XXX what's this supposed to do? */
if (!(bevent->state & GDK_SHIFT_MASK) &&
!(bevent->state & GDK_CONTROL_MASK))
if (selection_point_inside (gdisp->select, gdisp_ptr, bevent->x, bevent->y))
if (selection_point_inside (gdisp->select, gdisp_ptr,
bevent->x, bevent->y))
{
init_edit_selection (tool, gdisp->select, gdisp_ptr, bevent->x, bevent->y);
init_edit_selection (tool, gdisp->select, gdisp_ptr,
bevent->x, bevent->y);
return;
}
#endif
iscissors->state = SEED_PLACEMENT;
iscissors->draw = DRAW_CURRENT_SEED;
grab_pointer = 1;
grab_pointer = TRUE;
if (! (bevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -437,31 +468,18 @@ iscissors_button_press (Tool *tool,
iscissors->state = SEED_ADJUSTMENT;
iscissors->draw = DRAW_ACTIVE_CURVE;
draw_core_resume (iscissors->core, tool);
grab_pointer = 1;
grab_pointer = TRUE;
}
/* If the iscissors is connected, check if the click was inside */
else if (iscissors->connected && iscissors->mask &&
channel_value (iscissors->mask, iscissors->x, iscissors->y))
{
/* Undraw the curve */
tool->state = INACTIVE;
iscissors->draw = DRAW_CURVE;
draw_core_stop (iscissors->core, tool);
replace = 0;
if (bevent->state & GDK_SHIFT_MASK)
op = ADD;
else if (bevent->state & GDK_CONTROL_MASK)
op = SUB;
else
{
op = ADD;
replace = 1;
}
if (replace)
if (iscissors->op == SELECTION_REPLACE)
gimage_mask_clear (gdisp->gimage);
else
gimage_mask_undo (gdisp->gimage);
@ -471,28 +489,25 @@ iscissors_button_press (Tool *tool,
gimage_get_mask (gdisp->gimage),
((SelectionOptions *) iscissors_options)->feather_radius,
((SelectionOptions *) iscissors_options)->feather_radius,
op, 0, 0);
iscissors->op, 0, 0);
else
channel_combine_mask (gimage_get_mask (gdisp->gimage),
iscissors->mask, op, 0, 0);
iscissors->mask, iscissors->op, 0, 0);
iscissors_reset (iscissors);
selection_start (gdisp->select, TRUE);
gdisplays_flush ();
}
/* if we're not connected, we're adding a new point */
else if (!iscissors->connected)
{
iscissors->state = SEED_PLACEMENT;
iscissors->draw = DRAW_CURRENT_SEED;
grab_pointer = 1;
grab_pointer = TRUE;
draw_core_resume (iscissors->core, tool);
}
break;
}
if (grab_pointer)
@ -505,7 +520,8 @@ iscissors_button_press (Tool *tool,
static void
iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
iscissors_convert (Iscissors *iscissors,
gpointer gdisp_ptr)
{
GDisplay *gdisp = (GDisplay *) gdisp_ptr;
ScanConverter *sc;
@ -514,8 +530,8 @@ iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
GSList *list;
ICurve *icurve;
guint packed;
int i;
int index;
gint i;
gint index;
sc = scan_converter_new (gdisp->gimage->width, gdisp->gimage->height, 1);
@ -551,7 +567,6 @@ iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
}
static void
iscissors_button_release (Tool *tool,
GdkEventButton *bevent,
@ -586,6 +601,7 @@ iscissors_button_release (Tool *tool,
default:
break;
}
draw_core_stop (iscissors->core, tool);
/* First take care of the case where the user "cancels" the action */
@ -615,7 +631,7 @@ iscissors_button_release (Tool *tool,
if (iscissors->ix != iscissors->x ||
iscissors->iy != iscissors->y)
{
curve = g_malloc (sizeof (ICurve));
curve = g_new (ICurve, 1);
curve->x1 = iscissors->ix;
curve->y1 = iscissors->iy;
@ -699,6 +715,7 @@ iscissors_motion (Tool *tool,
if (! (mevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -714,6 +731,7 @@ iscissors_motion (Tool *tool,
if (! (mevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -819,7 +837,6 @@ iscissors_draw (Tool *tool)
gdk_draw_arc (iscissors->core->win, iscissors->core->gc, 1,
txn - POINT_HALFWIDTH, tyn - POINT_HALFWIDTH,
POINT_WIDTH, POINT_WIDTH, 0, 23040);
}
}
@ -831,8 +848,8 @@ iscissors_draw_curve (GDisplay *gdisp,
{
gpointer *point;
guint len;
int tx, ty;
int npts;
gint tx, ty;
gint npts;
guint32 coords;
/* Uh, this shouldn't happen, but it does. So we ignore it.
@ -867,6 +884,135 @@ iscissors_draw_curve (GDisplay *gdisp,
curve_points, npts);
}
static void
iscissors_oper_update (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
GDisplay *gdisp;
gint x, y;
iscissors = (Iscissors *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&x, &y, FALSE, FALSE);
if (iscissors->connected && iscissors->mask &&
channel_value (iscissors->mask, x, y))
{
if (mevent->state & GDK_SHIFT_MASK &&
mevent->state & GDK_CONTROL_MASK)
{
iscissors->op = SELECTION_INTERSECT;
}
else if (mevent->state & GDK_SHIFT_MASK)
{
iscissors->op = SELECTION_ADD;
}
else if (mevent->state & GDK_CONTROL_MASK)
{
iscissors->op = SELECTION_SUB;
}
else
{
iscissors->op = SELECTION_REPLACE;
}
}
else
{
iscissors->op = -1;
}
}
static void
iscissors_modifier_update (Tool *tool,
GdkEventKey *kevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
SelectOps op;
iscissors = (Iscissors *) tool->private;
op = iscissors->op;
if (op == -1)
return;
switch (kevent->keyval)
{
case GDK_Shift_L: case GDK_Shift_R:
if (op == SELECTION_REPLACE)
op = SELECTION_ADD;
else if (op == SELECTION_ADD)
op = SELECTION_REPLACE;
else if (op == SELECTION_SUB)
op = SELECTION_INTERSECT;
else
op = SELECTION_SUB;
break;
case GDK_Control_L: case GDK_Control_R:
if (op == SELECTION_REPLACE)
op = SELECTION_SUB;
else if (op == SELECTION_ADD)
op = SELECTION_INTERSECT;
else if (op == SELECTION_SUB)
op = SELECTION_REPLACE;
else
op = SELECTION_ADD;
break;
}
iscissors->op = op;
}
static void
iscissors_cursor_update (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
GDisplay *gdisp;
iscissors = (Iscissors *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
if (iscissors->op != -1)
{
switch (iscissors->op)
{
case SELECTION_ADD:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_ADD_CURSOR);
break;
case SELECTION_SUB:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_SUBTRACT_CURSOR);
break;
case SELECTION_INTERSECT:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_INTERSECT_CURSOR);
break;
default:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_CURSOR);
break;
}
}
else
{
switch (iscissors->state)
{
case WAITING:
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE_POINT_CURSOR);
break;
case SEED_PLACEMENT:
case SEED_ADJUSTMENT:
default:
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE_CURSOR);
break;
}
}
}
static void
iscissors_control (Tool *tool,
@ -1004,8 +1150,7 @@ iscissors_free_buffers (Iscissors * iscissors)
/* XXX need some scan-conversion routines from somewhere. maybe. ? */
static int
static gboolean
clicked_on_vertex (Tool *tool)
{
Iscissors * iscissors;
@ -1033,14 +1178,14 @@ clicked_on_vertex (Tool *tool)
{
iscissors->curve1 = curve;
if (curves_found++)
return 1;
return TRUE;
}
else if (abs (curve->x2 - iscissors->x) < POINT_HALFWIDTH &&
abs (curve->y2 - iscissors->y) < POINT_HALFWIDTH)
{
iscissors->curve2 = curve;
if (curves_found++)
return 1;
return TRUE;
}
list = g_slist_next (list);
@ -1052,7 +1197,7 @@ clicked_on_vertex (Tool *tool)
*/
if (curves_found == 1)
{
return 0;
return FALSE;
}
/* no vertices were found at the cursor click point. Now check whether
@ -1063,16 +1208,16 @@ clicked_on_vertex (Tool *tool)
}
static int
static gboolean
clicked_on_curve (Tool *tool)
{
Iscissors *iscissors;
GSList *list, *new_link;
gpointer *pt;
int len;
gint len;
ICurve *curve, *new_curve;
guint32 coords;
int tx, ty;
gint tx, ty;
iscissors = (Iscissors *) tool->private;
@ -1126,21 +1271,21 @@ clicked_on_curve (Tool *tool)
/* Redraw the curve */
draw_core_resume (iscissors->core, tool);
return 1;
return TRUE;
}
}
list = g_slist_next (list);
}
return 0;
return FALSE;
}
static void
precalculate_arrays (void)
{
int i;
gint i;
for (i = 0; i < 256; i++)
{
@ -1168,17 +1313,17 @@ precalculate_arrays (void)
}
static void
calculate_curve (Tool *tool, ICurve *curve)
calculate_curve (Tool *tool,
ICurve *curve)
{
GDisplay *gdisp;
Iscissors *iscissors;
int x, y, dir;
int xs, ys, xe, ye;
int x1, y1, x2, y2;
int width, height;
int ewidth, eheight;
gint x, y, dir;
gint xs, ys, xe, ye;
gint x1, y1, x2, y2;
gint width, height;
gint ewidth, eheight;
TRC (("calculate_curve(%p, %p)\n", tool, curve));
@ -1284,15 +1429,16 @@ calculate_curve (Tool *tool, ICurve *curve)
x += dir;
}
}
}
/* badly need to get a replacement - this is _way_ too expensive */
static int
gradient_map_value (TileManager *map, int x, int y,
guint8 *grad, guint8 *dir)
static gboolean
gradient_map_value (TileManager *map,
gint x,
gint y,
guint8 *grad,
guint8 *dir)
{
static int cur_tilex;
static int cur_tiley;
@ -1306,7 +1452,7 @@ gradient_map_value (TileManager *map, int x, int y,
tile_release (cur_tile, FALSE);
cur_tile = tile_manager_get_tile (map, x, y, TRUE, FALSE);
if (!cur_tile)
return 0;
return FALSE;
cur_tilex = x / TILE_WIDTH;
cur_tiley = y / TILE_HEIGHT;
}
@ -1314,14 +1460,18 @@ gradient_map_value (TileManager *map, int x, int y,
p = tile_data_pointer (cur_tile, x % TILE_WIDTH, y % TILE_HEIGHT);
*grad = p[0];
*dir = p[1];
return 1;
return TRUE;
}
static int
static gint
calculate_link (TileManager *gradient_map,
int x, int y, guint32 pixel, int link)
gint x,
gint y,
guint32 pixel,
gint link)
{
int value = 0;
gint value = 0;
guint8 grad1, dir1, grad2, dir2;
if (!gradient_map_value (gradient_map, x, y, &grad1, &dir1))
@ -1356,22 +1506,26 @@ calculate_link (TileManager *gradient_map,
static GPtrArray *
plot_pixels (Iscissors *iscissors, TempBuf *dp_buf,
int x1, int y1,
int xs, int ys,
int xe, int ye)
plot_pixels (Iscissors *iscissors,
TempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye)
{
int x, y;
gint x, y;
guint32 coords;
int link;
int width;
unsigned int * data;
gint link;
gint width;
guint *data;
GPtrArray *list;
width = dp_buf->width;
/* Start the data pointer at the correct location */
data = (unsigned int *)temp_buf_data(dp_buf) + (ye - y1) * width + (xe - x1);
data = (guint *) temp_buf_data (dp_buf) + (ye - y1) * width + (xe - x1);
x = xe;
y = ye;
@ -1397,28 +1551,32 @@ plot_pixels (Iscissors *iscissors, TempBuf *dp_buf,
}
#define PACK(x, y) ((((y) & 0xff) << 8) | ((x) & 0xff))
#define OFFSET(pixel) ((gint8)((pixel) & 0xff) + \
((gint8)(((pixel) & 0xff00) >> 8)) * dp_buf->width)
static void
find_optimal_path (TileManager *gradient_map, TempBuf *dp_buf,
int x1, int y1, int x2, int y2,
int xs, int ys)
find_optimal_path (TileManager *gradient_map,
TempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys)
{
int i, j, k;
int x, y;
int link;
int linkdir;
int dirx, diry;
int min_cost;
int new_cost;
int offset;
int cum_cost [8];
int link_cost [8];
int pixel_cost [8];
gint i, j, k;
gint x, y;
gint link;
gint linkdir;
gint dirx, diry;
gint min_cost;
gint new_cost;
gint offset;
gint cum_cost [8];
gint link_cost [8];
gint pixel_cost [8];
guint32 pixel [8];
guint32 * data, *d;
@ -1543,18 +1701,18 @@ find_optimal_path (TileManager *gradient_map, TempBuf *dp_buf,
}
/* Called to fill in a newly referenced tile in the gradient map */
static void
gradmap_tile_validate (TileManager *tm, Tile *tile)
gradmap_tile_validate (TileManager *tm,
Tile *tile)
{
static gboolean first_gradient = TRUE;
int x, y;
int dw, dh;
int sw, sh;
int i, j;
int b;
float gradient;
gint x, y;
gint dw, dh;
gint sw, sh;
gint i, j;
gint b;
gfloat gradient;
guint8 *gradmap;
guint8 *tiledata;
guint8 *datah, *datav;
@ -1567,7 +1725,7 @@ gradmap_tile_validate (TileManager *tm, Tile *tile)
if (first_gradient)
{
int radius = GRADIENT_SEARCH >> 1;
gint radius = GRADIENT_SEARCH >> 1;
/* compute the distance weights */
for (i = 0; i < GRADIENT_SEARCH; i++)
for (j = 0; j < GRADIENT_SEARCH; j++)
@ -1653,7 +1811,7 @@ gradmap_tile_validate (TileManager *tm, Tile *tile)
/* then 1 byte direction */
if (gradient > MIN_GRADIENT)
{
float direction;
gfloat direction;
if (!hmax)
direction = (vmax > 0) ? G_PI_2 : -G_PI_2;
else
@ -1700,17 +1858,20 @@ gradient_map_new (GImage *gimage)
}
static void
find_max_gradient (Iscissors *iscissors, GImage *gimage, int *x, int *y)
find_max_gradient (Iscissors *iscissors,
GImage *gimage,
gint *x,
gint *y)
{
PixelRegion srcPR;
int radius;
int i, j;
int endx, endy;
int sx, sy, cx, cy;
int x1, y1, x2, y2;
gint radius;
gint i, j;
gint endx, endy;
gint sx, sy, cx, cy;
gint x1, y1, x2, y2;
void *pr;
guint8 *gradient;
float g, max_gradient;
gfloat g, max_gradient;
TRC (("find_max_gradient(%d, %d)\n", *x, *y));
@ -1768,5 +1929,4 @@ find_max_gradient (Iscissors *iscissors, GImage *gimage, int *x, int *y)
TRC (("done: find_max_gradient(%d, %d)\n", *x, *y));
}
/* End of iscissors.c */

View File

@ -36,9 +36,12 @@
#include <stdlib.h>
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include "appenv.h"
#include "draw_core.h"
#include "channel_pvt.h"
#include "cursorutil.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -47,7 +50,6 @@
#include "iscissors.h"
#include "edit_selection.h"
#include "paint_funcs.h"
#include "rect_select.h"
#include "selection_options.h"
#include "temp_buf.h"
#include "tools.h"
@ -77,7 +79,8 @@ struct _ICurve
};
/* The possible states... */
typedef enum {
typedef enum
{
NO_ACTION,
SEED_PLACEMENT,
SEED_ADJUSTMENT,
@ -85,7 +88,8 @@ typedef enum {
} Iscissors_state;
/* The possible drawing states... */
typedef enum {
typedef enum
{
DRAW_NOTHING = 0x0,
DRAW_CURRENT_SEED = 0x1,
DRAW_CURVE = 0x2,
@ -99,9 +103,11 @@ struct _iscissors
{
DrawCore *core; /* Core select object */
int x, y; /* upper left hand coordinate */
int ix, iy; /* initial coordinates */
int nx, ny; /* new coordinates */
SelectOps op;
gint x, y; /* upper left hand coordinate */
gint ix, iy; /* initial coordinates */
gint nx, ny; /* new coordinates */
TempBuf *dp_buf; /* dynamic programming buffer */
@ -203,23 +209,23 @@ static GdkPoint curve_points [MAX_POINTS];
/* temporary convolution buffers -- */
D(static unsigned int sent0 = 0xd0d0d0d0);
static unsigned char maxgrad_conv0 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent1 = 0xd1d1d1d1);
static unsigned char maxgrad_conv1 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent2 = 0xd2d2d2d2);
static unsigned char maxgrad_conv2 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static unsigned int sent3 = 0xd3d3d3d3);
D(static guint sent0 = 0xd0d0d0d0);
static guchar maxgrad_conv0 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent1 = 0xd1d1d1d1);
static guchar maxgrad_conv1 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent2 = 0xd2d2d2d2);
static guchar maxgrad_conv2 [TILE_WIDTH * TILE_HEIGHT * 4] = "";
D(static guint sent3 = 0xd3d3d3d3);
static int horz_deriv [9] =
static gint horz_deriv [9] =
{
1, 0, -1,
2, 0, -2,
1, 0, -1,
};
static int vert_deriv [9] =
static gint vert_deriv [9] =
{
1, 2, 1,
0, 0, 0,
@ -228,7 +234,7 @@ static int vert_deriv [9] =
#ifdef USE_LAPLACIAN
static int laplacian [9] =
static gint laplacian [9] =
{
-1, -1, -1,
-1, 8, -1,
@ -236,17 +242,17 @@ static int laplacian [9] =
};
#endif
static int blur_32 [9] =
static gint blur_32 [9] =
{
1, 1, 1,
1, 24, 1,
1, 1, 1,
};
static float distance_weights [GRADIENT_SEARCH * GRADIENT_SEARCH];
static gfloat distance_weights [GRADIENT_SEARCH * GRADIENT_SEARCH];
static int diagonal_weight [256];
static int direction_value [256][4];
static gint diagonal_weight [256];
static gint direction_value [256][4];
static gboolean initialized = FALSE;
static Tile *cur_tile = NULL;
@ -263,26 +269,46 @@ static IScissorsOptions *iscissors_options = NULL;
static void iscissors_button_press (Tool *, GdkEventButton *, gpointer);
static void iscissors_button_release (Tool *, GdkEventButton *, gpointer);
static void iscissors_motion (Tool *, GdkEventMotion *, gpointer);
static void iscissors_oper_update (Tool *, GdkEventMotion *, gpointer);
static void iscissors_modifier_update (Tool *, GdkEventKey *, gpointer);
static void iscissors_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void iscissors_control (Tool *, ToolAction, gpointer);
static void iscissors_reset (Iscissors *);
static void iscissors_draw (Tool *);
static void iscissors_reset (Iscissors *iscissors);
static void iscissors_draw (Tool *tool);
static TileManager * gradient_map_new (GImage *gimage);
static void find_optimal_path (TileManager *, TempBuf *, int, int,
int, int, int, int);
static void find_max_gradient (Iscissors *, GImage *, int *, int *);
static void calculate_curve (Tool *, ICurve *);
static void iscissors_draw_curve (GDisplay *, Iscissors *, ICurve *);
static void iscissors_free_icurves (GSList *);
static void iscissors_free_buffers (Iscissors *);
static int clicked_on_vertex (Tool *);
static int clicked_on_curve (Tool *);
static void find_optimal_path (TileManager *gradient_map,
TempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys);
static void find_max_gradient (Iscissors *iscissors,
GImage *gimage,
gint *x,
gint *y);
static void calculate_curve (Tool *tool,
ICurve *curve);
static void iscissors_draw_curve (GDisplay *gdisp,
Iscissors *iscissors,
ICurve *curve);
static void iscissors_free_icurves (GSList *list);
static void iscissors_free_buffers (Iscissors *iscissors);
static gint clicked_on_vertex (Tool *tool);
static gint clicked_on_curve (Tool *tool);
static void precalculate_arrays (void);
static GPtrArray *plot_pixels (Iscissors *, TempBuf *,
int, int, int, int, int, int);
static GPtrArray * plot_pixels (Iscissors *iscissors,
TempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye);
static void
iscissors_options_reset (void)
@ -322,6 +348,7 @@ tools_new_iscissors (void)
private = g_new (Iscissors, 1);
private->core = draw_core_new (iscissors_draw);
private->op = -1;
private->curves = NULL;
private->dp_buf = NULL;
private->state = NO_ACTION;
@ -335,7 +362,9 @@ tools_new_iscissors (void)
tool->button_press_func = iscissors_button_press;
tool->button_release_func = iscissors_button_release;
tool->motion_func = iscissors_motion;
tool->cursor_update_func = rect_select_cursor_update;
tool->oper_update_func = iscissors_oper_update;
tool->modifier_key_func = iscissors_modifier_update;
tool->cursor_update_func = iscissors_cursor_update;
tool->control_func = iscissors_control;
iscissors_reset (private);
@ -375,8 +404,7 @@ iscissors_button_press (Tool *tool,
GDisplay *gdisp;
GimpDrawable *drawable;
Iscissors *iscissors;
int grab_pointer = 0;
int replace, op;
gboolean grab_pointer = FALSE;
gdisp = (GDisplay *) gdisp_ptr;
iscissors = (Iscissors *) tool->private;
@ -404,20 +432,23 @@ iscissors_button_press (Tool *tool,
/* XXX what's this supposed to do? */
if (!(bevent->state & GDK_SHIFT_MASK) &&
!(bevent->state & GDK_CONTROL_MASK))
if (selection_point_inside (gdisp->select, gdisp_ptr, bevent->x, bevent->y))
if (selection_point_inside (gdisp->select, gdisp_ptr,
bevent->x, bevent->y))
{
init_edit_selection (tool, gdisp->select, gdisp_ptr, bevent->x, bevent->y);
init_edit_selection (tool, gdisp->select, gdisp_ptr,
bevent->x, bevent->y);
return;
}
#endif
iscissors->state = SEED_PLACEMENT;
iscissors->draw = DRAW_CURRENT_SEED;
grab_pointer = 1;
grab_pointer = TRUE;
if (! (bevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -437,31 +468,18 @@ iscissors_button_press (Tool *tool,
iscissors->state = SEED_ADJUSTMENT;
iscissors->draw = DRAW_ACTIVE_CURVE;
draw_core_resume (iscissors->core, tool);
grab_pointer = 1;
grab_pointer = TRUE;
}
/* If the iscissors is connected, check if the click was inside */
else if (iscissors->connected && iscissors->mask &&
channel_value (iscissors->mask, iscissors->x, iscissors->y))
{
/* Undraw the curve */
tool->state = INACTIVE;
iscissors->draw = DRAW_CURVE;
draw_core_stop (iscissors->core, tool);
replace = 0;
if (bevent->state & GDK_SHIFT_MASK)
op = ADD;
else if (bevent->state & GDK_CONTROL_MASK)
op = SUB;
else
{
op = ADD;
replace = 1;
}
if (replace)
if (iscissors->op == SELECTION_REPLACE)
gimage_mask_clear (gdisp->gimage);
else
gimage_mask_undo (gdisp->gimage);
@ -471,28 +489,25 @@ iscissors_button_press (Tool *tool,
gimage_get_mask (gdisp->gimage),
((SelectionOptions *) iscissors_options)->feather_radius,
((SelectionOptions *) iscissors_options)->feather_radius,
op, 0, 0);
iscissors->op, 0, 0);
else
channel_combine_mask (gimage_get_mask (gdisp->gimage),
iscissors->mask, op, 0, 0);
iscissors->mask, iscissors->op, 0, 0);
iscissors_reset (iscissors);
selection_start (gdisp->select, TRUE);
gdisplays_flush ();
}
/* if we're not connected, we're adding a new point */
else if (!iscissors->connected)
{
iscissors->state = SEED_PLACEMENT;
iscissors->draw = DRAW_CURRENT_SEED;
grab_pointer = 1;
grab_pointer = TRUE;
draw_core_resume (iscissors->core, tool);
}
break;
}
if (grab_pointer)
@ -505,7 +520,8 @@ iscissors_button_press (Tool *tool,
static void
iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
iscissors_convert (Iscissors *iscissors,
gpointer gdisp_ptr)
{
GDisplay *gdisp = (GDisplay *) gdisp_ptr;
ScanConverter *sc;
@ -514,8 +530,8 @@ iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
GSList *list;
ICurve *icurve;
guint packed;
int i;
int index;
gint i;
gint index;
sc = scan_converter_new (gdisp->gimage->width, gdisp->gimage->height, 1);
@ -551,7 +567,6 @@ iscissors_convert (Iscissors *iscissors, gpointer gdisp_ptr)
}
static void
iscissors_button_release (Tool *tool,
GdkEventButton *bevent,
@ -586,6 +601,7 @@ iscissors_button_release (Tool *tool,
default:
break;
}
draw_core_stop (iscissors->core, tool);
/* First take care of the case where the user "cancels" the action */
@ -615,7 +631,7 @@ iscissors_button_release (Tool *tool,
if (iscissors->ix != iscissors->x ||
iscissors->iy != iscissors->y)
{
curve = g_malloc (sizeof (ICurve));
curve = g_new (ICurve, 1);
curve->x1 = iscissors->ix;
curve->y1 = iscissors->iy;
@ -699,6 +715,7 @@ iscissors_motion (Tool *tool,
if (! (mevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -714,6 +731,7 @@ iscissors_motion (Tool *tool,
if (! (mevent->state & GDK_SHIFT_MASK))
find_max_gradient (iscissors, gdisp->gimage,
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gdisp->gimage->width - 1);
iscissors->y = CLAMP (iscissors->y, 0, gdisp->gimage->height - 1);
@ -819,7 +837,6 @@ iscissors_draw (Tool *tool)
gdk_draw_arc (iscissors->core->win, iscissors->core->gc, 1,
txn - POINT_HALFWIDTH, tyn - POINT_HALFWIDTH,
POINT_WIDTH, POINT_WIDTH, 0, 23040);
}
}
@ -831,8 +848,8 @@ iscissors_draw_curve (GDisplay *gdisp,
{
gpointer *point;
guint len;
int tx, ty;
int npts;
gint tx, ty;
gint npts;
guint32 coords;
/* Uh, this shouldn't happen, but it does. So we ignore it.
@ -867,6 +884,135 @@ iscissors_draw_curve (GDisplay *gdisp,
curve_points, npts);
}
static void
iscissors_oper_update (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
GDisplay *gdisp;
gint x, y;
iscissors = (Iscissors *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&x, &y, FALSE, FALSE);
if (iscissors->connected && iscissors->mask &&
channel_value (iscissors->mask, x, y))
{
if (mevent->state & GDK_SHIFT_MASK &&
mevent->state & GDK_CONTROL_MASK)
{
iscissors->op = SELECTION_INTERSECT;
}
else if (mevent->state & GDK_SHIFT_MASK)
{
iscissors->op = SELECTION_ADD;
}
else if (mevent->state & GDK_CONTROL_MASK)
{
iscissors->op = SELECTION_SUB;
}
else
{
iscissors->op = SELECTION_REPLACE;
}
}
else
{
iscissors->op = -1;
}
}
static void
iscissors_modifier_update (Tool *tool,
GdkEventKey *kevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
SelectOps op;
iscissors = (Iscissors *) tool->private;
op = iscissors->op;
if (op == -1)
return;
switch (kevent->keyval)
{
case GDK_Shift_L: case GDK_Shift_R:
if (op == SELECTION_REPLACE)
op = SELECTION_ADD;
else if (op == SELECTION_ADD)
op = SELECTION_REPLACE;
else if (op == SELECTION_SUB)
op = SELECTION_INTERSECT;
else
op = SELECTION_SUB;
break;
case GDK_Control_L: case GDK_Control_R:
if (op == SELECTION_REPLACE)
op = SELECTION_SUB;
else if (op == SELECTION_ADD)
op = SELECTION_INTERSECT;
else if (op == SELECTION_SUB)
op = SELECTION_REPLACE;
else
op = SELECTION_ADD;
break;
}
iscissors->op = op;
}
static void
iscissors_cursor_update (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
Iscissors *iscissors;
GDisplay *gdisp;
iscissors = (Iscissors *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
if (iscissors->op != -1)
{
switch (iscissors->op)
{
case SELECTION_ADD:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_ADD_CURSOR);
break;
case SELECTION_SUB:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_SUBTRACT_CURSOR);
break;
case SELECTION_INTERSECT:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_INTERSECT_CURSOR);
break;
default:
gdisplay_install_tool_cursor (gdisp, GIMP_SELECTION_CURSOR);
break;
}
}
else
{
switch (iscissors->state)
{
case WAITING:
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE_POINT_CURSOR);
break;
case SEED_PLACEMENT:
case SEED_ADJUSTMENT:
default:
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE_CURSOR);
break;
}
}
}
static void
iscissors_control (Tool *tool,
@ -1004,8 +1150,7 @@ iscissors_free_buffers (Iscissors * iscissors)
/* XXX need some scan-conversion routines from somewhere. maybe. ? */
static int
static gboolean
clicked_on_vertex (Tool *tool)
{
Iscissors * iscissors;
@ -1033,14 +1178,14 @@ clicked_on_vertex (Tool *tool)
{
iscissors->curve1 = curve;
if (curves_found++)
return 1;
return TRUE;
}
else if (abs (curve->x2 - iscissors->x) < POINT_HALFWIDTH &&
abs (curve->y2 - iscissors->y) < POINT_HALFWIDTH)
{
iscissors->curve2 = curve;
if (curves_found++)
return 1;
return TRUE;
}
list = g_slist_next (list);
@ -1052,7 +1197,7 @@ clicked_on_vertex (Tool *tool)
*/
if (curves_found == 1)
{
return 0;
return FALSE;
}
/* no vertices were found at the cursor click point. Now check whether
@ -1063,16 +1208,16 @@ clicked_on_vertex (Tool *tool)
}
static int
static gboolean
clicked_on_curve (Tool *tool)
{
Iscissors *iscissors;
GSList *list, *new_link;
gpointer *pt;
int len;
gint len;
ICurve *curve, *new_curve;
guint32 coords;
int tx, ty;
gint tx, ty;
iscissors = (Iscissors *) tool->private;
@ -1126,21 +1271,21 @@ clicked_on_curve (Tool *tool)
/* Redraw the curve */
draw_core_resume (iscissors->core, tool);
return 1;
return TRUE;
}
}
list = g_slist_next (list);
}
return 0;
return FALSE;
}
static void
precalculate_arrays (void)
{
int i;
gint i;
for (i = 0; i < 256; i++)
{
@ -1168,17 +1313,17 @@ precalculate_arrays (void)
}
static void
calculate_curve (Tool *tool, ICurve *curve)
calculate_curve (Tool *tool,
ICurve *curve)
{
GDisplay *gdisp;
Iscissors *iscissors;
int x, y, dir;
int xs, ys, xe, ye;
int x1, y1, x2, y2;
int width, height;
int ewidth, eheight;
gint x, y, dir;
gint xs, ys, xe, ye;
gint x1, y1, x2, y2;
gint width, height;
gint ewidth, eheight;
TRC (("calculate_curve(%p, %p)\n", tool, curve));
@ -1284,15 +1429,16 @@ calculate_curve (Tool *tool, ICurve *curve)
x += dir;
}
}
}
/* badly need to get a replacement - this is _way_ too expensive */
static int
gradient_map_value (TileManager *map, int x, int y,
guint8 *grad, guint8 *dir)
static gboolean
gradient_map_value (TileManager *map,
gint x,
gint y,
guint8 *grad,
guint8 *dir)
{
static int cur_tilex;
static int cur_tiley;
@ -1306,7 +1452,7 @@ gradient_map_value (TileManager *map, int x, int y,
tile_release (cur_tile, FALSE);
cur_tile = tile_manager_get_tile (map, x, y, TRUE, FALSE);
if (!cur_tile)
return 0;
return FALSE;
cur_tilex = x / TILE_WIDTH;
cur_tiley = y / TILE_HEIGHT;
}
@ -1314,14 +1460,18 @@ gradient_map_value (TileManager *map, int x, int y,
p = tile_data_pointer (cur_tile, x % TILE_WIDTH, y % TILE_HEIGHT);
*grad = p[0];
*dir = p[1];
return 1;
return TRUE;
}
static int
static gint
calculate_link (TileManager *gradient_map,
int x, int y, guint32 pixel, int link)
gint x,
gint y,
guint32 pixel,
gint link)
{
int value = 0;
gint value = 0;
guint8 grad1, dir1, grad2, dir2;
if (!gradient_map_value (gradient_map, x, y, &grad1, &dir1))
@ -1356,22 +1506,26 @@ calculate_link (TileManager *gradient_map,
static GPtrArray *
plot_pixels (Iscissors *iscissors, TempBuf *dp_buf,
int x1, int y1,
int xs, int ys,
int xe, int ye)
plot_pixels (Iscissors *iscissors,
TempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye)
{
int x, y;
gint x, y;
guint32 coords;
int link;
int width;
unsigned int * data;
gint link;
gint width;
guint *data;
GPtrArray *list;
width = dp_buf->width;
/* Start the data pointer at the correct location */
data = (unsigned int *)temp_buf_data(dp_buf) + (ye - y1) * width + (xe - x1);
data = (guint *) temp_buf_data (dp_buf) + (ye - y1) * width + (xe - x1);
x = xe;
y = ye;
@ -1397,28 +1551,32 @@ plot_pixels (Iscissors *iscissors, TempBuf *dp_buf,
}
#define PACK(x, y) ((((y) & 0xff) << 8) | ((x) & 0xff))
#define OFFSET(pixel) ((gint8)((pixel) & 0xff) + \
((gint8)(((pixel) & 0xff00) >> 8)) * dp_buf->width)
static void
find_optimal_path (TileManager *gradient_map, TempBuf *dp_buf,
int x1, int y1, int x2, int y2,
int xs, int ys)
find_optimal_path (TileManager *gradient_map,
TempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys)
{
int i, j, k;
int x, y;
int link;
int linkdir;
int dirx, diry;
int min_cost;
int new_cost;
int offset;
int cum_cost [8];
int link_cost [8];
int pixel_cost [8];
gint i, j, k;
gint x, y;
gint link;
gint linkdir;
gint dirx, diry;
gint min_cost;
gint new_cost;
gint offset;
gint cum_cost [8];
gint link_cost [8];
gint pixel_cost [8];
guint32 pixel [8];
guint32 * data, *d;
@ -1543,18 +1701,18 @@ find_optimal_path (TileManager *gradient_map, TempBuf *dp_buf,
}
/* Called to fill in a newly referenced tile in the gradient map */
static void
gradmap_tile_validate (TileManager *tm, Tile *tile)
gradmap_tile_validate (TileManager *tm,
Tile *tile)
{
static gboolean first_gradient = TRUE;
int x, y;
int dw, dh;
int sw, sh;
int i, j;
int b;
float gradient;
gint x, y;
gint dw, dh;
gint sw, sh;
gint i, j;
gint b;
gfloat gradient;
guint8 *gradmap;
guint8 *tiledata;
guint8 *datah, *datav;
@ -1567,7 +1725,7 @@ gradmap_tile_validate (TileManager *tm, Tile *tile)
if (first_gradient)
{
int radius = GRADIENT_SEARCH >> 1;
gint radius = GRADIENT_SEARCH >> 1;
/* compute the distance weights */
for (i = 0; i < GRADIENT_SEARCH; i++)
for (j = 0; j < GRADIENT_SEARCH; j++)
@ -1653,7 +1811,7 @@ gradmap_tile_validate (TileManager *tm, Tile *tile)
/* then 1 byte direction */
if (gradient > MIN_GRADIENT)
{
float direction;
gfloat direction;
if (!hmax)
direction = (vmax > 0) ? G_PI_2 : -G_PI_2;
else
@ -1700,17 +1858,20 @@ gradient_map_new (GImage *gimage)
}
static void
find_max_gradient (Iscissors *iscissors, GImage *gimage, int *x, int *y)
find_max_gradient (Iscissors *iscissors,
GImage *gimage,
gint *x,
gint *y)
{
PixelRegion srcPR;
int radius;
int i, j;
int endx, endy;
int sx, sy, cx, cy;
int x1, y1, x2, y2;
gint radius;
gint i, j;
gint endx, endy;
gint sx, sy, cx, cy;
gint x1, y1, x2, y2;
void *pr;
guint8 *gradient;
float g, max_gradient;
gfloat g, max_gradient;
TRC (("find_max_gradient(%d, %d)\n", *x, *y));
@ -1768,5 +1929,4 @@ find_max_gradient (Iscissors *iscissors, GImage *gimage, int *x, int *y)
TRC (("done: find_max_gradient(%d, %d)\n", *x, *y));
}
/* End of iscissors.c */