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:

committed by
Michael Natterer

parent
2b1a1cf9bb
commit
6e48bd16b7
13
ChangeLog
13
ChangeLog
@ -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"/
|
||||
|
442
app/iscissors.c
442
app/iscissors.c
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user