Core/UI separation for the paint tools:

2002-02-14  Michael Natterer  <mitch@gimp.org>

	Core/UI separation for the paint tools:

	* configure.in
	* app/Makefile.am
	* app/paint/.cvsignore
	* app/paint/Makefile.am: added new directory for the paint methods
	without GUI and tools around them.

	* app/paint/paint-types.h: typedefs for this module.

	* app/paint/gimppaintcore-kernels.h
	* app/paint/gimppaintcore.[ch]: the general paint logic taken
	from GimpPaintTool.

	* app/paint/gimpairbrush.[ch]
	* app/paint/gimpclone.[ch]
	* app/paint/gimpconvolve.[ch]
	* app/paint/gimpdodgeburn.[ch]
	* app/paint/gimperaser.[ch]
	* app/paint/gimppaintbrush.[ch]
	* app/paint/gimppencil.[ch]
	* app/paint/gimpsmudge.[ch]: subclasses of GimpPaintCore,
	implementing their own paint() methods.  Needs more hacking
	to get the GtkWidget pointers out of the options structs.

	* app/tools/gimppainttool_kernels.h: removed.

	* app/tools/tools-types.h: removed the paint tool enums.

	* app/tools/gimpairbrushtool.[ch]
	* app/tools/gimpclonetool.[ch]
	* app/tools/gimpconvolvetool.[ch]
	* app/tools/gimpdodgeburntool.[ch]
	* app/tools/gimperasertool.[ch]
	* app/tools/gimppaintbrushtool.[ch]
	* app/tools/gimppainttool.[ch]
	* app/tools/gimppenciltool.[ch]
	* app/tools/gimpsmudgetool.[ch]: all paint tools are pure GUI
	things now.  PaintOptions and friends still need to be chopped up
	though...

	* app/undo.c: changed PaintUndo to GimpPaintCoreUndo, some minor
	cleanup.

	* tools/kernelgen.c: changed accordingly.

	* tools/pdbgen/Makefile.am: scan paint/paint-types.h for enums.

	* tools/pdbgen/pdb/paint_tools.pdb: hardcode "success = FALSE" for
	all paint PDB wrappers.  The non-gui stuff is completely broken.
	More commits to come...

	* app/pdb/paint_tools_cmds.c
	* tools/pdbgen/enums.pl: regenerated.
This commit is contained in:
Michael Natterer 2002-02-14 19:31:16 +00:00 committed by Michael Natterer
parent dac875d3f2
commit dca988f74d
57 changed files with 3040 additions and 11860 deletions

View File

@ -1,3 +1,60 @@
2002-02-14 Michael Natterer <mitch@gimp.org>
Core/UI separation for the paint tools:
* configure.in
* app/Makefile.am
* app/paint/.cvsignore
* app/paint/Makefile.am: added new directory for the paint methods
without GUI and tools around them.
* app/paint/paint-types.h: typedefs for this module.
* app/paint/gimppaintcore-kernels.h
* app/paint/gimppaintcore.[ch]: the general paint logic taken
from GimpPaintTool.
* app/paint/gimpairbrush.[ch]
* app/paint/gimpclone.[ch]
* app/paint/gimpconvolve.[ch]
* app/paint/gimpdodgeburn.[ch]
* app/paint/gimperaser.[ch]
* app/paint/gimppaintbrush.[ch]
* app/paint/gimppencil.[ch]
* app/paint/gimpsmudge.[ch]: subclasses of GimpPaintCore,
implementing their own paint() methods. Needs more hacking
to get the GtkWidget pointers out of the options structs.
* app/tools/gimppainttool_kernels.h: removed.
* app/tools/tools-types.h: removed the paint tool enums.
* app/tools/gimpairbrushtool.[ch]
* app/tools/gimpclonetool.[ch]
* app/tools/gimpconvolvetool.[ch]
* app/tools/gimpdodgeburntool.[ch]
* app/tools/gimperasertool.[ch]
* app/tools/gimppaintbrushtool.[ch]
* app/tools/gimppainttool.[ch]
* app/tools/gimppenciltool.[ch]
* app/tools/gimpsmudgetool.[ch]: all paint tools are pure GUI
things now. PaintOptions and friends still need to be chopped up
though...
* app/undo.c: changed PaintUndo to GimpPaintCoreUndo, some minor
cleanup.
* tools/kernelgen.c: changed accordingly.
* tools/pdbgen/Makefile.am: scan paint/paint-types.h for enums.
* tools/pdbgen/pdb/paint_tools.pdb: hardcode "success = FALSE" for
all paint PDB wrappers. The non-gui stuff is completely broken.
More commits to come...
* app/pdb/paint_tools_cmds.c
* tools/pdbgen/enums.pl: regenerated.
2002-02-13 Michael Natterer <mitch@gimp.org>
* app/tools/gimppainttool.[ch]: moved all global variables into

View File

@ -5,6 +5,7 @@ SUBDIRS = \
base \
core \
config \
paint \
xcf \
file \
pdb \
@ -133,6 +134,7 @@ gimp_1_3_LDADD = @STRIP_BEGIN@ \
tools/libapptools.a \
display/libappdisplay.a \
widgets/libappwidgets.a \
paint/libapppaint.a \
core/libappcore.a \
xcf/libappxcf.a \
file/libappfile.a \

View File

@ -47,6 +47,8 @@
#include "core/gimpparasite.h"
#include "core/gimpparasitelist.h"
#include "paint/gimppaintcore.h"
#include "tools/gimpbycolorselecttool.h"
#include "tools/gimptool.h"
#include "tools/gimpdrawtool.h"
@ -1265,48 +1267,50 @@ undo_pop_transform (GimpImage *gimage,
UndoType type,
gpointer tu_ptr)
{
GimpTool *active_tool;
GimpTransformTool *tt;
TransformUndo *tu;
TileManager *temp;
gdouble d;
gint i;
GimpTool *active_tool;
active_tool = tool_manager_get_active (gimage->gimp);
/* Can't have ANY tool selected - maybe a plugin running */
if (active_tool == NULL)
return TRUE;
tt = (GimpTransformTool *) active_tool;
tu = (TransformUndo *) tu_ptr;
path_transform_do_undo (gimage, tu->path_undo);
/* only pop if the active tool is the tool that pushed this undo */
if (tu->tool_ID != active_tool->ID)
return TRUE;
/* swap the transformation information arrays */
for (i = 0; i < TRAN_INFO_SIZE; i++)
if (active_tool)
{
d = tu->trans_info[i];
tu->trans_info[i] = tt->trans_info[i];
tt->trans_info[i] = d;
}
GimpTransformTool *tt;
TransformUndo *tu;
/* swap the original buffer--the source buffer for repeated transforms
*/
temp = tu->original;
tu->original = tt->original;
tt->original = temp;
tt = (GimpTransformTool *) active_tool;
tu = (TransformUndo *) tu_ptr;
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tt->original)
{
active_tool->state = ACTIVE;
path_transform_do_undo (gimage, tu->path_undo);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tt));
/* only pop if the active tool is the tool that pushed this undo */
if (tu->tool_ID == active_tool->ID)
{
TileManager *temp;
gdouble d;
gint i;
/* swap the transformation information arrays */
for (i = 0; i < TRAN_INFO_SIZE; i++)
{
d = tu->trans_info[i];
tu->trans_info[i] = tt->trans_info[i];
tt->trans_info[i] = d;
}
/* swap the original buffer--the source buffer for repeated transforms
*/
temp = tu->original;
tu->original = tt->original;
tt->original = temp;
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tt->original)
{
active_tool->state = ACTIVE;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tt));
}
}
}
return TRUE;
@ -1338,7 +1342,7 @@ undo_push_paint (GimpImage *gimage,
Undo *new;
if ((new = undo_push (gimage,
sizeof (PaintUndo), PAINT_UNDO, FALSE)))
sizeof (GimpPaintCoreUndo), PAINT_UNDO, FALSE)))
{
new->data = pu_ptr;
new->pop_func = undo_pop_paint;
@ -1359,28 +1363,30 @@ undo_pop_paint (GimpImage *gimage,
UndoType type,
gpointer pu_ptr)
{
GimpTool *active_tool;
GimpPaintTool *pt;
PaintUndo *pu;
GimpCoords tmp_coords;
GimpTool *active_tool;
active_tool = tool_manager_get_active (gimage->gimp);
/* Can't have ANY tool selected - maybe a plugin running */
if (active_tool == NULL)
return TRUE;
if (active_tool)
{
GimpPaintTool *pt;
GimpPaintCoreUndo *pu;
pt = (GimpPaintTool *) active_tool;
pu = (PaintUndo *) pu_ptr;
pt = (GimpPaintTool *) active_tool;
pu = (GimpPaintCoreUndo *) pu_ptr;
/* only pop if the active tool is the tool that pushed this undo */
if (pu->tool_ID != active_tool->ID)
return TRUE;
/* only pop if the active paint core is the one that pushed this undo */
if (pu->core_ID == pt->core->ID)
{
GimpCoords tmp_coords;
/* swap the paint core information */
tmp_coords = pt->last_coords;
pt->last_coords = pu->last_coords;
pu->last_coords = tmp_coords;
/* swap the paint core information */
tmp_coords = pt->core->last_coords;
pt->core->last_coords = pu->last_coords;
pu->last_coords = tmp_coords;
}
}
return TRUE;
}
@ -1390,9 +1396,9 @@ undo_free_paint (UndoState state,
UndoType type,
gpointer pu_ptr)
{
PaintUndo *pu;
GimpPaintCoreUndo *pu;
pu = (PaintUndo *) pu_ptr;
pu = (GimpPaintCoreUndo *) pu_ptr;
g_free (pu);
}

6
app/paint/.cvsignore Normal file
View File

@ -0,0 +1,6 @@
Makefile
Makefile.in
.deps
.libs
*.lo
libapppaint.la

40
app/paint/Makefile.am Normal file
View File

@ -0,0 +1,40 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libapppaint.a
libapppaint_a_SOURCES = @STRIP_BEGIN@ \
gimpairbrush.c \
gimpairbrush.h \
gimpclone.c \
gimpclone.h \
gimpconvolve.c \
gimpconvolve.h \
gimpdodgeburn.c \
gimpdodgeburn.h \
gimperaser.c \
gimperaser.h \
gimppaintcore.c \
gimppaintcore.h \
gimppencil.c \
gimppencil.h \
gimppaintbrush.c \
gimppaintbrush.h \
gimpsmudge.c \
gimpsmudge.h \
@STRIP_END@
AM_CPPFLAGS = @STRIP_BEGIN@ \
-DG_LOG_DOMAIN=\"Gimp-Paint\" \
@GIMP_THREAD_FLAGS@ \
@GIMP_MP_FLAGS@ \
@STRIP_END@
INCLUDES = @STRIP_BEGIN@ \
-I$(top_builddir) \
-I$(top_srcdir) \
-I$(top_builddir)/app \
-I$(top_srcdir)/app \
$(GTK_CFLAGS) \
$(PANGOFT2_CFLAGS) \
-I$(includedir) \
@STRIP_END@

View File

@ -21,9 +21,8 @@
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/temp-buf.h"
@ -35,258 +34,167 @@
#include "core/gimpdrawable.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplay-foreach.h"
#include "gimpairbrush.h"
#include "gimpairbrushtool.h"
#include "paint_options.h"
#include "gimptool.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
/* The maximum amount of pressure that can be exerted */
#define MAX_PRESSURE 0.075
/* Default pressure setting */
#define AIRBRUSH_DEFAULT_RATE 0.0
#define AIRBRUSH_DEFAULT_PRESSURE 10.0
#define AIRBRUSH_DEFAULT_INCREMENTAL FALSE
#define OFF 0
#define ON 1
/* the airbrush structures */
typedef struct _AirbrushTimeout AirbrushTimeout;
struct _AirbrushTimeout
{
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
GimpDrawable *drawable;
};
typedef struct _AirbrushOptions AirbrushOptions;
struct _AirbrushOptions
{
PaintOptions paint_options;
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
gdouble pressure;
gdouble pressure_d;
GtkObject *pressure_w;
PaintOptions *paint_options;
};
/* local function prototypes */
static void gimp_airbrush_class_init (GimpAirbrushClass *klass);
static void gimp_airbrush_init (GimpAirbrush *airbrush);
static void gimp_airbrush_tool_class_init (GimpAirbrushToolClass *klass);
static void gimp_airbrush_tool_init (GimpAirbrushTool *airbrush);
static void gimp_airbrush_finalize (GObject *object);
static void gimp_airbrush_tool_finalize (GObject *object);
static void gimp_airbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble pressure,
gboolean incremental);
static gint airbrush_time_out (gpointer data);
static GimpToolOptions * airbrush_options_new (GimpToolInfo *tool_info);
static void airbrush_options_reset (GimpToolOptions *tool_options);
static void gimp_airbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options);
static gboolean gimp_airbrush_timeout (gpointer data);
/* local variables */
static gint timer; /* timer for successive paint applications */
static gint timer_state = OFF; /* state of airbrush tool */
static AirbrushTimeout airbrush_timeout;
static guint timeout_id = 0;
static AirbrushTimeout airbrush_timeout;
static gdouble non_gui_rate;
static gdouble non_gui_pressure;
static gboolean non_gui_incremental;
static GimpPaintCoreClass *parent_class = NULL;
static GimpPaintToolClass *parent_class = NULL;
/* functions */
void
gimp_airbrush_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_AIRBRUSH_TOOL,
airbrush_options_new,
TRUE,
"gimp:airbrush_tool",
_("Airbrush"),
_("Airbrush with variable pressure"),
N_("/Tools/Paint Tools/Airbrush"), "A",
NULL, "tools/airbrush.html",
GIMP_STOCK_TOOL_AIRBRUSH);
}
GType
gimp_airbrush_tool_get_type (void)
gimp_airbrush_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpAirbrushToolClass),
sizeof (GimpAirbrushClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_airbrush_tool_class_init,
(GClassInitFunc) gimp_airbrush_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpAirbrushTool),
sizeof (GimpAirbrush),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_airbrush_tool_init,
(GInstanceInitFunc) gimp_airbrush_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpAirbrushTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpAirbrush",
&info, 0);
}
return tool_type;
return type;
}
static void
gimp_airbrush_tool_class_init (GimpAirbrushToolClass *klass)
gimp_airbrush_class_init (GimpAirbrushClass *klass)
{
GObjectClass *object_class;
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
object_class = G_OBJECT_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_airbrush_tool_finalize;
object_class->finalize = gimp_airbrush_finalize;
paint_tool_class->paint = gimp_airbrush_tool_paint;
paint_core_class->paint = gimp_airbrush_paint;
}
static void
gimp_airbrush_tool_init (GimpAirbrushTool *airbrush)
gimp_airbrush_init (GimpAirbrush *airbrush)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (airbrush);
paint_tool = GIMP_PAINT_TOOL (airbrush);
paint_core = GIMP_PAINT_CORE (airbrush);
tool->tool_cursor = GIMP_AIRBRUSH_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_airbrush_tool_finalize (GObject *object)
gimp_airbrush_finalize (GObject *object)
{
if (timer_state == ON)
if (timeout_id)
{
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
gimp_airbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
AirbrushOptions *options;
PaintPressureOptions *pressure_options;
gdouble pressure;
gdouble rate;
gboolean incremental;
GimpBrush *brush;
AirbrushOptions *options;
GimpBrush *brush;
if (! drawable)
return;
options = (AirbrushOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
pressure = options->pressure;
rate = options->rate;
incremental = options->paint_options.incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
pressure = non_gui_pressure;
rate = non_gui_rate;
incremental = non_gui_incremental;
}
options = (AirbrushOptions *) paint_options;
brush =
gimp_context_get_brush (gimp_get_current_context (drawable->gimage->gimp));
switch (state)
switch (paint_state)
{
case INIT_PAINT:
if (timer_state == ON)
if (timeout_id)
{
g_warning ("killing stray timer, please report to lewing@gimp.org");
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
break;
case MOTION_PAINT:
if (timer_state == ON)
if (timeout_id)
{
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
gimp_airbrush_tool_motion (paint_tool,
drawable,
pressure_options,
pressure,
incremental);
gimp_airbrush_motion (paint_core,
drawable,
paint_options);
if (rate != 0.0)
if (options->rate != 0.0)
{
gdouble timeout;
airbrush_timeout.paint_tool = paint_tool;
airbrush_timeout.drawable = drawable;
airbrush_timeout.paint_core = paint_core;
airbrush_timeout.drawable = drawable;
airbrush_timeout.paint_options = paint_options;
timeout = (pressure_options->rate ?
(10000 / (rate * 2.0 * paint_tool->cur_coords.pressure)) :
(10000 / rate));
timeout = (paint_options->pressure_options->rate ?
(10000 / (options->rate * 2.0 * paint_core->cur_coords.pressure)) :
(10000 / options->rate));
timer = gtk_timeout_add (timeout, airbrush_time_out, paint_tool);
timer_state = ON;
timeout_id = g_timeout_add (timeout,
gimp_airbrush_timeout,
NULL);
}
break;
case FINISH_PAINT:
if (timer_state == ON)
if (timeout_id)
{
gtk_timeout_remove (timer);
timer_state = OFF;
g_source_remove (timeout_id);
timeout_id = 0;
}
break;
@ -295,50 +203,31 @@ gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
}
}
static gint
airbrush_time_out (gpointer client_data)
static gboolean
gimp_airbrush_timeout (gpointer client_data)
{
GimpTool *tool;
AirbrushOptions *options;
PaintPressureOptions *pressure_options;
gdouble pressure;
gdouble rate;
gboolean incremental;
gdouble rate;
tool = GIMP_TOOL (client_data);
options = (AirbrushOptions *) tool->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
pressure = options->pressure;
rate = options->rate;
incremental = options->paint_options.incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
pressure = non_gui_pressure;
rate = non_gui_rate;
incremental = non_gui_incremental;
}
gimp_airbrush_tool_motion (airbrush_timeout.paint_tool,
airbrush_timeout.drawable,
pressure_options,
pressure,
incremental);
gimp_airbrush_motion (airbrush_timeout.paint_core,
airbrush_timeout.drawable,
airbrush_timeout.paint_options);
gdisplays_flush ();
rate = ((AirbrushOptions *) airbrush_timeout.paint_options)->rate;
/* restart the timer */
if (rate != 0.0)
{
if (pressure_options->rate)
if (airbrush_timeout.paint_options->pressure_options->rate)
{
/* set a new timer */
timer = gtk_timeout_add ((10000 / (rate * 2.0 * airbrush_timeout.paint_tool->cur_coords.pressure)),
airbrush_time_out, NULL);
if (timeout_id)
g_source_remove (timeout_id);
timeout_id = g_timeout_add ((10000 /
(rate * 2.0 *
airbrush_timeout.paint_core->cur_coords.pressure)),
gimp_airbrush_timeout,
NULL);
return FALSE;
}
@ -349,42 +238,42 @@ airbrush_time_out (gpointer client_data)
}
static void
gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble pressure,
gboolean incremental)
gimp_airbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
PaintApplicationMode paint_appl_mode = incremental ? INCREMENTAL : CONSTANT;
if (!drawable)
return;
PaintApplicationMode paint_appl_mode;
gdouble pressure;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
paint_appl_mode = paint_options->incremental ? INCREMENTAL : CONSTANT;
pressure = ((AirbrushOptions *) paint_options)->pressure;
if (paint_options->pressure_options->size)
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
/* color the pixels */
if (pressure_options->color)
if (paint_options->pressure_options->color)
{
GimpRGB color;
gimp_gradient_get_color_at (gimp_context_get_gradient (context),
paint_tool->cur_coords.pressure, &color);
paint_core->cur_coords.pressure, &color);
gimp_rgba_get_uchar (&color,
&col[RED_PIX],
@ -395,13 +284,14 @@ gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
paint_appl_mode = INCREMENTAL;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
area->width * area->height,
area->bytes);
}
else if (paint_tool->brush && paint_tool->brush->pixmap)
else if (paint_core->brush && paint_core->brush->pixmap)
{
paint_appl_mode = INCREMENTAL;
gimp_paint_tool_color_area_with_pixmap (paint_tool, gimage,
gimp_paint_core_color_area_with_pixmap (paint_core, gimage,
drawable, area,
scale, SOFT);
}
@ -413,155 +303,13 @@ gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
area->width * area->height, area->bytes);
}
if (pressure_options->pressure)
pressure = pressure * 2.0 * paint_tool->cur_coords.pressure;
if (paint_options->pressure_options->pressure)
pressure = pressure * 2.0 * paint_core->cur_coords.pressure;
/* paste the newly painted area to the image */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (pressure, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_paint_mode (gimp_get_current_context (gimage->gimp)),
SOFT, scale, paint_appl_mode);
}
gboolean
airbrush_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
GimpToolInfo *tool_info;
AirbrushOptions *options;
gdouble pressure = AIRBRUSH_DEFAULT_PRESSURE;
tool_info = tool_manager_get_info_by_type (drawable->gimage->gimp,
GIMP_TYPE_AIRBRUSH_TOOL);
options = (AirbrushOptions *) tool_info->tool_options;
if (options)
pressure = options->pressure;
return airbrush_non_gui (drawable, pressure, num_strokes, stroke_array);
}
gboolean
airbrush_non_gui (GimpDrawable *drawable,
gdouble pressure,
gint num_strokes,
gdouble *stroke_array)
{
static GimpAirbrushTool *non_gui_airbrush = NULL;
GimpPaintTool *paint_tool;
gint i;
if (! non_gui_airbrush)
{
non_gui_airbrush = g_object_new (GIMP_TYPE_AIRBRUSH_TOOL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_airbrush);
if (gimp_paint_tool_start (paint_tool, drawable,
stroke_array[0],
stroke_array[1]))
{
non_gui_rate = AIRBRUSH_DEFAULT_RATE;
non_gui_pressure = pressure;
non_gui_incremental = AIRBRUSH_DEFAULT_INCREMENTAL;
paint_tool->start_coords.x = paint_tool->last_coords.x = stroke_array[0];
paint_tool->start_coords.y = paint_tool->last_coords.y = stroke_array[1];
gimp_airbrush_tool_paint (paint_tool, drawable, MOTION_PAINT);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
return TRUE;
}
return FALSE;
}
static GimpToolOptions *
airbrush_options_new (GimpToolInfo *tool_info)
{
AirbrushOptions *options;
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *scale;
options = g_new0 (AirbrushOptions, 1);
paint_options_init ((PaintOptions *) options, tool_info);
((GimpToolOptions *) options)->reset_func = airbrush_options_reset;
options->rate = options->rate_d = 80.0;
options->pressure = options->pressure_d = AIRBRUSH_DEFAULT_PRESSURE;
/* the main vbox */
vbox = ((GimpToolOptions *) options)->main_vbox;
/* the rate scale */
table = gtk_table_new (2, 2, FALSE);
gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 1);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
options->rate_w =
gtk_adjustment_new (options->rate_d, 0.0, 150.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->rate_w));
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
g_signal_connect (G_OBJECT (options->rate_w), "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&options->rate);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("Rate:"), 1.0, 1.0,
scale, 1, FALSE);
/* the pressure scale */
options->pressure_w =
gtk_adjustment_new (options->pressure_d, 0.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->pressure_w));
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
g_signal_connect (G_OBJECT (options->pressure_w), "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&options->pressure);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
_("Pressure:"), 1.0, 1.0,
scale, 1, FALSE);
gtk_widget_show (table);
return (GimpToolOptions *) options;
}
static void
airbrush_options_reset (GimpToolOptions *tool_options)
{
AirbrushOptions *options;
options = (AirbrushOptions *) tool_options;
paint_options_reset (tool_options);
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->rate_w),
options->rate_d);
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->pressure_w),
options->pressure_d);
}

View File

@ -16,48 +16,52 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_AIRBRUSH_TOOL_H__
#define __GIMP_AIRBRUSH_TOOL_H__
#ifndef __GIMP_AIRBRUSH_H__
#define __GIMP_AIRBRUSH_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
#define GIMP_TYPE_AIRBRUSH_TOOL (gimp_airbrush_tool_get_type ())
#define GIMP_AIRBRUSH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_AIRBRUSH_TOOL, GimpAirbrushTool))
#define GIMP_AIRBRUSH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_AIRBRUSH_TOOL, GimpAirbrushToolClass))
#define GIMP_IS_AIRBRUSH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_AIRBRUSH_TOOL))
#define GIMP_IS_AIRBRUSH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_AIRBRUSH_TOOL))
#define GIMP_AIRBRUSH_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_AIRBRUSH_TOOL, GimpAirbrushToolClass))
#define GIMP_TYPE_AIRBRUSH (gimp_airbrush_get_type ())
#define GIMP_AIRBRUSH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_AIRBRUSH, GimpAirbrush))
#define GIMP_AIRBRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_AIRBRUSH, GimpAirbrushClass))
#define GIMP_IS_AIRBRUSH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_AIRBRUSH))
#define GIMP_IS_AIRBRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_AIRBRUSH))
#define GIMP_AIRBRUSH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_AIRBRUSH, GimpAirbrushClass))
typedef struct _GimpAirbrushTool GimpAirbrushTool;
typedef struct _GimpAirbrushToolClass GimpAirbrushToolClass;
typedef struct _GimpAirbrush GimpAirbrush;
typedef struct _GimpAirbrushClass GimpAirbrushClass;
struct _GimpAirbrushTool
struct _GimpAirbrush
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
};
struct _GimpAirbrushToolClass
struct _GimpAirbrushClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_airbrush_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
typedef struct _AirbrushOptions AirbrushOptions;
GType gimp_airbrush_tool_get_type (void) G_GNUC_CONST;
struct _AirbrushOptions
{
PaintOptions paint_options;
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
gdouble pressure;
gdouble pressure_d;
GtkObject *pressure_w;
};
gboolean airbrush_non_gui (GimpDrawable *drawable,
gdouble pressure,
gint num_strokes,
gdouble *stroke_array);
gboolean airbrush_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
GType gimp_airbrush_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_AIRBRUSH_TOOL_H__ */
#endif /* __GIMP_AIRBRUSH_H__ */

View File

@ -23,9 +23,7 @@
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
@ -39,270 +37,167 @@
#include "core/gimpimage.h"
#include "core/gimpimage-mask.h"
#include "core/gimppattern.h"
#include "core/gimptoolinfo.h"
#include "display/gimpdisplay.h"
#include "gimpclonetool.h"
#include "paint_options.h"
#include "gimpclone.h"
#include "libgimp/gimpintl.h"
#define TARGET_WIDTH 15
#define TARGET_HEIGHT 15
static void gimp_clone_class_init (GimpCloneClass *klass);
static void gimp_clone_init (GimpClone *clone);
/* default types */
#define CLONE_DEFAULT_TYPE IMAGE_CLONE
#define CLONE_DEFAULT_ALIGNED ALIGN_NO
static void gimp_clone_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y);
static void gimp_clone_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width);
static void gimp_clone_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width);
/* the clone structures */
typedef enum
{
ALIGN_NO,
ALIGN_YES,
ALIGN_REGISTERED
} AlignType;
typedef struct _CloneOptions CloneOptions;
struct _CloneOptions
{
PaintOptions paint_options;
CloneType type;
CloneType type_d;
GtkWidget *type_w[2]; /* 2 radio buttons */
AlignType aligned;
AlignType aligned_d;
GtkWidget *aligned_w[3]; /* 3 radio buttons */
};
static void gimp_clone_set_src_drawable (GimpClone *clone,
GimpDrawable *drawable);
/* forward function declarations */
static gint dest_x = 0; /* */
static gint dest_y = 0; /* position of clone src */
static gint offset_x = 0; /* */
static gint offset_y = 0; /* offset for cloning */
static gint first = TRUE;
static void gimp_clone_tool_class_init (GimpCloneToolClass *klass);
static void gimp_clone_tool_init (GimpCloneTool *tool);
static GimpPaintCoreClass *parent_class = NULL;
static void gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_clone_tool_draw (GimpDrawTool *draw_tool);
static void gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y);
static void gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width);
static void gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width);
static GimpToolOptions * clone_options_new (GimpToolInfo *tool_info);
static void clone_options_reset (GimpToolOptions *options);
/* local variables */
static gint src_x = 0; /* */
static gint src_y = 0; /* position of clone src */
static gint dest_x = 0; /* */
static gint dest_y = 0; /* position of clone src */
static gint offset_x = 0; /* */
static gint offset_y = 0; /* offset for cloning */
static gint first = TRUE;
static GimpDrawable *the_src_drawable = NULL; /* source drawable */
static GimpDrawable *non_gui_src_drawable;
static gint non_gui_offset_x;
static gint non_gui_offset_y;
static CloneType non_gui_type;
static GimpPaintToolClass *parent_class;
/* public functions */
void
gimp_clone_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_CLONE_TOOL,
clone_options_new,
TRUE,
"gimp:clone_tool",
_("Clone"),
_("Paint using Patterns or Image Regions"),
N_("/Tools/Paint Tools/Clone"), "C",
NULL, "tools/clone.html",
GIMP_STOCK_TOOL_CLONE);
}
GType
gimp_clone_tool_get_type (void)
gimp_clone_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpCloneToolClass),
sizeof (GimpCloneClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_clone_tool_class_init,
(GClassInitFunc) gimp_clone_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpCloneTool),
sizeof (GimpClone),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_clone_tool_init,
(GInstanceInitFunc) gimp_clone_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpCloneTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpClone",
&info, 0);
}
return tool_type;
return type;
}
/* static functions */
static void
gimp_clone_tool_class_init (GimpCloneToolClass *klass)
gimp_clone_class_init (GimpCloneClass *klass)
{
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
tool_class = GIMP_TOOL_CLASS (klass);
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->cursor_update = gimp_clone_tool_cursor_update;
draw_tool_class->draw = gimp_clone_tool_draw;
paint_tool_class->paint = gimp_clone_tool_paint;
paint_core_class->paint = gimp_clone_paint;
}
static void
gimp_clone_tool_init (GimpCloneTool *clone)
gimp_clone_init (GimpClone *clone)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (clone);
paint_tool = GIMP_PAINT_TOOL (clone);
paint_core = GIMP_PAINT_CORE (clone);
tool->tool_cursor = GIMP_CLONE_TOOL_CURSOR;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_TRACES_ON_WINDOW;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_tool->flags |= TOOL_TRACES_ON_WINDOW;
clone->set_source = FALSE;
clone->src_drawable = NULL;
clone->src_x = 0.0;
clone->src_y = 0.0;
clone->init_callback = NULL;
clone->finish_callback = NULL;
clone->pretrace_callback = NULL;
clone->posttrace_callback = NULL;
clone->callback_data = NULL;
}
static void
clone_src_drawable_disconnect_cb (GimpDrawable *drawable,
GimpDrawable **src_drawable)
gimp_clone_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
if (drawable == *src_drawable)
{
*src_drawable = NULL;
}
}
static void
clone_set_src_drawable (GimpDrawable *drawable)
{
if (the_src_drawable == drawable)
return;
if (the_src_drawable)
g_signal_handlers_disconnect_by_func (G_OBJECT (the_src_drawable),
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
the_src_drawable = drawable;
if (the_src_drawable)
{
g_signal_connect (G_OBJECT (the_src_drawable), "disconnect",
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
}
}
static void
gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
GimpTool *tool;
GimpDrawTool *draw_tool;
CloneOptions *options;
GimpContext *context;
static gint orig_src_x = 0;
static gint orig_src_y = 0;
tool = GIMP_TOOL (paint_tool);
draw_tool = GIMP_DRAW_TOOL (paint_tool);
GimpClone *clone;
CloneOptions *options;
GimpContext *context;
options = (CloneOptions *) tool->tool_info->tool_options;
clone = GIMP_CLONE (paint_core);
context = gimp_get_current_context (tool->gdisp->gimage->gimp);
options = (CloneOptions *) paint_options;
switch (state)
context = gimp_get_current_context (drawable->gimage->gimp);
switch (paint_state)
{
case PRETRACE_PAINT:
gimp_draw_tool_pause (draw_tool);
if (clone->pretrace_callback)
clone->pretrace_callback (clone, clone->callback_data);
break;
case POSTTRACE_PAINT:
gimp_draw_tool_resume (draw_tool);
if (clone->posttrace_callback)
clone->posttrace_callback (clone, clone->callback_data);
break;
case MOTION_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
if (clone->set_source)
{
/* If the control key is down, move the src target and return */
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
first = TRUE;
}
else
{
/* otherwise, update the target */
dest_x = paint_tool->cur_coords.x;
dest_y = paint_tool->cur_coords.y;
dest_x = paint_core->cur_coords.x;
dest_y = paint_core->cur_coords.y;
if (options->aligned == ALIGN_REGISTERED)
{
@ -311,37 +206,40 @@ gimp_clone_tool_paint (GimpPaintTool *paint_tool,
}
else if (first)
{
offset_x = src_x - dest_x;
offset_y = src_y - dest_y;
offset_x = clone->src_x - dest_x;
offset_y = clone->src_y - dest_y;
first = FALSE;
}
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
clone->src_x = dest_x + offset_x;
clone->src_y = dest_y + offset_y;
gimp_clone_tool_motion (paint_tool, drawable, the_src_drawable,
options->paint_options.pressure_options,
options->type,
offset_x, offset_y);
gimp_clone_motion (paint_core, drawable,
clone->src_drawable,
options->paint_options.pressure_options,
options->type,
offset_x, offset_y);
}
break;
case INIT_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
if (clone->set_source)
{
clone_set_src_drawable (drawable);
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
gimp_clone_set_src_drawable (clone, drawable);
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
first = TRUE;
}
else if (options->aligned == ALIGN_NO)
{
first = TRUE;
orig_src_x = src_x;
orig_src_y = src_y;
orig_src_x = clone->src_x;
orig_src_y = clone->src_y;
}
gimp_draw_tool_start (draw_tool, tool->gdisp);
if (clone->init_callback)
clone->init_callback (clone, clone->callback_data);
if (options->type == PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
@ -349,12 +247,13 @@ gimp_clone_tool_paint (GimpPaintTool *paint_tool,
break;
case FINISH_PAINT:
gimp_draw_tool_stop (draw_tool);
if (clone->finish_callback)
clone->finish_callback (clone, clone->callback_data);
if (options->aligned == ALIGN_NO && !first)
{
src_x = orig_src_x;
src_y = orig_src_y;
clone->src_x = orig_src_x;
clone->src_y = orig_src_y;
}
break;
@ -363,89 +262,14 @@ gimp_clone_tool_paint (GimpPaintTool *paint_tool,
}
}
void
gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp)
{
CloneOptions *options;
GimpLayer *layer;
GdkCursorType ctype = GIMP_MOUSE_CURSOR;
options = (CloneOptions *) tool->tool_info->tool_options;
if ((layer = gimp_image_get_active_layer (gdisp->gimage)))
{
int off_x, off_y;
gimp_drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
if (coords->x >= off_x &&
coords->y >= off_y &&
coords->x < (off_x + gimp_drawable_width (GIMP_DRAWABLE (layer))) &&
coords->y < (off_y + gimp_drawable_height (GIMP_DRAWABLE (layer))))
{
/* One more test--is there a selected region?
* if so, is cursor inside?
*/
if (gimp_image_mask_is_empty (gdisp->gimage))
ctype = GIMP_MOUSE_CURSOR;
else if (gimp_image_mask_value (gdisp->gimage, coords->x, coords->y))
ctype = GIMP_MOUSE_CURSOR;
}
}
if (options->type == IMAGE_CLONE)
{
if (state & GDK_CONTROL_MASK)
ctype = GIMP_CROSSHAIR_SMALL_CURSOR;
else if (! the_src_drawable)
ctype = GIMP_BAD_CURSOR;
}
tool->cursor = ctype;
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_clone_tool_draw (GimpDrawTool *draw_tool)
{
GimpTool *tool;
tool = GIMP_TOOL (draw_tool);
if (tool->state == ACTIVE)
{
CloneOptions *options;
options = (CloneOptions *) tool->tool_info->tool_options;
if (draw_tool->gdisp && options->type == IMAGE_CLONE)
{
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_CROSS,
src_x, src_y,
TARGET_WIDTH, TARGET_WIDTH,
GTK_ANCHOR_CENTER,
TRUE);
}
}
else
{
GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool);
}
}
static void
gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
int offset_x,
int offset_y)
gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y)
{
GimpImage *gimage;
GimpImage *src_gimage = NULL;
@ -484,12 +308,12 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
switch (type)
@ -532,7 +356,7 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
return;
/* get the original image */
orig = gimp_paint_tool_get_orig_image (paint_tool, drawable, x1, y1, x2, y2);
orig = gimp_paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0; srcPR.y = 0;
@ -583,16 +407,18 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
switch (type)
{
case IMAGE_CLONE:
gimp_clone_tool_line_image (gimage, src_gimage, drawable,
src_drawable, s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
gimp_clone_line_image (gimage, src_gimage,
drawable, src_drawable,
s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
break;
case PATTERN_CLONE:
gimp_clone_tool_line_pattern (gimage, drawable, pattern, d,
area->x + offset_x,
area->y + y + offset_y,
destPR.bytes, destPR.w);
gimp_clone_line_pattern (gimage, drawable,
pattern, d,
area->x + offset_x,
area->y + y + offset_y,
destPR.bytes, destPR.w);
break;
}
@ -602,10 +428,10 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
opacity = 255.0 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_paint_mode (context),
@ -613,18 +439,17 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
scale, CONSTANT);
}
static void
gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width)
gimp_clone_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width)
{
guchar rgb[3];
gint src_alpha, dest_alpha;
@ -648,14 +473,14 @@ gimp_clone_tool_line_image (GimpImage *dest,
}
static void
gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width)
gimp_clone_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width)
{
guchar *pat, *p;
GimpImageBaseType color_type;
@ -688,172 +513,34 @@ gimp_clone_tool_line_pattern (GimpImage *dest,
}
}
#if 0 /* leave these to the stub functions. */
static gpointer
gimp_clone_tool_non_gui_paint_func (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
static void
gimp_clone_src_drawable_disconnect_cb (GimpDrawable *drawable,
GimpClone *clone)
{
gimp_clone_tool_motion (paint_tool, drawable, non_gui_src_drawable,
&non_gui_pressure_options,
non_gui_type, non_gui_offset_x, non_gui_offset_y);
return NULL;
}
gboolean
gimp_clone_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
GimpDrawable *src_drawable = NULL;
CloneType clone_type = CLONE_DEFAULT_TYPE;
gdouble local_src_x = 0.0;
gdouble local_src_y = 0.0;
CloneOptions *options = clone_options;
if (options)
if (drawable == clone->src_drawable)
{
clone_type = options->type;
src_drawable = the_src_drawable;
local_src_x = src_x;
local_src_y = src_y;
clone->src_drawable = NULL;
}
return gimp_clone_tool_non_gui (drawable,
src_drawable,
clone_type,
local_src_x,local_src_y,
num_strokes, stroke_array);
}
gboolean
gimp_clone_tool_non_gui (GimpDrawable *drawable,
GimpDrawable *src_drawable,
CloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gdouble *stroke_array)
{
gint i;
if (gimp_paint_tool_start (&non_gui_paint_tool, drawable,
stroke_array[0], stroke_array[1]))
{
/* Set the paint core's paint func */
non_gui_paint_core.paint_func = clone_non_gui_paint_func;
non_gui_type = clone_type;
non_gui_src_drawable = src_drawable;
non_gui_paint_core.startx = non_gui_paint_core.lastx = stroke_array[0];
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
non_gui_offset_x = (int) (src_x - non_gui_paint_core.start_coords.x);
non_gui_offset_y = (int) (src_y - non_gui_paint_core.start_coords.y);
clone_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
non_gui_paint_core.cur_coords.x = stroke_array[i * 2 + 0];
non_gui_paint_core.cur_coords.y = stroke_array[i * 2 + 1];
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.last_coords.x = non_gui_paint_core.cur_coords.x;
non_gui_paint_core.last_coords.y = non_gui_paint_core.cur_coords.y;
}
/* Finish the painting */
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* Cleanup */
paint_core_cleanup ();
return TRUE;
}
else
return FALSE;
}
#endif /* 0 - non-gui functions */
static GimpToolOptions *
clone_options_new (GimpToolInfo *tool_info)
{
CloneOptions *options;
GtkWidget *vbox;
GtkWidget *frame;
options = g_new0 (CloneOptions, 1);
paint_options_init ((PaintOptions *) options, tool_info);
((GimpToolOptions *) options)->reset_func = clone_options_reset;
options->type = options->type_d = CLONE_DEFAULT_TYPE;
options->aligned = options->aligned_d = CLONE_DEFAULT_ALIGNED;
/* the main vbox */
vbox = ((GimpToolOptions *) options)->main_vbox;
frame = gimp_radio_group_new2 (TRUE, _("Source"),
G_CALLBACK (gimp_radio_button_update),
&options->type,
GINT_TO_POINTER (options->type),
_("Image Source"),
GINT_TO_POINTER (IMAGE_CLONE),
&options->type_w[0],
_("Pattern Source"),
GINT_TO_POINTER (PATTERN_CLONE),
&options->type_w[1],
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
frame = gimp_radio_group_new2 (TRUE, _("Alignment"),
G_CALLBACK (gimp_radio_button_update),
&options->aligned,
GINT_TO_POINTER (options->aligned),
_("Non Aligned"),
GINT_TO_POINTER (ALIGN_NO),
&options->aligned_w[0],
_("Aligned"),
GINT_TO_POINTER (ALIGN_YES),
&options->aligned_w[1],
_("Registered"),
GINT_TO_POINTER (ALIGN_REGISTERED),
&options->aligned_w[2],
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
return (GimpToolOptions *) options;
}
static void
clone_options_reset (GimpToolOptions *tool_options)
gimp_clone_set_src_drawable (GimpClone *clone,
GimpDrawable *drawable)
{
CloneOptions *options;
if (clone->src_drawable == drawable)
return;
options = (CloneOptions *) tool_options;
if (clone->src_drawable)
g_signal_handlers_disconnect_by_func (G_OBJECT (clone->src_drawable),
gimp_clone_src_drawable_disconnect_cb,
clone);
paint_options_reset (tool_options);
clone->src_drawable = drawable;
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (options->type_d));
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->aligned_w[0]),
GINT_TO_POINTER (options->aligned_d));
if (clone->src_drawable)
{
g_signal_connect (G_OBJECT (clone->src_drawable), "disconnect",
G_CALLBACK (gimp_clone_src_drawable_disconnect_cb),
clone);
}
}

View File

@ -16,63 +16,77 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_CLONE_TOOL_H__
#define __GIMP_CLONE_TOOL_H__
#ifndef __GIMP_CLONE_H__
#define __GIMP_CLONE_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
typedef enum
typedef enum /*< skip >*/ /*< pdb-skip >*/
{
IMAGE_CLONE,
PATTERN_CLONE
} CloneType;
ALIGN_NO,
ALIGN_YES,
ALIGN_REGISTERED
} AlignType;
#define GIMP_TYPE_CLONE_TOOL (gimp_clone_tool_get_type ())
#define GIMP_CLONE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CLONE_TOOL, GimpCloneTool))
#define GIMP_CLONE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CLONE_TOOL, GimpCloneToolClass))
#define GIMP_IS_CLONE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CLONE_TOOL))
#define GIMP_IS_CLONE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CLONE_TOOL))
#define GIMP_CLONE_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CLONE_TOOL, GimpCloneToolClass))
#define GIMP_TYPE_CLONE (gimp_clone_get_type ())
#define GIMP_CLONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CLONE, GimpClone))
#define GIMP_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CLONE, GimpCloneClass))
#define GIMP_IS_CLONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CLONE))
#define GIMP_IS_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CLONE))
#define GIMP_CLONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CLONE, GimpCloneClass))
typedef struct _GimpCloneTool GimpCloneTool;
typedef struct _GimpCloneToolClass GimpCloneToolClass;
typedef struct _GimpClone GimpClone;
typedef struct _GimpCloneClass GimpCloneClass;
struct _GimpCloneTool
struct _GimpClone
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
gboolean set_source;
GimpDrawable *src_drawable;
gint src_x;
gint src_y;
void (* init_callback) (GimpClone *clone,
gpointer data);
void (* finish_callback) (GimpClone *clone,
gpointer data);
void (* pretrace_callback) (GimpClone *clone,
gpointer data);
void (* posttrace_callback) (GimpClone *clone,
gpointer data);
gpointer callback_data;
};
struct _GimpCloneToolClass
struct _GimpCloneClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_clone_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
typedef struct _CloneOptions CloneOptions;
GType gimp_clone_tool_get_type (void) G_GNUC_CONST;
struct _CloneOptions
{
PaintOptions paint_options;
CloneType type;
CloneType type_d;
GtkWidget *type_w[2]; /* 2 radio buttons */
AlignType aligned;
AlignType aligned_d;
GtkWidget *aligned_w[3]; /* 3 radio buttons */
};
/* FIXME: Old style functions in need of a replacement. The only
* time these are used is to stroke paths or fill selections
* They should be somewhere else.
*/
gboolean clone_non_gui (GimpDrawable *drawable,
GimpDrawable *src_drawable,
CloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gdouble *stroke_array);
gboolean clone_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
GType gimp_clone_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_CLONE_TOOL_H__ */
#endif /* __GIMP_CLONE_H__ */

View File

@ -19,11 +19,8 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
@ -35,12 +32,8 @@
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "gimpconvolvetool.h"
#include "paint_options.h"
#include "libgimp/gimpintl.h"
#include "gimpconvolve.h"
#define FIELD_COLS 4
@ -49,14 +42,9 @@
#define MIN_SHARPEN -512
#define MAX_SHARPEN -64
/* defaults */
#define DEFAULT_CONVOLVE_RATE 50.0
#define DEFAULT_CONVOLVE_TYPE BLUR_CONVOLVE
/* Different clip relationships between a blur-blob and edges:
see convolve_motion */
* see convolve_motion
*/
typedef enum
{
CONVOLVE_NCLIP, /* Left or top edge */
@ -65,71 +53,35 @@ typedef enum
} ConvolveClipType;
/* the convolve structures */
static void gimp_convolve_class_init (GimpConvolveClass *klass);
static void gimp_convolve_init (GimpConvolve *convolve);
typedef struct _ConvolveOptions ConvolveOptions;
struct _ConvolveOptions
{
PaintOptions paint_options;
ConvolveType type;
ConvolveType type_d;
GtkWidget *type_w[2];
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
};
static void gimp_convolve_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_convolve_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
ConvolveType type,
gdouble rate);
/* forward function declarations */
static void gimp_convolve_tool_class_init (GimpConvolveToolClass *klass);
static void gimp_convolve_tool_init (GimpConvolveTool *tool);
static void gimp_convolve_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_convolve_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_convolve_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
ConvolveType type,
gdouble rate);
static void gimp_convolve_calculate_matrix (ConvolveType type,
gdouble rate);
static void gimp_convolve_integer_matrix (gfloat *source,
gint *dest,
gint size);
static void gimp_convolve_copy_matrix (gfloat *src,
gfloat *dest,
gint size);
static gint gimp_convolve_sum_matrix (gint *matrix,
gint size);
static void calculate_matrix (ConvolveType type,
gdouble rate);
static void integer_matrix (gfloat *source,
gint *dest,
gint size);
static void copy_matrix (gfloat *src,
gfloat *dest,
gint size);
static gint sum_matrix (gint *matrix,
gint size);
static GimpToolOptions * convolve_options_new (GimpToolInfo *tool_info);
static void convolve_options_reset (GimpToolOptions *options);
/* local variables */
static gint matrix [25];
static gint matrix_size;
static gint matrix_divisor;
static ConvolveType non_gui_type;
static gdouble non_gui_rate;
static gint matrix [25];
static gint matrix_size;
static gint matrix_divisor;
static gfloat custom_matrix [25] =
{
@ -158,104 +110,72 @@ static gfloat sharpen_matrix [25] =
0, 0, 0, 0, 0,
};
static GimpPaintToolClass *parent_class;
static GimpPaintCoreClass *parent_class;
/* public functions */
void
gimp_convolve_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_CONVOLVE_TOOL,
convolve_options_new,
TRUE,
"gimp:convolve_tool",
_("Convolve"),
_("Blur or Sharpen"),
N_("/Tools/Paint Tools/Convolve"), "B",
NULL, "tools/convolve.html",
GIMP_STOCK_TOOL_BLUR);
}
GType
gimp_convolve_tool_get_type (void)
gimp_convolve_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpConvolveToolClass),
sizeof (GimpConvolveClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_convolve_tool_class_init,
(GClassInitFunc) gimp_convolve_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpConvolveTool),
sizeof (GimpConvolve),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_convolve_tool_init,
(GInstanceInitFunc) gimp_convolve_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpConvolveTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpConvolve",
&info, 0);
}
return tool_type;
return type;
}
/* static functions */
static void
gimp_convolve_tool_class_init (GimpConvolveToolClass *klass)
gimp_convolve_class_init (GimpConvolveClass *klass)
{
GimpToolClass *tool_class;
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
tool_class = GIMP_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->modifier_key = gimp_convolve_tool_modifier_key;
tool_class->cursor_update = gimp_convolve_tool_cursor_update;
paint_tool_class->paint = gimp_convolve_tool_paint;
paint_core_class->paint = gimp_convolve_paint;
}
static void
gimp_convolve_tool_init (GimpConvolveTool *convolve)
gimp_convolve_init (GimpConvolve *convolve)
{
GimpTool *tool;
tool = GIMP_TOOL (convolve);
tool->tool_cursor = GIMP_BLUR_TOOL_CURSOR;
tool->cursor_modifier = GIMP_CURSOR_MODIFIER_NONE;
tool->toggle_tool_cursor = GIMP_BLUR_TOOL_CURSOR;
tool->toggle_cursor_modifier = GIMP_CURSOR_MODIFIER_MINUS;
}
static void
gimp_convolve_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
gimp_convolve_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
ConvolveOptions *options;
options = (ConvolveOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
options = (ConvolveOptions *) paint_options;
switch (state)
switch (paint_state)
{
case MOTION_PAINT:
gimp_convolve_tool_motion (paint_tool,
drawable,
options->paint_options.pressure_options,
options->type,
options->rate);
gimp_convolve_motion (paint_core,
drawable,
paint_options->pressure_options,
options->type,
options->rate);
break;
default:
@ -264,56 +184,11 @@ gimp_convolve_tool_paint (GimpPaintTool *paint_tool,
}
static void
gimp_convolve_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp)
{
ConvolveOptions *options;
options = (ConvolveOptions *) tool->tool_info->tool_options;
if ((key == GDK_CONTROL_MASK) &&
! (state & GDK_SHIFT_MASK)) /* leave stuff untouched in line draw mode */
{
switch (options->type)
{
case BLUR_CONVOLVE:
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (SHARPEN_CONVOLVE));
break;
case SHARPEN_CONVOLVE:
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (BLUR_CONVOLVE));
break;
default:
break;
}
}
}
static void
gimp_convolve_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp)
{
ConvolveOptions *options;
options = (ConvolveOptions *) tool->tool_info->tool_options;
tool->toggled = (options->type == SHARPEN_CONVOLVE);
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
ConvolveType type,
double rate)
gimp_convolve_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
ConvolveType type,
gdouble rate)
{
TempBuf *area;
guchar *temp_data;
@ -335,17 +210,17 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
/* If the brush is smaller than the convolution matrix, don't convolve */
if ((paint_tool->brush->mask->width < matrix_size) ||
(paint_tool->brush->mask->height < matrix_size))
if ((paint_core->brush->mask->width < matrix_size) ||
(paint_core->brush->mask->height < matrix_size))
return;
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
/* Get image region around current brush (mask bbox + 1 pixel) */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
/* configure the source pixel region */
@ -364,21 +239,21 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
destPR.data = temp_buf_data (area);
if (pressure_options->rate)
rate = rate * 2.0 * paint_tool->cur_coords.pressure;
rate = rate * 2.0 * paint_core->cur_coords.pressure;
calculate_matrix (type, rate);
gimp_convolve_calculate_matrix (type, rate);
/* Image region near edges? If so, paint area will be clipped */
/* with respect to brush mask + 1 pixel border (# 19285) */
if ((marginx = (gint) paint_tool->cur_coords.x - paint_tool->brush->mask->width / 2 - 1) != area->x)
if ((marginx = (gint) paint_core->cur_coords.x - paint_core->brush->mask->width / 2 - 1) != area->x)
area_hclip = CONVOLVE_NCLIP;
else if ((marginx = area->width - paint_tool->brush->mask->width - 2) != 0)
else if ((marginx = area->width - paint_core->brush->mask->width - 2) != 0)
area_hclip = CONVOLVE_PCLIP;
if ((marginy = (gint) paint_tool->cur_coords.y - paint_tool->brush->mask->height / 2 - 1) != area->y)
if ((marginy = (gint) paint_core->cur_coords.y - paint_core->brush->mask->height / 2 - 1) != area->y)
area_vclip = CONVOLVE_NCLIP;
else if ((marginy = area->height - paint_tool->brush->mask->height - 2) != 0)
else if ((marginy = area->height - paint_core->brush->mask->height - 2) != 0)
area_vclip = CONVOLVE_PCLIP;
/* Has the TempBuf been clipped by a canvas edge or two ? */
@ -451,9 +326,9 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
fillcolor = gimp_drawable_get_color_at
(drawable,
CLAMP ((gint) paint_tool->cur_coords.x,
CLAMP ((gint) paint_core->cur_coords.x,
0, gimp_drawable_width (drawable) - 1),
CLAMP ((gint) paint_tool->cur_coords.y,
CLAMP ((gint) paint_core->cur_coords.y,
0, gimp_drawable_height (drawable) - 1));
marginx *= (marginx < 0) ? -1 : 0;
@ -463,7 +338,8 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
ovrsz2PR.y = 0;
ovrsz2PR.w = area->width + marginx;
ovrsz2PR.h = area->height + marginy;
ovrsz2PR.bytes = (gimp_drawable_has_alpha (drawable))? srcPR.bytes : srcPR.bytes + 1;
ovrsz2PR.bytes = (gimp_drawable_has_alpha (drawable) ?
srcPR.bytes : srcPR.bytes + 1);
ovrsz2PR.offx = 0;
ovrsz2PR.offy = 0;
ovrsz2PR.rowstride = ovrsz2PR.bytes * ovrsz2PR.w;
@ -475,7 +351,8 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
ovrsz1PR.y = 0;
ovrsz1PR.w = area->width + marginx;
ovrsz1PR.h = area->height + marginy;
ovrsz1PR.bytes = (gimp_drawable_has_alpha (drawable))? srcPR.bytes : srcPR.bytes + 1;
ovrsz1PR.bytes = (gimp_drawable_has_alpha (drawable) ?
srcPR.bytes : srcPR.bytes + 1);
ovrsz1PR.offx = 0;
ovrsz1PR.offy = 0;
ovrsz1PR.rowstride = ovrsz2PR.bytes * ovrsz2PR.w;
@ -489,7 +366,9 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
ovrsz1PR.y = (area_vclip == CONVOLVE_NCLIP)? marginy : 0;
ovrsz1PR.w = area->width;
ovrsz1PR.h = area->height;
ovrsz1PR.data = ovrsz1_data + (ovrsz1PR.rowstride * ovrsz1PR.y) + (ovrsz1PR.bytes * ovrsz1PR.x);
ovrsz1PR.data = (ovrsz1_data +
(ovrsz1PR.rowstride * ovrsz1PR.y) +
(ovrsz1PR.bytes * ovrsz1PR.x));
if (! gimp_drawable_has_alpha (drawable))
add_alpha_region (&srcPR, &ovrsz1PR);
@ -513,7 +392,9 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
ovrsz2PR.y = (area_vclip == CONVOLVE_NCLIP)? marginy : 0;
ovrsz2PR.w = area->width;
ovrsz2PR.h = area->height;
ovrsz2PR.data = ovrsz2_data + (ovrsz2PR.rowstride * ovrsz2PR.y) + (ovrsz2PR.bytes * ovrsz2PR.x);
ovrsz2PR.data = (ovrsz2_data +
(ovrsz2PR.rowstride * ovrsz2PR.y) +
(ovrsz2PR.bytes * ovrsz2PR.x));
copy_region (&ovrsz2PR, &destPR);
@ -525,15 +406,17 @@ gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
context = gimp_get_current_context (gimp_drawable_gimage (drawable)->gimp);
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_replace_canvas (paint_tool, drawable, OPAQUE_OPACITY,
gimp_paint_core_replace_canvas (paint_core, drawable,
OPAQUE_OPACITY,
(gint) (gimp_context_get_opacity (context) * 255),
pressure_options->pressure ? PRESSURE : SOFT,
scale, INCREMENTAL);
scale,
INCREMENTAL);
}
static void
calculate_matrix (ConvolveType type,
gdouble rate)
gimp_convolve_calculate_matrix (ConvolveType type,
gdouble rate)
{
gfloat percent;
@ -546,13 +429,13 @@ calculate_matrix (ConvolveType type,
case BLUR_CONVOLVE:
matrix_size = 5;
blur_matrix [12] = MIN_BLUR + percent * (MAX_BLUR - MIN_BLUR);
copy_matrix (blur_matrix, custom_matrix, matrix_size);
gimp_convolve_copy_matrix (blur_matrix, custom_matrix, matrix_size);
break;
case SHARPEN_CONVOLVE:
matrix_size = 5;
sharpen_matrix [12] = MIN_SHARPEN + percent * (MAX_SHARPEN - MIN_SHARPEN);
copy_matrix (sharpen_matrix, custom_matrix, matrix_size);
gimp_convolve_copy_matrix (sharpen_matrix, custom_matrix, matrix_size);
break;
case CUSTOM_CONVOLVE:
@ -560,17 +443,17 @@ calculate_matrix (ConvolveType type,
break;
}
integer_matrix (custom_matrix, matrix, matrix_size);
matrix_divisor = sum_matrix (matrix, matrix_size);
gimp_convolve_integer_matrix (custom_matrix, matrix, matrix_size);
matrix_divisor = gimp_convolve_sum_matrix (matrix, matrix_size);
if (!matrix_divisor)
matrix_divisor = 1;
}
static void
integer_matrix (gfloat *source,
gint *dest,
gint size)
gimp_convolve_integer_matrix (gfloat *source,
gint *dest,
gint size)
{
gint i;
@ -581,9 +464,9 @@ integer_matrix (gfloat *source,
}
static void
copy_matrix (gfloat *src,
gfloat *dest,
gint size)
gimp_convolve_copy_matrix (gfloat *src,
gfloat *dest,
gint size)
{
gint i;
@ -592,8 +475,8 @@ copy_matrix (gfloat *src,
}
static gint
sum_matrix (gint *matrix,
gint size)
gimp_convolve_sum_matrix (gint *matrix,
gint size)
{
gint sum = 0;
@ -604,156 +487,3 @@ sum_matrix (gint *matrix,
return sum;
}
#if 0 /* Leave these to the STUBs */
static gpointer
convolve_non_gui_paint_func (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
convolve_motion (paint_tool, drawable, &non_gui_pressure_options,
non_gui_type, non_gui_rate);
return NULL;
}
gboolean
convolve_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
gdouble rate = DEFAULT_CONVOLVE_RATE;
ConvolveType type = DEFAULT_CONVOLVE_TYPE;
ConvolveOptions *options = convolve_options;
if (options)
{
rate = options->rate;
type = options->type;
}
return convolve_non_gui (drawable, rate, type, num_strokes, stroke_array);
}
gboolean
convolve_non_gui (GimpDrawable *drawable,
gdouble rate,
ConvolveType type,
gint num_strokes,
gdouble *stroke_array)
{
gint i;
if (gimp_paint_tool_init (&non_gui_paint_core, drawable,
stroke_array[0], stroke_array[1]))
{
non_gui_type = type;
non_gui_rate = rate;
non_gui_paint_core.startx = non_gui_paint_core.lastx = stroke_array[0];
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
convolve_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
non_gui_paint_core.cur_coords.x = stroke_array[i * 2 + 0];
non_gui_paint_core.cur_coords.y = stroke_array[i * 2 + 1];
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.last_coords.x = non_gui_paint_core.cur_coords.x;
non_gui_paint_core.last_coords.y = non_gui_paint_core.cur_coords.y;
}
paint_core_finish (&non_gui_paint_core, drawable, -1);
paint_core_cleanup ();
return TRUE;
}
return FALSE;
}
#endif /* 0 - non-gui functions */
static GimpToolOptions *
convolve_options_new (GimpToolInfo *tool_info)
{
ConvolveOptions *options;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *scale;
GtkWidget *frame;
options = g_new0 (ConvolveOptions, 1);
paint_options_init ((PaintOptions *) options, tool_info);
((GimpToolOptions *) options)->reset_func = convolve_options_reset;
options->type = options->type_d = DEFAULT_CONVOLVE_TYPE;
options->rate = options->rate_d = DEFAULT_CONVOLVE_RATE;
/* the main vbox */
vbox = ((GimpToolOptions *) options)->main_vbox;
/* the rate scale */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Rate:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
options->rate_w =
gtk_adjustment_new (options->rate_d, 0.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->rate_w));
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
g_signal_connect (G_OBJECT (options->rate_w), "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&options->rate);
gtk_widget_show (scale);
gtk_widget_show (hbox);
frame = gimp_radio_group_new2 (TRUE, _("Convolve Type (<Ctrl>)"),
G_CALLBACK (gimp_radio_button_update),
&options->type,
GINT_TO_POINTER (options->type),
_("Blur"),
GINT_TO_POINTER (BLUR_CONVOLVE),
&options->type_w[0],
_("Sharpen"),
GINT_TO_POINTER (SHARPEN_CONVOLVE),
&options->type_w[1],
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
return (GimpToolOptions *) options;
}
static void
convolve_options_reset (GimpToolOptions *tool_options)
{
ConvolveOptions *options;
options = (ConvolveOptions *) tool_options;
paint_options_reset (tool_options);
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->rate_w),
options->rate_d);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (options->type_d));
}

View File

@ -16,58 +16,52 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_CONVOLVE_TOOL_H__
#define __GIMP_CONVOLVE_TOOL_H__
#ifndef __GIMP_CONVOLVE_H__
#define __GIMP_CONVOLVE_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
typedef enum
#define GIMP_TYPE_CONVOLVE (gimp_convolve_get_type ())
#define GIMP_CONVOLVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CONVOLVE, GimpConvolve))
#define GIMP_CONVOLVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CONVOLVE, GimpConvolveClass))
#define GIMP_IS_CONVOLVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CONVOLVE))
#define GIMP_IS_CONVOLVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CONVOLVE))
#define GIMP_CONVOLVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CONVOLVE, GimpConvolveClass))
typedef struct _GimpConvolve GimpConvolve;
typedef struct _GimpConvolveClass GimpConvolveClass;
struct _GimpConvolve
{
BLUR_CONVOLVE,
SHARPEN_CONVOLVE,
CUSTOM_CONVOLVE
} ConvolveType;
#define GIMP_TYPE_CONVOLVE_TOOL (gimp_convolve_tool_get_type ())
#define GIMP_CONVOLVE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CONVOLVE_TOOL, GimpConvolveTool))
#define GIMP_CONVOLVE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CONVOLVE_TOOL, GimpConvolveToolClass))
#define GIMP_IS_CONVOLVE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CONVOLVE_TOOL))
#define GIMP_IS_CONVOLVE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CONVOLVE_TOOL))
#define GIMP_CONVOLVE_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CONVOLVE_TOOL, GimpConvolveToolClass))
typedef struct _GimpConvolveTool GimpConvolveTool;
typedef struct _GimpConvolveToolClass GimpConvolveToolClass;
struct _GimpConvolveTool
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
};
struct _GimpConvolveToolClass
struct _GimpConvolveClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_convolve_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
typedef struct _ConvolveOptions ConvolveOptions;
GType gimp_convolve_tool_get_type (void) G_GNUC_CONST;
struct _ConvolveOptions
{
PaintOptions paint_options;
ConvolveType type;
ConvolveType type_d;
GtkWidget *type_w[2];
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
};
/* FIXME: These need to disappear */
gboolean convolve_non_gui (GimpDrawable *drawable,
gdouble rate,
ConvolveType type,
gint num_strokes,
gdouble *stroke_array);
gboolean convolve_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
GType gimp_convolve_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_CONVOLVE_TOOL_H__ */
#endif /* __GIMP_CONVOLVE_H__ */

View File

@ -19,12 +19,10 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/gimplut.h"
#include "base/pixel-region.h"
@ -36,183 +34,103 @@
#include "core/gimpdrawable.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "gimpdodgeburntool.h"
#include "paint_options.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
#include "gimpdodgeburn.h"
/* Default values */
static void gimp_dodgeburn_class_init (GimpDodgeBurnClass *klass);
static void gimp_dodgeburn_init (GimpDodgeBurn *dodgeburn);
#define DODGEBURN_DEFAULT_EXPOSURE 50.0
#define DODGEBURN_DEFAULT_TYPE DODGE
#define DODGEBURN_DEFAULT_MODE GIMP_HIGHLIGHTS
static void gimp_dodgeburn_make_luts (GimpPaintCore *paint_core,
gdouble db_exposure,
DodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable);
/* the dodgeburn structures */
static void gimp_dodgeburn_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
typedef struct _DodgeBurnOptions DodgeBurnOptions;
static void gimp_dodgeburn_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options);
struct _DodgeBurnOptions
{
PaintOptions paint_options;
DodgeBurnType type;
DodgeBurnType type_d;
GtkWidget *type_w[2];
GimpTransferMode mode; /*highlights, midtones, shadows*/
GimpTransferMode mode_d;
GtkWidget *mode_w[3];
gdouble exposure;
gdouble exposure_d;
GtkObject *exposure_w;
GimpLut *lut;
};
static gfloat gimp_dodgeburn_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static void gimp_dodgeburn_tool_class_init (GimpDodgeBurnToolClass *klass);
static void gimp_dodgeburn_tool_init (GimpDodgeBurnTool *dodgeburn);
static GimpPaintCoreClass *parent_class = NULL;
static void gimp_dodgeburn_tool_make_luts (GimpPaintTool *paint_tool,
gdouble db_exposure,
DodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable);
static void gimp_dodgeburn_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_dodgeburn_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_dodgeburn_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble dodgeburn_exposure,
GimpLut *lut);
static gfloat gimp_dodgeburn_tool_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_tool_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_tool_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static GimpToolOptions * gimp_dodgeburn_tool_options_new (GimpToolInfo *tool_info);
static void gimp_dodgeburn_tool_options_reset (GimpToolOptions *tool_options);
static gdouble non_gui_exposure;
static GimpLut *non_gui_lut;
static GimpPaintToolClass *parent_class = NULL;
/* functions */
void
gimp_dodgeburn_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_DODGEBURN_TOOL,
gimp_dodgeburn_tool_options_new,
TRUE,
"gimp:dodgeburn_tool",
_("Dodge/Burn"),
_("Dodge or Burn strokes"),
N_("/Tools/Paint Tools/DodgeBurn"), "<shift>D",
NULL, "tools/dodgeburn.html",
GIMP_STOCK_TOOL_DODGE);
}
GType
gimp_dodgeburn_tool_get_type (void)
gimp_dodgeburn_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (!tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpDodgeBurnToolClass),
sizeof (GimpDodgeBurnClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_dodgeburn_tool_class_init,
(GClassInitFunc) gimp_dodgeburn_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpDodgeBurnTool),
sizeof (GimpDodgeBurn),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_dodgeburn_tool_init,
(GInstanceInitFunc) gimp_dodgeburn_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpDodgeBurnTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpDodgeBurn",
&info, 0);
}
return tool_type;
return type;
}
static void
gimp_dodgeburn_tool_class_init (GimpDodgeBurnToolClass *klass)
gimp_dodgeburn_class_init (GimpDodgeBurnClass *klass)
{
GimpToolClass *tool_class;
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
tool_class = GIMP_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->modifier_key = gimp_dodgeburn_tool_modifier_key;
tool_class->cursor_update = gimp_dodgeburn_tool_cursor_update;
paint_tool_class->paint = gimp_dodgeburn_tool_paint;
paint_core_class->paint = gimp_dodgeburn_paint;
}
static void
gimp_dodgeburn_tool_init (GimpDodgeBurnTool *dodgeburn)
gimp_dodgeburn_init (GimpDodgeBurn *dodgeburn)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (dodgeburn);
paint_tool = GIMP_PAINT_TOOL (dodgeburn);
paint_core = GIMP_PAINT_CORE (dodgeburn);
tool->tool_cursor = GIMP_DODGE_TOOL_CURSOR;
tool->toggle_tool_cursor = GIMP_BURN_TOOL_CURSOR;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_dodgeburn_tool_make_luts (GimpPaintTool *paint_tool,
gdouble db_exposure,
DodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable)
gimp_dodgeburn_make_luts (GimpPaintCore *paint_core,
gdouble db_exposure,
DodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable)
{
GimpLutFunc lut_func;
gint nchannels = gimp_drawable_bytes (drawable);
@ -227,13 +145,13 @@ gimp_dodgeburn_tool_make_luts (GimpPaintTool *paint_tool,
switch (mode)
{
case GIMP_HIGHLIGHTS:
lut_func = gimp_dodgeburn_tool_highlights_lut_func;
lut_func = gimp_dodgeburn_highlights_lut_func;
break;
case GIMP_MIDTONES:
lut_func = gimp_dodgeburn_tool_midtones_lut_func;
lut_func = gimp_dodgeburn_midtones_lut_func;
break;
case GIMP_SHADOWS:
lut_func = gimp_dodgeburn_tool_shadows_lut_func;
lut_func = gimp_dodgeburn_shadows_lut_func;
break;
default:
lut_func = NULL;
@ -246,105 +164,36 @@ gimp_dodgeburn_tool_make_luts (GimpPaintTool *paint_tool,
}
static void
gimp_dodgeburn_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp)
gimp_dodgeburn_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
DodgeBurnOptions *options;
options = (DodgeBurnOptions *) tool->tool_info->tool_options;
options = (DodgeBurnOptions *) paint_options;
if (key == GDK_CONTROL_MASK &&
! (state & GDK_SHIFT_MASK)) /* leave stuff untouched in line draw mode */
{
switch (options->type)
{
case DODGE:
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (BURN));
break;
case BURN:
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (DODGE));
break;
default:
break;
}
}
tool->toggled = (options->type == BURN);
}
static void
gimp_dodgeburn_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp)
{
DodgeBurnOptions *options;
options = (DodgeBurnOptions *) tool->tool_info->tool_options;
tool->toggled = (options->type == BURN);
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_dodgeburn_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
DodgeBurnOptions *options;
PaintPressureOptions *pressure_options;
gdouble exposure;
GimpLut *lut;
options = (DodgeBurnOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
exposure = options->exposure;
lut = options->lut;
}
else
{
pressure_options = &non_gui_pressure_options;
exposure = non_gui_exposure;
lut = non_gui_lut;
}
switch (state)
switch (paint_state)
{
case INIT_PAINT:
if (options)
{
options->lut = gimp_lut_new ();
options->lut = gimp_lut_new ();
gimp_dodgeburn_tool_make_luts (paint_tool,
options->exposure,
options->type,
options->mode,
options->lut,
drawable);
lut = options->lut;
}
gimp_dodgeburn_make_luts (paint_core,
options->exposure,
options->type,
options->mode,
options->lut,
drawable);
break;
case MOTION_PAINT:
gimp_dodgeburn_tool_motion (paint_tool,
drawable,
pressure_options,
exposure,
lut);
gimp_dodgeburn_motion (paint_core,
drawable,
paint_options);
break;
case FINISH_PAINT:
if (options && options->lut)
if (options->lut)
{
gimp_lut_free (options->lut);
options->lut = NULL;
@ -357,19 +206,19 @@ gimp_dodgeburn_tool_paint (GimpPaintTool *paint_tool,
}
static void
gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
double dodgeburn_exposure,
GimpLut *lut)
gimp_dodgeburn_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options)
{
GimpImage *gimage;
TempBuf *area;
TempBuf *orig;
PixelRegion srcPR, destPR, tempPR;
guchar *temp_data;
gint opacity;
gdouble scale;
DodgeBurnOptions *options;
PaintPressureOptions *pressure_options;
GimpImage *gimage;
TempBuf *area;
TempBuf *orig;
PixelRegion srcPR, destPR, tempPR;
guchar *temp_data;
gint opacity;
gdouble scale;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
@ -379,13 +228,17 @@ gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
(gimp_drawable_type (drawable) == GIMP_INDEXEDA_IMAGE))
return;
options = (DodgeBurnOptions *) paint_options;
pressure_options = paint_options->pressure_options;
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
/* Constant painting --get a copy of the orig drawable (with no
@ -403,36 +256,39 @@ gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
return;
/* get the original untouched image */
orig = gimp_paint_tool_get_orig_image (paint_tool, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0;
srcPR.y = 0;
srcPR.w = x2 - x1;
srcPR.h = y2 - y1;
orig = gimp_paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0;
srcPR.y = 0;
srcPR.w = x2 - x1;
srcPR.h = y2 - y1;
srcPR.rowstride = srcPR.bytes * orig->width;
srcPR.data = temp_buf_data (orig);
srcPR.data = temp_buf_data (orig);
}
/* tempPR will hold the dodgeburned region*/
tempPR.bytes = srcPR.bytes;
tempPR.x = srcPR.x;
tempPR.y = srcPR.y;
tempPR.w = srcPR.w;
tempPR.h = srcPR.h;
tempPR.bytes = srcPR.bytes;
tempPR.x = srcPR.x;
tempPR.y = srcPR.y;
tempPR.w = srcPR.w;
tempPR.h = srcPR.h;
tempPR.rowstride = tempPR.bytes * tempPR.w;
temp_data = g_malloc (tempPR.h * tempPR.rowstride);
tempPR.data = temp_data;
tempPR.data = g_malloc (tempPR.h * tempPR.rowstride);
temp_data = tempPR.data;
/* DodgeBurn the region */
gimp_lut_process (lut, &srcPR, &tempPR);
gimp_lut_process (options->lut, &srcPR, &tempPR);
/* The dest is the paint area we got above (= canvas_buf) */
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.bytes = area->bytes;
destPR.x = 0;
destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.rowstride = area->width * destPR.bytes;
destPR.data = temp_buf_data (area);
destPR.data = temp_buf_data (area);
/* Now add an alpha to the dodgeburned region
and put this in area = canvas_buf */
@ -445,10 +301,10 @@ gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
255 * gimp_context_get_opacity (gimp_get_current_context (gimage->gimp));
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* Replace the newly dodgedburned area (canvas_buf) to the gimage*/
gimp_paint_tool_replace_canvas (paint_tool, drawable,
gimp_paint_core_replace_canvas (paint_core, drawable,
MIN (opacity, 255),
OPAQUE_OPACITY,
pressure_options->pressure ? PRESSURE : SOFT,
@ -458,10 +314,10 @@ gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
}
static gfloat
gimp_dodgeburn_tool_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
gimp_dodgeburn_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
gfloat exposure = *exposure_ptr;
@ -475,10 +331,10 @@ gimp_dodgeburn_tool_highlights_lut_func (gpointer user_data,
}
static gfloat
gimp_dodgeburn_tool_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
gimp_dodgeburn_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
gfloat exposure = *exposure_ptr;
@ -497,10 +353,10 @@ gimp_dodgeburn_tool_midtones_lut_func (gpointer user_data,
}
static gfloat
gimp_dodgeburn_tool_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
gimp_dodgeburn_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
gfloat exposure = *exposure_ptr;
@ -527,208 +383,3 @@ gimp_dodgeburn_tool_shadows_lut_func (gpointer user_data,
return new_value;
}
/* non-gui stuff */
gboolean
gimp_dodgeburn_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
GimpToolInfo *tool_info;
DodgeBurnOptions *options;
gdouble exposure = DODGEBURN_DEFAULT_EXPOSURE;
DodgeBurnType type = DODGEBURN_DEFAULT_TYPE;
GimpTransferMode mode = DODGEBURN_DEFAULT_MODE;
tool_info = tool_manager_get_info_by_type (drawable->gimage->gimp,
GIMP_TYPE_DODGEBURN_TOOL);
options = (DodgeBurnOptions *) tool_info->tool_options;
if (options)
{
exposure = options->exposure;
type = options->type;
mode = options->mode;
}
return gimp_dodgeburn_tool_non_gui (drawable, exposure, type, mode,
num_strokes, stroke_array);
}
gboolean
gimp_dodgeburn_tool_non_gui (GimpDrawable *drawable,
gdouble exposure,
DodgeBurnType type,
GimpTransferMode mode,
gint num_strokes,
gdouble *stroke_array)
{
static GimpDodgeBurnTool *non_gui_dodgeburn = NULL;
GimpPaintTool *paint_tool;
gint i;
if (! non_gui_dodgeburn)
{
non_gui_dodgeburn = g_object_new (GIMP_TYPE_DODGEBURN_TOOL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_dodgeburn);
if (gimp_paint_tool_start (paint_tool, drawable,
stroke_array[0],
stroke_array[1]))
{
non_gui_exposure = exposure;
non_gui_lut = gimp_lut_new ();
gimp_dodgeburn_tool_make_luts (paint_tool,
exposure,
type,
mode,
non_gui_lut,
drawable);
paint_tool->start_coords.x = paint_tool->last_coords.x = stroke_array[0];
paint_tool->start_coords.y = paint_tool->last_coords.y = stroke_array[1];
gimp_dodgeburn_tool_paint (paint_tool, drawable, MOTION_PAINT);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
gimp_lut_free (non_gui_lut);
non_gui_lut = NULL;
return TRUE;
}
return FALSE;
}
/* tool options stuff */
static GimpToolOptions *
gimp_dodgeburn_tool_options_new (GimpToolInfo *tool_info)
{
DodgeBurnOptions *options;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *scale;
GtkWidget *frame;
options = g_new0 (DodgeBurnOptions, 1);
paint_options_init ((PaintOptions *) options, tool_info);
((GimpToolOptions *) options)->reset_func = gimp_dodgeburn_tool_options_reset;
options->type = options->type_d = DODGEBURN_DEFAULT_TYPE;
options->exposure = options->exposure_d = DODGEBURN_DEFAULT_EXPOSURE;
options->mode = options->mode_d = DODGEBURN_DEFAULT_MODE;
options->lut = NULL;
/* the main vbox */
vbox = ((GimpToolOptions *) options)->main_vbox;
/* the exposure scale */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Exposure:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
options->exposure_w =
gtk_adjustment_new (options->exposure_d, 0.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->exposure_w));
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
g_signal_connect (G_OBJECT (options->exposure_w), "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&options->exposure);
gtk_widget_show (scale);
gtk_widget_show (hbox);
/* the type (dodge or burn) */
frame = gimp_radio_group_new2 (TRUE, _("Type (<Ctrl>)"),
G_CALLBACK (gimp_radio_button_update),
&options->type,
GINT_TO_POINTER (options->type),
_("Dodge"),
GINT_TO_POINTER (DODGE),
&options->type_w[0],
_("Burn"),
GINT_TO_POINTER (BURN),
&options->type_w[1],
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* mode (highlights, midtones, or shadows) */
frame = gimp_radio_group_new2 (TRUE, _("Mode"),
G_CALLBACK (gimp_radio_button_update),
&options->mode,
GINT_TO_POINTER (options->mode),
_("Highlights"),
GINT_TO_POINTER (GIMP_HIGHLIGHTS),
&options->mode_w[0],
_("Midtones"),
GINT_TO_POINTER (GIMP_MIDTONES),
&options->mode_w[1],
_("Shadows"),
GINT_TO_POINTER (GIMP_SHADOWS),
&options->mode_w[2],
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
return (GimpToolOptions *) options;
}
static void
gimp_dodgeburn_tool_options_reset (GimpToolOptions *tool_options)
{
DodgeBurnOptions *options;
options = (DodgeBurnOptions *) tool_options;
paint_options_reset (tool_options);
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->exposure_w),
options->exposure_d);
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (options->type_d));
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->mode_w[0]),
GINT_TO_POINTER (options->mode_d));
}

View File

@ -16,57 +16,57 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_DODGE_BURN_TOOL_H__
#define __GIMP_DODGE_BURN_TOOL_H__
#ifndef __GIMP_DODGE_BURN_H__
#define __GIMP_DODGE_BURN_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
typedef enum
#define GIMP_TYPE_DODGEBURN (gimp_dodgeburn_get_type ())
#define GIMP_DODGEBURN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DODGEBURN, GimpDodgeBurn))
#define GIMP_IS_DODGEBURN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DODGEBURN))
#define GIMP_DODGEBURN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DODGEBURN, GimpDodgeBurnClass))
#define GIMP_IS_DODGEBURN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DODGEBURN))
typedef struct _GimpDodgeBurn GimpDodgeBurn;
typedef struct _GimpDodgeBurnClass GimpDodgeBurnClass;
struct _GimpDodgeBurn
{
DODGE,
BURN
} DodgeBurnType;
#define GIMP_TYPE_DODGEBURN_TOOL (gimp_dodgeburn_tool_get_type ())
#define GIMP_DODGEBURN_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DODGEBURN_TOOL, GimpDodgeBurnTool))
#define GIMP_IS_DODGEBURN_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DODGEBURN_TOOL))
#define GIMP_DODGEBURN_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DODGEBURN_TOOL, GimpDodgeBurnToolClass))
#define GIMP_IS_DODGEBURN_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DODGEBURN_TOOL))
typedef struct _GimpDodgeBurnTool GimpDodgeBurnTool;
typedef struct _GimpDodgeBurnToolClass GimpDodgeBurnToolClass;
struct _GimpDodgeBurnTool
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
};
struct _GimpDodgeBurnToolClass
struct _GimpDodgeBurnClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_dodgeburn_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
typedef struct _DodgeBurnOptions DodgeBurnOptions;
GType gimp_dodgeburn_tool_get_type (void) G_GNUC_CONST;
struct _DodgeBurnOptions
{
PaintOptions paint_options;
DodgeBurnType type;
DodgeBurnType type_d;
GtkWidget *type_w[2];
GimpTransferMode mode; /*highlights, midtones, shadows*/
GimpTransferMode mode_d;
GtkWidget *mode_w[3];
gdouble exposure;
gdouble exposure_d;
GtkObject *exposure_w;
GimpLut *lut;
};
gboolean gimp_dodgeburn_tool_non_gui (GimpDrawable *drawable,
gdouble exposure,
DodgeBurnType type,
GimpTransferMode mode,
gint num_strokes,
gdouble *stroke_array);
gboolean gimp_dodgeburn_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
GType gimp_dodgeburn_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_DODGEBURN_TOOL_H__ */
#endif /* __GIMP_DODGEBURN_H__ */

View File

@ -19,12 +19,10 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/temp-buf.h"
@ -34,226 +32,91 @@
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "gimperasertool.h"
#include "paint_options.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
#include "gimperaser.h"
#define ERASER_DEFAULT_HARD FALSE
#define ERASER_DEFAULT_INCREMENTAL FALSE
#define ERASER_DEFAULT_ANTI_ERASE FALSE
static void gimp_eraser_class_init (GimpEraserClass *klass);
static void gimp_eraser_init (GimpEraser *eraser);
static void gimp_eraser_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_eraser_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options);
typedef struct _EraserOptions EraserOptions;
static GimpPaintCoreClass *parent_class = NULL;
struct _EraserOptions
{
PaintOptions paint_options;
gboolean hard;
gboolean hard_d;
GtkWidget *hard_w;
gboolean anti_erase;
gboolean anti_erase_d;
GtkWidget *anti_erase_w;
};
static void gimp_eraser_tool_class_init (GimpEraserToolClass *klass);
static void gimp_eraser_tool_init (GimpEraserTool *eraser);
static void gimp_eraser_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_eraser_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_eraser_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_eraser_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean hard,
gboolean incremental,
gboolean anti_erase);
static GimpToolOptions * gimp_eraser_tool_options_new (GimpToolInfo *tool_info);
static void gimp_eraser_tool_options_reset (GimpToolOptions *tool_options);
/* local variables */
static gboolean non_gui_hard = ERASER_DEFAULT_HARD;
static gboolean non_gui_incremental = ERASER_DEFAULT_INCREMENTAL;
static gboolean non_gui_anti_erase = ERASER_DEFAULT_ANTI_ERASE;
static GimpPaintToolClass *parent_class = NULL;
/* functions */
void
gimp_eraser_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_ERASER_TOOL,
gimp_eraser_tool_options_new,
TRUE,
"gimp:eraser_tool",
_("Eraser"),
_("Paint fuzzy brush strokes"),
N_("/Tools/Paint Tools/Eraser"), "<shift>E",
NULL, "tools/eraser.html",
GIMP_STOCK_TOOL_ERASER);
}
GType
gimp_eraser_tool_get_type (void)
gimp_eraser_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpEraserToolClass),
sizeof (GimpEraserClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_eraser_tool_class_init,
(GClassInitFunc) gimp_eraser_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpEraserTool),
sizeof (GimpEraser),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_eraser_tool_init,
(GInstanceInitFunc) gimp_eraser_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpEraserTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpEraser",
&info, 0);
}
return tool_type;
return type;
}
static void
gimp_eraser_tool_class_init (GimpEraserToolClass *klass)
gimp_eraser_class_init (GimpEraserClass *klass)
{
GimpToolClass *tool_class;
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
tool_class = GIMP_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->modifier_key = gimp_eraser_tool_modifier_key;
tool_class->cursor_update = gimp_eraser_tool_cursor_update;
paint_tool_class->paint = gimp_eraser_tool_paint;
paint_core_class->paint = gimp_eraser_paint;
}
static void
gimp_eraser_tool_init (GimpEraserTool *eraser)
gimp_eraser_init (GimpEraser *eraser)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (eraser);
paint_tool = GIMP_PAINT_TOOL (eraser);
paint_core = GIMP_PAINT_CORE (eraser);
tool->tool_cursor = GIMP_ERASER_TOOL_CURSOR;
tool->cursor_modifier = GIMP_CURSOR_MODIFIER_NONE;
tool->toggle_tool_cursor = GIMP_ERASER_TOOL_CURSOR;
tool->toggle_cursor_modifier = GIMP_CURSOR_MODIFIER_MINUS;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_eraser_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp)
gimp_eraser_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
EraserOptions *options;
options = (EraserOptions *) tool->tool_info->tool_options;
if ((key == GDK_CONTROL_MASK) &&
! (state & GDK_SHIFT_MASK)) /* leave stuff untouched in line draw mode */
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->anti_erase_w),
! options->anti_erase);
}
}
static void
gimp_eraser_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp)
{
EraserOptions *options;
options = (EraserOptions *) tool->tool_info->tool_options;
tool->toggled = options->anti_erase;
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_eraser_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
EraserOptions *options;
PaintPressureOptions *pressure_options;
gboolean hard;
gboolean incremental;
gboolean anti_erase;
options = (EraserOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
hard = options->hard;
incremental = options->paint_options.incremental;
anti_erase = options->anti_erase;
}
else
{
pressure_options = &non_gui_pressure_options;
hard = non_gui_hard;
incremental = non_gui_incremental;
anti_erase = non_gui_anti_erase;
}
switch (state)
switch (paint_state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
gimp_eraser_tool_motion (paint_tool,
drawable,
pressure_options,
hard,
incremental,
anti_erase);
gimp_eraser_motion (paint_core,
drawable,
paint_options);
break;
case FINISH_PAINT:
@ -265,34 +128,37 @@ gimp_eraser_tool_paint (GimpPaintTool *paint_tool,
}
static void
gimp_eraser_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean hard,
gboolean incremental,
gboolean anti_erase)
gimp_eraser_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options)
{
GimpImage *gimage;
GimpContext *context;
gint opacity;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
EraserOptions *options;
PaintPressureOptions *pressure_options;
GimpImage *gimage;
GimpContext *context;
gint opacity;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
options = (EraserOptions *) paint_options;
pressure_options = paint_options->pressure_options;
gimp_image_get_background (gimage, drawable, col);
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
/* set the alpha channel */
@ -305,157 +171,16 @@ gimp_eraser_tool_motion (GimpPaintTool *paint_tool,
opacity = 255 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being
* worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
* worked on
*/
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, 255),
gimp_context_get_opacity (context) * 255,
anti_erase ? GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE,
hard ? HARD : (pressure_options->pressure ? PRESSURE : SOFT),
options->anti_erase ? GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE,
options->hard ? HARD : (pressure_options->pressure ? PRESSURE : SOFT),
scale,
incremental ? INCREMENTAL : CONSTANT);
}
/* non-gui stuff */
gboolean
eraser_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
GimpToolInfo *tool_info;
EraserOptions *options;
gboolean hard = ERASER_DEFAULT_HARD;
gboolean incremental = ERASER_DEFAULT_INCREMENTAL;
gboolean anti_erase = ERASER_DEFAULT_ANTI_ERASE;
tool_info = tool_manager_get_info_by_type (drawable->gimage->gimp,
GIMP_TYPE_ERASER_TOOL);
options = (EraserOptions *) tool_info->tool_options;
if (options)
{
hard = options->hard;
incremental = options->paint_options.incremental;
anti_erase = options->anti_erase;
}
return eraser_non_gui (drawable, num_strokes, stroke_array,
hard, incremental, anti_erase);
}
gboolean
eraser_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array,
gint hard,
gint incremental,
gboolean anti_erase)
{
static GimpEraserTool *non_gui_eraser = NULL;
GimpPaintTool *paint_tool;
gint i;
if (! non_gui_eraser)
{
non_gui_eraser = g_object_new (GIMP_TYPE_ERASER_TOOL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_eraser);
if (gimp_paint_tool_start (paint_tool, drawable,
stroke_array[0],
stroke_array[1]))
{
non_gui_hard = hard;
non_gui_incremental = incremental;
non_gui_anti_erase = anti_erase;
paint_tool->start_coords.x = paint_tool->last_coords.x = stroke_array[0];
paint_tool->start_coords.y = paint_tool->last_coords.y = stroke_array[1];
gimp_paint_tool_paint (paint_tool, drawable, MOTION_PAINT);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
return TRUE;
}
return FALSE;
}
/* tool options stuff */
static GimpToolOptions *
gimp_eraser_tool_options_new (GimpToolInfo *tool_info)
{
EraserOptions *options;
GtkWidget *vbox;
options = g_new0 (EraserOptions, 1);
paint_options_init ((PaintOptions *) options, tool_info);
((GimpToolOptions *) options)->reset_func = gimp_eraser_tool_options_reset;
options->hard = options->hard_d = ERASER_DEFAULT_HARD;
options->anti_erase = options->anti_erase_d = ERASER_DEFAULT_ANTI_ERASE;
/* the main vbox */
vbox = ((GimpToolOptions *) options)->main_vbox;
/* the hard toggle */
options->hard_w = gtk_check_button_new_with_label (_("Hard Edge"));
gtk_box_pack_start (GTK_BOX (vbox), options->hard_w, FALSE, FALSE, 0);
g_signal_connect (G_OBJECT (options->hard_w), "toggled",
G_CALLBACK (gimp_toggle_button_update),
&options->hard);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->hard_w),
options->hard_d);
gtk_widget_show (options->hard_w);
/* the anti_erase toggle */
options->anti_erase_w =
gtk_check_button_new_with_label (_("Anti Erase (<Ctrl>)"));
gtk_box_pack_start (GTK_BOX (vbox), options->anti_erase_w, FALSE, FALSE, 0);
g_signal_connect (G_OBJECT (options->anti_erase_w), "toggled",
G_CALLBACK (gimp_toggle_button_update),
&options->anti_erase);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->anti_erase_w),
options->anti_erase_d);
gtk_widget_show (options->anti_erase_w);
return (GimpToolOptions *) options;
}
static void
gimp_eraser_tool_options_reset (GimpToolOptions *tool_options)
{
EraserOptions *options;
options = (EraserOptions *) tool_options;
paint_options_reset (tool_options);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->hard_w),
options->hard_d);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->anti_erase_w),
options->anti_erase_d);
paint_options->incremental ? INCREMENTAL : CONSTANT);
}

View File

@ -16,50 +16,52 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_ERASER_TOOL_H__
#define __GIMP_ERASER_TOOL_H__
#ifndef __GIMP_ERASER_H__
#define __GIMP_ERASER_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
#define GIMP_TYPE_ERASER_TOOL (gimp_eraser_tool_get_type ())
#define GIMP_ERASER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ERASER_TOOL, GimpEraserTool))
#define GIMP_ERASER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ERASER_TOOL, GimpEraserToolClass))
#define GIMP_IS_ERASER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ERASER_TOOL))
#define GIMP_IS_ERASER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_ERASER_TOOL))
#define GIMP_ERASER_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_ERASER_TOOL, GimpEraserToolClass))
#define GIMP_TYPE_ERASER (gimp_eraser_get_type ())
#define GIMP_ERASER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ERASER, GimpEraser))
#define GIMP_ERASER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ERASER, GimpEraserClass))
#define GIMP_IS_ERASER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ERASER))
#define GIMP_IS_ERASER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_ERASER))
#define GIMP_ERASER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_ERASER, GimpEraserClass))
typedef struct _GimpEraserTool GimpEraserTool;
typedef struct _GimpEraserToolClass GimpEraserToolClass;
typedef struct _GimpEraser GimpEraser;
typedef struct _GimpEraserClass GimpEraserClass;
struct _GimpEraserTool
struct _GimpEraser
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
};
struct _GimpEraserToolClass
struct _GimpEraserClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_eraser_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
typedef struct _EraserOptions EraserOptions;
GType gimp_eraser_tool_get_type (void) G_GNUC_CONST;
struct _EraserOptions
{
PaintOptions paint_options;
gboolean hard;
gboolean hard_d;
GtkWidget *hard_w;
gboolean anti_erase;
gboolean anti_erase_d;
GtkWidget *anti_erase_w;
};
gboolean eraser_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array,
gint hardness,
gint method,
gboolean anti_erase);
gboolean eraser_non_gui_default (GimpDrawable *paint_core,
gint num_strokes,
gdouble *stroke_array);
GType gimp_eraser_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_ERASER_TOOL_H__ */
#endif /* __GIMP_ERASER_H__ */

View File

@ -23,9 +23,8 @@
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/temp-buf.h"
@ -37,123 +36,87 @@
#include "core/gimpdrawable.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "gimppaintbrushtool.h"
#include "paint_options.h"
#include "libgimp/gimpintl.h"
#include "gimppaintbrush.h"
#define PAINT_LEFT_THRESHOLD 0.05
#define PAINTBRUSH_DEFAULT_INCREMENTAL FALSE
static void gimp_paintbrush_class_init (GimpPaintbrushClass *klass);
static void gimp_paintbrush_init (GimpPaintbrush *paintbrush);
static void gimp_paintbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_paintbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
PaintGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GradientPaintMode gradient_type);
static void gimp_paintbrush_tool_class_init (GimpPaintbrushToolClass *klass);
static void gimp_paintbrush_tool_init (GimpPaintbrushTool *tool);
static GimpPaintCoreClass *parent_class = NULL;
static void gimp_paintbrush_tool_paint (GimpPaintTool *paint_core,
GimpDrawable *drawable,
PaintState state);
static void gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
PaintGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GradientPaintMode gradient_type);
/* local variables */
static gboolean non_gui_incremental = PAINTBRUSH_DEFAULT_INCREMENTAL;
static GimpPaintToolClass *parent_class = NULL;
/* public functions */
void
gimp_paintbrush_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_PAINTBRUSH_TOOL,
paint_options_new,
TRUE,
"gimp:paintbrush_tool",
_("Paintbrush"),
_("Paint fuzzy brush strokes"),
N_("/Tools/Paint Tools/Paintbrush"), "P",
NULL, "tools/paintbrush.html",
GIMP_STOCK_TOOL_PAINTBRUSH);
}
GType
gimp_paintbrush_tool_get_type (void)
gimp_paintbrush_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpPaintbrushToolClass),
sizeof (GimpPaintbrushClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_paintbrush_tool_class_init,
(GClassInitFunc) gimp_paintbrush_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpPaintbrushTool),
sizeof (GimpPaintbrush),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_paintbrush_tool_init,
(GInstanceInitFunc) gimp_paintbrush_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpPaintbrushTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpPaintbrush",
&info, 0);
}
return tool_type;
return type;
}
/* private functions */
static void
gimp_paintbrush_tool_class_init (GimpPaintbrushToolClass *klass)
gimp_paintbrush_class_init (GimpPaintbrushClass *klass)
{
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
paint_tool_class->paint = gimp_paintbrush_tool_paint;
paint_core_class->paint = gimp_paintbrush_paint;
}
static void
gimp_paintbrush_tool_init (GimpPaintbrushTool *paintbrush)
gimp_paintbrush_init (GimpPaintbrush *paintbrush)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (paintbrush);
paint_tool = GIMP_PAINT_TOOL (paintbrush);
paint_core = GIMP_PAINT_CORE (paintbrush);
tool->tool_cursor = GIMP_PAINTBRUSH_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_paintbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
gimp_paintbrush_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
PaintOptions *paint_options;
PaintPressureOptions *pressure_options;
PaintGradientOptions *gradient_options;
gboolean incremental;
@ -164,27 +127,14 @@ gimp_paintbrush_tool_paint (GimpPaintTool *paint_tool,
gimage = gimp_drawable_gimage (drawable);
g_return_if_fail (gimage != NULL);
if (! gimage)
return;
paint_options = (PaintOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
pressure_options = paint_options->pressure_options;
gradient_options = paint_options->gradient_options;
incremental = paint_options->incremental;
if (paint_options)
{
pressure_options = paint_options->pressure_options;
gradient_options = paint_options->gradient_options;
incremental = paint_options->incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
gradient_options = &non_gui_gradient_options;
incremental = non_gui_incremental;
}
switch (state)
switch (paint_state)
{
case INIT_PAINT:
break;
@ -224,13 +174,13 @@ gimp_paintbrush_tool_paint (GimpPaintTool *paint_tool,
break;
}
gimp_paintbrush_tool_motion (paint_tool, drawable,
pressure_options,
gradient_options,
gradient_options->use_fade ? fade_out : 0,
gradient_options->use_gradient ? gradient_length : 0,
incremental,
gradient_options->gradient_type);
gimp_paintbrush_motion (paint_core, drawable,
pressure_options,
gradient_options,
gradient_options->use_fade ? fade_out : 0,
gradient_options->use_gradient ? gradient_length : 0,
incremental,
gradient_options->gradient_type);
break;
case FINISH_PAINT:
@ -242,14 +192,14 @@ gimp_paintbrush_tool_paint (GimpPaintTool *paint_tool,
}
static void
gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
PaintGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GradientPaintMode gradient_type)
gimp_paintbrush_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
PaintGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GradientPaintMode gradient_type)
{
GimpImage *gimage;
GimpContext *context;
@ -270,7 +220,7 @@ gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
@ -278,14 +228,14 @@ gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
gradient_length = 1.0; /* not really used, only for if cases */
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
/* factor in the fade out value */
if (fade_out)
{
/* Model the amount of paint left as a gaussian curve */
x = ((double) paint_tool->pixel_dist / fade_out);
x = ((double) paint_core->pixel_dist / fade_out);
paint_left = exp (- x * x * 5.541); /* ln (1/255) */
local_blend = (int) (255 * paint_left);
}
@ -304,10 +254,10 @@ gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
if (pressure_options->color)
gimp_gradient_get_color_at (gradient,
paint_tool->cur_coords.pressure,
paint_core->cur_coords.pressure,
&color);
else
gimp_paint_tool_get_color_from_gradient (paint_tool,
gimp_paint_core_get_color_from_gradient (paint_core,
gradient,
gradient_length,
&color,
@ -330,9 +280,9 @@ gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
/* we check to see if this is a pixmap, if so composite the
* pixmap image into the area instead of the color
*/
else if (paint_tool->brush && paint_tool->brush->pixmap)
else if (paint_core->brush && paint_core->brush->pixmap)
{
gimp_paint_tool_color_area_with_pixmap (paint_tool, gimage, drawable,
gimp_paint_core_color_area_with_pixmap (paint_core, gimage, drawable,
area,
scale, SOFT);
paint_appl_mode = INCREMENTAL;
@ -348,9 +298,9 @@ gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
opacity = (gdouble) temp_blend;
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
gimp_paint_tool_paste_canvas (paint_tool, drawable,
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, 255),
gimp_context_get_opacity (context) * 255,
gimp_context_get_paint_mode (context),
@ -358,106 +308,3 @@ gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
scale, paint_appl_mode);
}
}
/* non-gui stuff */
static GimpPaintbrushTool *non_gui_paintbrush = NULL;
gboolean
gimp_paintbrush_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
GimpPaintTool *paint_tool;
gint i;
if (! non_gui_paintbrush)
{
non_gui_paintbrush = g_object_new (GIMP_TYPE_PAINTBRUSH_TOOL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_paintbrush);
/* Hmmm... PDB paintbrush should have gradient type added to it!
* thats why the code below is duplicated.
*/
if (gimp_paint_tool_start (paint_tool, drawable,
stroke_array[0],
stroke_array[1]))
{
paint_tool->start_coords.x = paint_tool->last_coords.x = stroke_array[0];
paint_tool->start_coords.y = paint_tool->last_coords.y = stroke_array[1];
gimp_paint_tool_paint (paint_tool, drawable, MOTION_PAINT);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
return TRUE;
}
return FALSE;
}
gboolean
gimp_paintbrush_tool_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array,
gdouble fade_out,
gint method,
gdouble gradient_length)
{
GimpPaintTool *paint_tool;
gint i;
if (! non_gui_paintbrush)
{
non_gui_paintbrush = g_object_new (GIMP_TYPE_PAINTBRUSH_TOOL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_paintbrush);
/* Code duplicated above */
if (gimp_paint_tool_start (paint_tool, drawable,
stroke_array[0],
stroke_array[1]))
{
non_gui_gradient_options.fade_out = fade_out;
non_gui_gradient_options.gradient_length = gradient_length;
non_gui_gradient_options.gradient_type = LOOP_TRIANGLE;
non_gui_incremental = method;
paint_tool->start_coords.x = paint_tool->last_coords.x = stroke_array[0];
paint_tool->start_coords.y = paint_tool->last_coords.y = stroke_array[1];
gimp_paint_tool_paint (paint_tool, drawable, MOTION_PAINT);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
return TRUE;
}
return FALSE;
}

View File

@ -16,50 +16,36 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_PAINTBRUSH_TOOL_H__
#define __GIMP_PAINTBRUSH_TOOL_H__
#ifndef __GIMP_PAINTBRUSH_H__
#define __GIMP_PAINTBRUSH_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
#define GIMP_TYPE_PAINTBRUSH_TOOL (gimp_paintbrush_tool_get_type ())
#define GIMP_PAINTBRUSH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINTBRUSH_TOOL, GimpPaintbrushTool))
#define GIMP_PAINTBRUSH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PAINTBRUSH_TOOL, GimpPaintbrushToolClass))
#define GIMP_IS_PAINTBRUSH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PAINTBRUSH_TOOL))
#define GIMP_IS_PAINTBRUSH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PAINTBRUSH_TOOL))
#define GIMP_PAINTBRUSH_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PAINTBRUSH_TOOL, GimpPaintbrushToolClass))
#define GIMP_TYPE_PAINTBRUSH (gimp_paintbrush_get_type ())
#define GIMP_PAINTBRUSH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINTBRUSH, GimpPaintbrush))
#define GIMP_PAINTBRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PAINTBRUSH, GimpPaintbrushClass))
#define GIMP_IS_PAINTBRUSH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PAINTBRUSH))
#define GIMP_IS_PAINTBRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PAINTBRUSH))
#define GIMP_PAINTBRUSH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PAINTBRUSH, GimpPaintbrushClass))
typedef struct _GimpPaintbrushTool GimpPaintbrushTool;
typedef struct _GimpPaintbrushToolClass GimpPaintbrushToolClass;
typedef struct _GimpPaintbrush GimpPaintbrush;
typedef struct _GimpPaintbrushClass GimpPaintbrushClass;
struct _GimpPaintbrushTool
struct _GimpPaintbrush
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
};
struct _GimpPaintbrushToolClass
struct _GimpPaintbrushClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_paintbrush_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
GType gimp_paintbrush_tool_get_type (void) G_GNUC_CONST;
GType gimp_paintbrush_get_type (void) G_GNUC_CONST;
gboolean gimp_paintbrush_tool_non_gui (GimpDrawable *drawable,
gint num_srokes,
gdouble *stroke_array,
gdouble fade_out,
gint incremental,
gdouble gradient_length);
gboolean gimp_paintbrush_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_PAINTBRUSH_TOOL_H__ */
#endif /* __GIMP_PAINTBRUSH_H__ */

View File

@ -1,16 +1,20 @@
/* paint_core_kernels.h
/* gimppaintcore-kernels.h
*
* This file was generated using kernelgen as found in the tools dir.
* (threshold = 0.25)
*/
#ifndef __GIMP_PAINT_CORE_KERNELS_H__
#define __GIMP_PAINT_CORE_KERNELS_H__
#define KERNEL_WIDTH 3
#define KERNEL_HEIGHT 3
#define KERNEL_SUBSAMPLE 4
/* Brush pixel subsampling kernels */
static const int subsample[5][5][9] = {
static const int subsample[5][5][9] =
{
{
{ 64, 64, 0, 64, 64, 0, 0, 0, 0, },
{ 25, 102, 0, 25, 102, 0, 0, 0, 0, },
@ -47,3 +51,5 @@ static const int subsample[5][5][9] = {
{ 0, 0, 0, 0, 64, 64, 0, 64, 64, }
}
};
#endif /* __GIMP_PAINT_CORE_KERNELS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -16,14 +16,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_PAINT_TOOL_H__
#define __GIMP_PAINT_TOOL_H__
#ifndef __GIMP_PAINT_CORE_H__
#define __GIMP_PAINT_CORE_H__
#include "gimpdrawtool.h"
#include "core/gimpobject.h"
#include "tools/tools-types.h" /* temp hack */
#include "tools/paint_options.h" /* temp hack */
#define PAINT_TOOL_SUBSAMPLE 4
#define PAINT_CORE_SUBSAMPLE 4
/* the different states that the painting function can be called with */
@ -37,135 +40,145 @@ typedef enum /*< pdb-skip >*/
FINISH_PAINT, /* Cleanup and/or reset PaintFunc operation */
PRETRACE_PAINT, /* PaintFunc performs window tracing activity prior to rendering */
POSTTRACE_PAINT /* PaintFunc performs window tracing activity following rendering */
} PaintState;
} GimpPaintCoreState;
typedef enum /*< pdb-skip >*/
{
TOOL_CAN_HANDLE_CHANGING_BRUSH = 0x0001, /* Set for tools that don't mind
CORE_CAN_HANDLE_CHANGING_BRUSH = 0x0001, /* Set for tools that don't mind
* if the brush changes while
* painting.
*/
TOOL_TRACES_ON_WINDOW /* Set for tools that perform temporary
CORE_TRACES_ON_WINDOW /* Set for tools that perform temporary
* rendering directly to the window. These
* require sequencing with gdisplay_flush()
* routines. See clone.c for example.
*/
} ToolFlags;
} GimpPaintCoreFlags;
#define GIMP_TYPE_PAINT_TOOL (gimp_paint_tool_get_type ())
#define GIMP_PAINT_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINT_TOOL, GimpPaintTool))
#define GIMP_PAINT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PAINT_TOOL, GimpPaintToolClass))
#define GIMP_IS_PAINT_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PAINT_TOOL))
#define GIMP_IS_PAINT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PAINT_TOOL))
#define GIMP_PAINT_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PAINT_TOOL, GimpPaintToolClass))
#define GIMP_TYPE_PAINT_CORE (gimp_paint_core_get_type ())
#define GIMP_PAINT_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINT_CORE, GimpPaintCore))
#define GIMP_PAINT_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PAINT_CORE, GimpPaintCoreClass))
#define GIMP_IS_PAINT_CORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PAINT_CORE))
#define GIMP_IS_PAINT_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PAINT_CORE))
#define GIMP_PAINT_CORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PAINT_CORE, GimpPaintCoreClass))
typedef struct _GimpPaintToolClass GimpPaintToolClass;
typedef struct _GimpPaintCoreClass GimpPaintCoreClass;
struct _GimpPaintTool
struct _GimpPaintCore
{
GimpDrawTool parent_instance;
GimpObject parent_instance;
GimpCoords start_coords; /* starting coords */
GimpCoords cur_coords; /* current coords */
GimpCoords last_coords; /* last coords */
gint ID; /* unique instance ID */
gint state; /* state of buttons and keys */
GimpCoords start_coords; /* starting coords */
GimpCoords cur_coords; /* current coords */
GimpCoords last_coords; /* last coords */
gdouble distance; /* distance traveled by brush */
gdouble pixel_dist; /* distance in pixels */
gdouble spacing; /* spacing */
gdouble distance; /* distance traveled by brush */
gdouble pixel_dist; /* distance in pixels */
gdouble spacing; /* spacing */
gint x1, y1; /* image space coordinate */
gint x2, y2; /* image space coords */
gint x1, y1; /* image space coords */
gint x2, y2; /* image space coords */
GimpBrush *brush; /* current brush */
GimpBrush *brush; /* current brush */
gboolean pick_colors; /* pick color if ctrl or alt is pressed */
gboolean pick_state; /* was ctrl or alt pressed when clicked? */
ToolFlags flags; /* tool flags, see ToolFlags above */
GimpPaintCoreFlags flags; /* tool flags, see ToolFlags above */
/* undo blocks variables */
TileManager *undo_tiles;
TileManager *canvas_tiles;
TileManager *undo_tiles;
TileManager *canvas_tiles;
/* paint buffers variables */
TempBuf *orig_buf;
TempBuf *canvas_buf;
TempBuf *orig_buf;
TempBuf *canvas_buf;
/* brush buffers */
MaskBuf *pressure_brush;
MaskBuf *solid_brush;
MaskBuf *scale_brush;
MaskBuf *scale_pixmap;
MaskBuf *kernel_brushes[PAINT_TOOL_SUBSAMPLE + 1][PAINT_TOOL_SUBSAMPLE + 1];
MaskBuf *pressure_brush;
MaskBuf *last_brush_mask;
gboolean cache_invalid;
MaskBuf *solid_brush;
MaskBuf *last_solid_brush;
MaskBuf *scale_brush;
MaskBuf *last_scale_brush;
gint last_scale_width;
gint last_scale_height;
MaskBuf *scale_pixmap;
MaskBuf *last_scale_pixmap;
gint last_scale_pixmap_width;
gint last_scale_pixmap_height;
MaskBuf *kernel_brushes[PAINT_CORE_SUBSAMPLE + 1][PAINT_CORE_SUBSAMPLE + 1];
MaskBuf *last_brush_mask;
gboolean cache_invalid;
/* don't use this one... */
GimpBrush *grr_brush;
GimpBrush *grr_brush;
};
struct _GimpPaintToolClass
struct _GimpPaintCoreClass
{
GimpDrawToolClass parent_class;
GimpObjectClass parent_class;
/* virtual function */
void (* paint) (GimpPaintTool *tool,
GimpDrawable *drawable,
PaintState paint_state);
void (* paint) (GimpPaintCore *core,
GimpDrawable *drawable,
PaintOptions *options,
GimpPaintCoreState paint_state);
};
/* Special undo type */
typedef struct _PaintUndo PaintUndo;
typedef struct _GimpPaintCoreUndo GimpPaintCoreUndo;
struct _PaintUndo
struct _GimpPaintCoreUndo
{
gint tool_ID;
GType tool_type;
gint core_ID;
GType core_type;
GimpCoords last_coords;
};
GType gimp_paint_tool_get_type (void) G_GNUC_CONST;
GType gimp_paint_core_get_type (void) G_GNUC_CONST;
void gimp_paint_tool_paint (GimpPaintTool *paint_tool,
void gimp_paint_core_paint (GimpPaintCore *core,
GimpDrawable *drawable,
PaintState state);
PaintOptions *options,
GimpPaintCoreState state);
int gimp_paint_tool_start (GimpPaintTool *paint_tool,
int gimp_paint_core_start (GimpPaintCore *core,
GimpDrawable *drawable,
gdouble x,
gdouble y);
void gimp_paint_tool_interpolate (GimpPaintTool *paint_tool,
GimpCoords *coords);
void gimp_paint_core_interpolate (GimpPaintCore *core,
GimpDrawable *drawable,
PaintOptions *paint_options);
void gimp_paint_core_finish (GimpPaintCore *core,
GimpDrawable *drawable);
void gimp_paint_tool_finish (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
void gimp_paint_tool_cleanup (GimpPaintTool *paint_tool);
void gimp_paint_core_cleanup (GimpPaintCore *core);
void gimp_paint_tool_get_color_from_gradient (GimpPaintTool *paint_tool,
void gimp_paint_core_get_color_from_gradient (GimpPaintCore *core,
GimpGradient *gradient,
gdouble gradient_length,
GimpRGB *color,
GradientPaintMode mode);
/* paint tool painting functions */
TempBuf * gimp_paint_tool_get_paint_area (GimpPaintTool *paint_tool,
/* paint core painting functions */
TempBuf * gimp_paint_core_get_paint_area (GimpPaintCore *core,
GimpDrawable *drawable,
gdouble scale);
TempBuf * gimp_paint_tool_get_orig_image (GimpPaintTool *paint_tool,
TempBuf * gimp_paint_core_get_orig_image (GimpPaintCore *core,
GimpDrawable *drawable,
gint x1,
gint y1,
gint x2,
gint y2);
void gimp_paint_tool_paste_canvas (GimpPaintTool *paint_tool,
void gimp_paint_core_paste_canvas (GimpPaintCore *core,
GimpDrawable *drawable,
gint brush_opacity,
gint image_opacity,
@ -173,14 +186,14 @@ void gimp_paint_tool_paste_canvas (GimpPaintTool *paint_too
BrushApplicationMode brush_hardness,
gdouble brush_scale,
PaintApplicationMode mode);
void gimp_paint_tool_replace_canvas (GimpPaintTool *paint_tool,
void gimp_paint_core_replace_canvas (GimpPaintCore *core,
GimpDrawable *drawable,
gint brush_opacity,
gint image_opacity,
BrushApplicationMode brush_hardness,
gdouble brush_scale,
PaintApplicationMode mode);
void gimp_paint_tool_color_area_with_pixmap (GimpPaintTool *paint_tool,
void gimp_paint_core_color_area_with_pixmap (GimpPaintCore *core,
GimpImage *dest,
GimpDrawable *drawable,
TempBuf *area,
@ -188,4 +201,4 @@ void gimp_paint_tool_color_area_with_pixmap (GimpPaintTool *paint_too
BrushApplicationMode mode);
#endif /* __GIMP_PAINT_TOOL_H__ */
#endif /* __GIMP_PAINT_CORE_H__ */

View File

@ -21,9 +21,8 @@
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/temp-buf.h"
@ -35,138 +34,89 @@
#include "core/gimpdrawable.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "gimppenciltool.h"
#include "paint_options.h"
#include "libgimp/gimpintl.h"
#include "gimppencil.h"
#define PENCIL_INCREMENTAL_DEFAULT FALSE
static void gimp_pencil_class_init (GimpPencilClass *klass);
static void gimp_pencil_init (GimpPencil *pencil);
static void gimp_pencil_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_pencil_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options);
static void gimp_pencil_tool_class_init (GimpPencilToolClass *klass);
static void gimp_pencil_tool_init (GimpPencilTool *pancil);
static GimpPaintCoreClass *parent_class = NULL;
static void gimp_pencil_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_pencil_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean incremental);
/* private variables */
static gboolean non_gui_incremental = PENCIL_INCREMENTAL_DEFAULT;
static GimpPaintToolClass *parent_class = NULL;
/* functions */
void
gimp_pencil_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_PENCIL_TOOL,
paint_options_new,
TRUE,
"gimp:pencil_tool",
_("Pencil"),
_("Paint hard edged pixels"),
N_("/Tools/Paint Tools/Pencil"), "P",
NULL, "tools/pencil.html",
GIMP_STOCK_TOOL_PENCIL);
}
GType
gimp_pencil_tool_get_type (void)
gimp_pencil_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpPencilToolClass),
sizeof (GimpPencilClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_pencil_tool_class_init,
(GClassInitFunc) gimp_pencil_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpPencilTool),
sizeof (GimpPencil),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_pencil_tool_init,
(GInstanceInitFunc) gimp_pencil_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpPencilTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpPencilCore",
&info, 0);
}
return tool_type;
return type;
}
static void
gimp_pencil_tool_class_init (GimpPencilToolClass *klass)
gimp_pencil_class_init (GimpPencilClass *klass)
{
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
paint_tool_class->paint = gimp_pencil_tool_paint;
paint_core_class->paint = gimp_pencil_paint;
}
static void
gimp_pencil_tool_init (GimpPencilTool *pencil)
gimp_pencil_init (GimpPencil *pencil)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (pencil);
paint_tool = GIMP_PAINT_TOOL (pencil);
paint_core = GIMP_PAINT_CORE (pencil);
tool->tool_cursor = GIMP_PENCIL_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_pencil_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
gimp_pencil_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
PaintOptions *paint_options;
PaintPressureOptions *pressure_options;
gboolean incremental;
paint_options = (PaintOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (paint_options)
{
pressure_options = paint_options->pressure_options;
incremental = paint_options->incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
incremental = non_gui_incremental;
}
switch (state)
switch (paint_state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
gimp_pencil_tool_motion (paint_tool, drawable,
pressure_options, incremental);
gimp_pencil_motion (paint_core, drawable, paint_options);
break;
case FINISH_PAINT:
@ -178,10 +128,9 @@ gimp_pencil_tool_paint (GimpPaintTool *paint_tool,
}
static void
gimp_pencil_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean incremental)
gimp_pencil_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options)
{
GimpImage *gimage;
GimpContext *context;
@ -189,29 +138,32 @@ gimp_pencil_tool_motion (GimpPaintTool *paint_tool,
guchar col[MAX_CHANNELS];
gint opacity;
gdouble scale;
PaintApplicationMode paint_appl_mode = incremental ? INCREMENTAL : CONSTANT;
PaintApplicationMode paint_appl_mode;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
paint_appl_mode = paint_options->incremental ? INCREMENTAL : CONSTANT;
if (paint_options->pressure_options->size)
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
/* color the pixels */
if (pressure_options->color)
if (paint_options->pressure_options->color)
{
GimpRGB color;
gimp_gradient_get_color_at (gimp_context_get_gradient (context),
paint_tool->cur_coords.pressure, &color);
paint_core->cur_coords.pressure,
&color);
gimp_rgba_get_uchar (&color,
&col[RED_PIX],
@ -221,13 +173,15 @@ gimp_pencil_tool_motion (GimpPaintTool *paint_tool,
paint_appl_mode = INCREMENTAL;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
area->width * area->height,
area->bytes);
}
else if (paint_tool->brush && paint_tool->brush->pixmap)
else if (paint_core->brush && paint_core->brush->pixmap)
{
/* if its a pixmap, do pixmap stuff */
gimp_paint_tool_color_area_with_pixmap (paint_tool, gimage, drawable,
area, scale, HARD);
gimp_paint_core_color_area_with_pixmap (paint_core,
gimage, drawable,
area, scale, HARD);
paint_appl_mode = INCREMENTAL;
}
else
@ -235,65 +189,19 @@ gimp_pencil_tool_motion (GimpPaintTool *paint_tool,
gimp_image_get_foreground (gimage, drawable, col);
col[area->bytes - 1] = OPAQUE_OPACITY;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
area->width * area->height,
area->bytes);
}
opacity = 255 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
if (paint_options->pressure_options->opacity)
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, 255),
gimp_context_get_opacity (context) * 255,
gimp_context_get_paint_mode (context),
HARD, scale, paint_appl_mode);
}
/* non-gui stuff */
gboolean
pencil_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
static GimpPencilTool *non_gui_pencil = NULL;
GimpPaintTool *paint_tool;
gint i;
if (! non_gui_pencil)
{
non_gui_pencil = g_object_new (GIMP_TYPE_PENCIL_TOOL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_pencil);
if (gimp_paint_tool_start (paint_tool, drawable,
stroke_array[0],
stroke_array[1]))
{
paint_tool->start_coords.x = paint_tool->last_coords.x = stroke_array[0];
paint_tool->start_coords.y = paint_tool->last_coords.y = stroke_array[1];
gimp_pencil_tool_paint (paint_tool, drawable, MOTION_PAINT);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
return TRUE;
}
return FALSE;
}

View File

@ -16,51 +16,39 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_PENCIL_TOOL_H__
#define __GIMP_PENCIL_TOOL_H__
#ifndef __GIMP_PENCIL_H__
#define __GIMP_PENCIL_H__
/* FIXME: This whole tool should probably just be a paintbrush tool that
* has an option of hard edge. It'll give the "pencil tool" all the
* flashy stuff the paintbrush tool has, and not duplicate code.
/* FIXME: This whole core should probably just be a paintbrush core that
* has an option of hard edge. It'll give the "pencil core" all the
* flashy stuff the paintbrush core has, and not duplicate code.
*/
#include "gimppainttool.h"
#include "gimppaintcore.h"
#define GIMP_TYPE_PENCIL_TOOL (gimp_pencil_tool_get_type ())
#define GIMP_PENCIL_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PENCIL_TOOL, GimpPencilTool))
#define GIMP_PENCIL_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PENCIL_TOOL, GimpPencilToolClass))
#define GIMP_IS_PENCIL_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PENCIL_TOOL))
#define GIMP_IS_PENCIL_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PENCIL_TOOL))
#define GIMP_PENCIL_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PENCIL_TOOL, GimpPencilToolClass))
#define GIMP_TYPE_PENCIL (gimp_pencil_get_type ())
#define GIMP_PENCIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PENCIL, GimpPencil))
#define GIMP_PENCIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PENCIL, GimpPencilClass))
#define GIMP_IS_PENCIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PENCIL))
#define GIMP_IS_PENCIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PENCIL))
#define GIMP_PENCIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PENCIL, GimpPencilClass))
typedef struct _GimpPencilTool GimpPencilTool;
typedef struct _GimpPencilToolClass GimpPencilToolClass;
typedef struct _GimpPencil GimpPencil;
typedef struct _GimpPencilClass GimpPencilClass;
struct _GimpPencilTool
struct _GimpPencil
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
};
struct _GimpPencilToolClass
struct _GimpPencilClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_pencil_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
GType gimp_pencil_tool_get_type (void) G_GNUC_CONST;
GType gimp_pencil_get_type (void) G_GNUC_CONST;
/* FIXME: Get rid of this non_gui stuff someday. Preferably make
* everything use it interally for ease of macro recording.
*/
gboolean pencil_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_PENCIL_TOOL_H__ */
#endif /* __GIMP_PENCIL_H__ */

View File

@ -19,12 +19,10 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
@ -36,171 +34,122 @@
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "gimpsmudgetool.h"
#include "paint_options.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
#include "gimpsmudge.h"
/* default defines */
static void gimp_smudge_class_init (GimpSmudgeClass *klass);
static void gimp_smudge_init (GimpSmudge *smudge);
#define SMUDGE_DEFAULT_RATE 50.0
static void gimp_smudge_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
/* the smudge structures */
static gboolean gimp_smudge_start (GimpPaintCore *paint_core,
GimpDrawable *drawable);
static void gimp_smudge_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble smudge_rate);
static void gimp_smudge_finish (GimpPaintCore *paint_core,
GimpDrawable *drawable);
typedef struct _SmudgeOptions SmudgeOptions;
struct _SmudgeOptions
{
PaintOptions paint_options;
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
};
static void gimp_smudge_nonclipped_painthit_coords (GimpPaintCore *paint_core,
gint *x,
gint *y,
gint *w,
gint *h);
static void gimp_smudge_allocate_accum_buffer (gint w,
gint h,
gint bytes,
guchar *do_fill);
/* function prototypes */
static void gimp_smudge_tool_class_init (GimpSmudgeToolClass *klass);
static void gimp_smudge_tool_init (GimpSmudgeTool *tool);
static void gimp_smudge_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_smudge_tool_motion (GimpPaintTool *paint_tool,
PaintPressureOptions *pressure_options,
gdouble smudge_rate,
GimpDrawable *drawable);
static gboolean gimp_smudge_tool_start (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
static void gimp_smudge_tool_finish (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
static void gimp_smudge_tool_nonclipped_painthit_coords (GimpPaintTool *paint_tool,
gint *x,
gint *y,
gint *w,
gint *h);
static void gimp_smudge_tool_allocate_accum_buffer (gint w,
gint h,
gint bytes,
guchar *do_fill);
static GimpToolOptions * smudge_options_new (GimpToolInfo *tool_info);
static void smudge_options_reset (GimpToolOptions *tool_options);
/* local variables */
static PixelRegion accumPR;
static guchar *accum_data = NULL;
static gdouble non_gui_rate;
static GimpPaintCoreClass *parent_class = NULL;
static GimpPaintToolClass *parent_class = NULL;
/* global functions */
void
gimp_smudge_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_SMUDGE_TOOL,
smudge_options_new,
TRUE,
"gimp:smudge_tool",
_("Smudge"),
_("Smudge image"),
N_("/Tools/Paint Tools/Smudge"), "S",
NULL, "tools/smudge.html",
GIMP_STOCK_TOOL_SMUDGE);
}
GType
gimp_smudge_tool_get_type (void)
gimp_smudge_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpSmudgeToolClass),
sizeof (GimpSmudgeClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_smudge_tool_class_init,
(GClassInitFunc) gimp_smudge_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpSmudgeTool),
sizeof (GimpSmudge),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_smudge_tool_init,
(GInstanceInitFunc) gimp_smudge_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpSmudgeTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpSmudge",
&info, 0);
}
return tool_type;
return type;
}
static void
gimp_smudge_tool_class_init (GimpSmudgeToolClass *klass)
gimp_smudge_class_init (GimpSmudgeClass *klass)
{
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
paint_tool_class->paint = gimp_smudge_tool_paint;
paint_core_class->paint = gimp_smudge_paint;
}
static void
gimp_smudge_tool_init (GimpSmudgeTool *smudge)
gimp_smudge_init (GimpSmudge *smudge)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (smudge);
paint_tool = GIMP_PAINT_TOOL (smudge);
paint_core = GIMP_PAINT_CORE (smudge);
tool->tool_cursor = GIMP_SMUDGE_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_smudge_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
gimp_smudge_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
SmudgeOptions *options;
/* initialization fails if the user starts outside the drawable */
static gboolean initialized = FALSE;
options = (SmudgeOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
options = (SmudgeOptions *) paint_options;
switch (state)
switch (paint_state)
{
case MOTION_PAINT:
if (! initialized)
initialized = gimp_smudge_tool_start (paint_tool, drawable);
initialized = gimp_smudge_start (paint_core, drawable);
if (initialized)
gimp_smudge_tool_motion (paint_tool,
options->paint_options.pressure_options,
options->rate,
drawable);
gimp_smudge_motion (paint_core,
drawable,
paint_options->pressure_options,
options->rate);
break;
case FINISH_PAINT:
gimp_smudge_tool_finish (paint_tool, drawable);
gimp_smudge_finish (paint_core, drawable);
initialized = FALSE;
break;
@ -211,33 +160,8 @@ gimp_smudge_tool_paint (GimpPaintTool *paint_tool,
return;
}
static void
gimp_smudge_tool_finish (GimpPaintTool *paint_tool,
GimpDrawable *drawable)
{
if (accum_data)
{
g_free (accum_data);
accum_data = NULL;
}
}
static void
gimp_smudge_tool_nonclipped_painthit_coords (GimpPaintTool *paint_tool,
gint *x,
gint *y,
gint *w,
gint *h)
{
/* Note: these are the brush mask size plus a border of 1 pixel */
*x = (gint) paint_tool->cur_coords.x - paint_tool->brush->mask->width/2 - 1;
*y = (gint) paint_tool->cur_coords.y - paint_tool->brush->mask->height/2 - 1;
*w = paint_tool->brush->mask->width + 2;
*h = paint_tool->brush->mask->height + 2;
}
static gboolean
gimp_smudge_tool_start (GimpPaintTool *paint_tool,
gimp_smudge_start (GimpPaintCore *paint_core,
GimpDrawable *drawable)
{
GimpImage *gimage;
@ -254,13 +178,13 @@ gimp_smudge_tool_start (GimpPaintTool *paint_tool,
if (gimp_drawable_is_indexed (drawable))
return FALSE;
area = gimp_paint_tool_get_paint_area (paint_tool, drawable, 1.0);
area = gimp_paint_core_get_paint_area (paint_core, drawable, 1.0);
if (!area)
return FALSE;
/* adjust the x and y coordinates to the upper left corner of the brush */
gimp_smudge_tool_nonclipped_painthit_coords (paint_tool, &x, &y, &w, &h);
gimp_smudge_nonclipped_painthit_coords (paint_core, &x, &y, &w, &h);
if (x != area->x || y != area->y || w != area->width || h != area->height)
was_clipped = TRUE;
@ -278,12 +202,12 @@ gimp_smudge_tool_start (GimpPaintTool *paint_tool,
if (was_clipped)
do_fill = gimp_drawable_get_color_at (drawable,
CLAMP ((gint) paint_tool->cur_coords.x,
CLAMP ((gint) paint_core->cur_coords.x,
0, gimp_drawable_width (drawable) - 1),
CLAMP ((gint) paint_tool->cur_coords.y,
CLAMP ((gint) paint_core->cur_coords.y,
0, gimp_drawable_height (drawable) - 1));
gimp_smudge_tool_allocate_accum_buffer (w, h,
gimp_smudge_allocate_accum_buffer (w, h,
gimp_drawable_bytes (drawable),
do_fill);
@ -318,33 +242,10 @@ gimp_smudge_tool_start (GimpPaintTool *paint_tool,
}
static void
gimp_smudge_tool_allocate_accum_buffer (gint w,
gint h,
gint bytes,
guchar *do_fill)
{
/* Allocate the accumulation buffer */
accumPR.bytes = bytes;
accum_data = g_malloc (w * h * bytes);
if (do_fill != NULL)
{
/* guchar color[3] = {0,0,0}; */
accumPR.x = 0;
accumPR.y = 0;
accumPR.w = w;
accumPR.h = h;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data;
color_region (&accumPR, (const guchar*)do_fill);
}
}
static void
gimp_smudge_tool_motion (GimpPaintTool *paint_tool,
PaintPressureOptions *pressure_options,
gdouble smudge_rate,
GimpDrawable *drawable)
gimp_smudge_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble smudge_rate)
{
GimpImage *gimage;
GimpContext *context;
@ -363,11 +264,11 @@ gimp_smudge_tool_motion (GimpPaintTool *paint_tool,
if (gimp_drawable_is_indexed (drawable))
return;
gimp_smudge_tool_nonclipped_painthit_coords (paint_tool, &x, &y, &w, &h);
gimp_smudge_nonclipped_painthit_coords (paint_core, &x, &y, &w, &h);
/* Get the paint area */
/* Smudge won't scale! */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, 1.0)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, 1.0)))
return;
/* srcPR will be the pixels under the current painthit from
@ -378,7 +279,7 @@ gimp_smudge_tool_motion (GimpPaintTool *paint_tool,
/* Enable pressure sensitive rate */
if (pressure_options->rate)
rate = MIN (smudge_rate / 100.0 * paint_tool->cur_coords.pressure * 2.0, 1.0);
rate = MIN (smudge_rate / 100.0 * paint_core->cur_coords.pressure * 2.0, 1.0);
else
rate = smudge_rate / 100.0;
@ -431,144 +332,60 @@ gimp_smudge_tool_motion (GimpPaintTool *paint_tool,
opacity = 255 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/*Replace the newly made paint area to the gimage*/
gimp_paint_tool_replace_canvas (paint_tool, drawable,
gimp_paint_core_replace_canvas (paint_core, drawable,
MIN (opacity, 255),
OPAQUE_OPACITY,
pressure_options->pressure ? PRESSURE : SOFT,
1.0, INCREMENTAL);
}
static GimpSmudgeTool *non_gui_smudge = NULL;
gboolean
gimp_smudge_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
static void
gimp_smudge_finish (GimpPaintCore *paint_core,
GimpDrawable *drawable)
{
GimpToolInfo *tool_info;
SmudgeOptions *options;
gdouble rate = SMUDGE_DEFAULT_RATE;
tool_info = tool_manager_get_info_by_type (drawable->gimage->gimp,
GIMP_TYPE_SMUDGE_TOOL);
options = (SmudgeOptions *) tool_info->tool_options;
if (options)
rate = options->rate;
return gimp_smudge_tool_non_gui (drawable, rate, num_strokes, stroke_array);
if (accum_data)
{
g_free (accum_data);
accum_data = NULL;
}
}
gboolean
gimp_smudge_tool_non_gui (GimpDrawable *drawable,
gdouble rate,
gint num_strokes,
gdouble *stroke_array)
static void
gimp_smudge_nonclipped_painthit_coords (GimpPaintCore *paint_core,
gint *x,
gint *y,
gint *w,
gint *h)
{
GimpPaintTool *paint_tool;
gint i;
if (! non_gui_smudge)
{
non_gui_smudge = g_object_new (GIMP_TYPE_SMUDGE_TOOL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_smudge);
if (gimp_paint_tool_start (paint_tool, drawable,
stroke_array[0], stroke_array[1]))
{
gimp_smudge_tool_start (paint_tool, drawable);
non_gui_rate = rate;
paint_tool->cur_coords.x = paint_tool->start_coords.x =
paint_tool->last_coords.x = stroke_array[0];
paint_tool->cur_coords.y = paint_tool->start_coords.y =
paint_tool->last_coords.y = stroke_array[1];
gimp_smudge_tool_paint (paint_tool, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
gimp_paint_tool_cleanup (paint_tool);
gimp_smudge_tool_finish (paint_tool, drawable);
return TRUE;
}
return FALSE;
}
static GimpToolOptions *
smudge_options_new (GimpToolInfo *tool_info)
{
SmudgeOptions *options;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *scale;
options = g_new0 (SmudgeOptions, 1);
paint_options_init ((PaintOptions *) options, tool_info);
((GimpToolOptions *) options)->reset_func = smudge_options_reset;
options->rate = options->rate_d = SMUDGE_DEFAULT_RATE;
/* the main vbox */
vbox = ((GimpToolOptions *) options)->main_vbox;
/* the rate scale */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new (_("Rate:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
options->rate_w =
gtk_adjustment_new (options->rate_d, 0.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->rate_w));
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
g_signal_connect (G_OBJECT (options->rate_w), "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&options->rate);
gtk_widget_show (scale);
gtk_widget_show (hbox);
return (GimpToolOptions *) options;
/* Note: these are the brush mask size plus a border of 1 pixel */
*x = (gint) paint_core->cur_coords.x - paint_core->brush->mask->width/2 - 1;
*y = (gint) paint_core->cur_coords.y - paint_core->brush->mask->height/2 - 1;
*w = paint_core->brush->mask->width + 2;
*h = paint_core->brush->mask->height + 2;
}
static void
smudge_options_reset (GimpToolOptions *tool_options)
gimp_smudge_allocate_accum_buffer (gint w,
gint h,
gint bytes,
guchar *do_fill)
{
SmudgeOptions *options;
options = (SmudgeOptions *) tool_options;
paint_options_reset (tool_options);
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->rate_w), options->rate_d);
/* Allocate the accumulation buffer */
accumPR.bytes = bytes;
accum_data = g_malloc (w * h * bytes);
if (do_fill != NULL)
{
/* guchar color[3] = {0,0,0}; */
accumPR.x = 0;
accumPR.y = 0;
accumPR.w = w;
accumPR.h = h;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data;
color_region (&accumPR, (const guchar*)do_fill);
}
}

View File

@ -16,56 +16,48 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_SMUDGE_TOOL_H__
#define __GIMP_SMUDGE_TOOL_H__
#ifndef __GIMP_SMUDGE_H__
#define __GIMP_SMUDGE_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
typedef enum
#define GIMP_TYPE_SMUDGE (gimp_smudge_get_type ())
#define GIMP_SMUDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SMUDGE, GimpSmudge))
#define GIMP_SMUDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SMUDGE, GimpSmudgeClass))
#define GIMP_IS_SMUDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SMUDGE))
#define GIMP_IS_SMUDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SMUDGE))
#define GIMP_SMUDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SMUDGE, GimpSmudgeClass))
typedef struct _GimpSmudge GimpSmudge;
typedef struct _GimpSmudgeClass GimpSmudgeClass;
struct _GimpSmudge
{
SMUDGE_TYPE_SMUDGE,
SMUDGE_TYPE_STREAK
} SmudgeType;
#define GIMP_TYPE_SMUDGE_TOOL (gimp_smudge_tool_get_type ())
#define GIMP_SMUDGE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SMUDGE_TOOL, GimpSmudgeTool))
#define GIMP_SMUDGE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SMUDGE_TOOL, GimpSmudgeToolClass))
#define GIMP_IS_SMUDGE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SMUDGE_TOOL))
#define GIMP_IS_SMUDGE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SMUDGE_TOOL))
#define GIMP_SMUDGE_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SMUDGE_TOOL, GimpSmudgeToolClass))
typedef struct _GimpSmudgeTool GimpSmudgeTool;
typedef struct _GimpSmudgeToolClass GimpSmudgeToolClass;
struct _GimpSmudgeTool
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
};
struct _GimpSmudgeToolClass
struct _GimpSmudgeClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_smudge_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
typedef struct _SmudgeOptions SmudgeOptions;
GType gimp_smudge_tool_get_type (void) G_GNUC_CONST;
struct _SmudgeOptions
{
PaintOptions paint_options;
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
};
/* FIXME: this antique code doesn't follow the coding style */
gboolean gimp_smudge_tool_non_gui (GimpDrawable *drawable,
gdouble rate,
gint num_strokes,
gdouble *stroke_array);
gboolean gimp_smudge_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
GType gimp_smudge_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_SMUDGE_TOOL_H__ */
#endif /* __GIMP_SMUDGE_H__ */

View File

@ -23,9 +23,7 @@
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint-types.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
@ -39,270 +37,167 @@
#include "core/gimpimage.h"
#include "core/gimpimage-mask.h"
#include "core/gimppattern.h"
#include "core/gimptoolinfo.h"
#include "display/gimpdisplay.h"
#include "gimpclonetool.h"
#include "paint_options.h"
#include "gimpclone.h"
#include "libgimp/gimpintl.h"
#define TARGET_WIDTH 15
#define TARGET_HEIGHT 15
static void gimp_clone_class_init (GimpCloneClass *klass);
static void gimp_clone_init (GimpClone *clone);
/* default types */
#define CLONE_DEFAULT_TYPE IMAGE_CLONE
#define CLONE_DEFAULT_ALIGNED ALIGN_NO
static void gimp_clone_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state);
static void gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y);
static void gimp_clone_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width);
static void gimp_clone_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width);
/* the clone structures */
typedef enum
{
ALIGN_NO,
ALIGN_YES,
ALIGN_REGISTERED
} AlignType;
typedef struct _CloneOptions CloneOptions;
struct _CloneOptions
{
PaintOptions paint_options;
CloneType type;
CloneType type_d;
GtkWidget *type_w[2]; /* 2 radio buttons */
AlignType aligned;
AlignType aligned_d;
GtkWidget *aligned_w[3]; /* 3 radio buttons */
};
static void gimp_clone_set_src_drawable (GimpClone *clone,
GimpDrawable *drawable);
/* forward function declarations */
static gint dest_x = 0; /* */
static gint dest_y = 0; /* position of clone src */
static gint offset_x = 0; /* */
static gint offset_y = 0; /* offset for cloning */
static gint first = TRUE;
static void gimp_clone_tool_class_init (GimpCloneToolClass *klass);
static void gimp_clone_tool_init (GimpCloneTool *tool);
static GimpPaintCoreClass *parent_class = NULL;
static void gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_clone_tool_draw (GimpDrawTool *draw_tool);
static void gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y);
static void gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width);
static void gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width);
static GimpToolOptions * clone_options_new (GimpToolInfo *tool_info);
static void clone_options_reset (GimpToolOptions *options);
/* local variables */
static gint src_x = 0; /* */
static gint src_y = 0; /* position of clone src */
static gint dest_x = 0; /* */
static gint dest_y = 0; /* position of clone src */
static gint offset_x = 0; /* */
static gint offset_y = 0; /* offset for cloning */
static gint first = TRUE;
static GimpDrawable *the_src_drawable = NULL; /* source drawable */
static GimpDrawable *non_gui_src_drawable;
static gint non_gui_offset_x;
static gint non_gui_offset_y;
static CloneType non_gui_type;
static GimpPaintToolClass *parent_class;
/* public functions */
void
gimp_clone_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
{
(* callback) (gimp,
GIMP_TYPE_CLONE_TOOL,
clone_options_new,
TRUE,
"gimp:clone_tool",
_("Clone"),
_("Paint using Patterns or Image Regions"),
N_("/Tools/Paint Tools/Clone"), "C",
NULL, "tools/clone.html",
GIMP_STOCK_TOOL_CLONE);
}
GType
gimp_clone_tool_get_type (void)
gimp_clone_get_type (void)
{
static GType tool_type = 0;
static GType type = 0;
if (! tool_type)
if (! type)
{
static const GTypeInfo tool_info =
static const GTypeInfo info =
{
sizeof (GimpCloneToolClass),
sizeof (GimpCloneClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_clone_tool_class_init,
(GClassInitFunc) gimp_clone_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpCloneTool),
sizeof (GimpClone),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_clone_tool_init,
(GInstanceInitFunc) gimp_clone_init,
};
tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
"GimpCloneTool",
&tool_info, 0);
type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
"GimpClone",
&info, 0);
}
return tool_type;
return type;
}
/* static functions */
static void
gimp_clone_tool_class_init (GimpCloneToolClass *klass)
gimp_clone_class_init (GimpCloneClass *klass)
{
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
GimpPaintToolClass *paint_tool_class;
GimpPaintCoreClass *paint_core_class;
tool_class = GIMP_TOOL_CLASS (klass);
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->cursor_update = gimp_clone_tool_cursor_update;
draw_tool_class->draw = gimp_clone_tool_draw;
paint_tool_class->paint = gimp_clone_tool_paint;
paint_core_class->paint = gimp_clone_paint;
}
static void
gimp_clone_tool_init (GimpCloneTool *clone)
gimp_clone_init (GimpClone *clone)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpPaintCore *paint_core;
tool = GIMP_TOOL (clone);
paint_tool = GIMP_PAINT_TOOL (clone);
paint_core = GIMP_PAINT_CORE (clone);
tool->tool_cursor = GIMP_CLONE_TOOL_CURSOR;
paint_core->flags |= CORE_CAN_HANDLE_CHANGING_BRUSH;
paint_core->flags |= CORE_TRACES_ON_WINDOW;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_tool->flags |= TOOL_TRACES_ON_WINDOW;
clone->set_source = FALSE;
clone->src_drawable = NULL;
clone->src_x = 0.0;
clone->src_y = 0.0;
clone->init_callback = NULL;
clone->finish_callback = NULL;
clone->pretrace_callback = NULL;
clone->posttrace_callback = NULL;
clone->callback_data = NULL;
}
static void
clone_src_drawable_disconnect_cb (GimpDrawable *drawable,
GimpDrawable **src_drawable)
gimp_clone_paint (GimpPaintCore *paint_core,
GimpDrawable *drawable,
PaintOptions *paint_options,
GimpPaintCoreState paint_state)
{
if (drawable == *src_drawable)
{
*src_drawable = NULL;
}
}
static void
clone_set_src_drawable (GimpDrawable *drawable)
{
if (the_src_drawable == drawable)
return;
if (the_src_drawable)
g_signal_handlers_disconnect_by_func (G_OBJECT (the_src_drawable),
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
the_src_drawable = drawable;
if (the_src_drawable)
{
g_signal_connect (G_OBJECT (the_src_drawable), "disconnect",
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
}
}
static void
gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
GimpTool *tool;
GimpDrawTool *draw_tool;
CloneOptions *options;
GimpContext *context;
static gint orig_src_x = 0;
static gint orig_src_y = 0;
tool = GIMP_TOOL (paint_tool);
draw_tool = GIMP_DRAW_TOOL (paint_tool);
GimpClone *clone;
CloneOptions *options;
GimpContext *context;
options = (CloneOptions *) tool->tool_info->tool_options;
clone = GIMP_CLONE (paint_core);
context = gimp_get_current_context (tool->gdisp->gimage->gimp);
options = (CloneOptions *) paint_options;
switch (state)
context = gimp_get_current_context (drawable->gimage->gimp);
switch (paint_state)
{
case PRETRACE_PAINT:
gimp_draw_tool_pause (draw_tool);
if (clone->pretrace_callback)
clone->pretrace_callback (clone, clone->callback_data);
break;
case POSTTRACE_PAINT:
gimp_draw_tool_resume (draw_tool);
if (clone->posttrace_callback)
clone->posttrace_callback (clone, clone->callback_data);
break;
case MOTION_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
if (clone->set_source)
{
/* If the control key is down, move the src target and return */
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
first = TRUE;
}
else
{
/* otherwise, update the target */
dest_x = paint_tool->cur_coords.x;
dest_y = paint_tool->cur_coords.y;
dest_x = paint_core->cur_coords.x;
dest_y = paint_core->cur_coords.y;
if (options->aligned == ALIGN_REGISTERED)
{
@ -311,37 +206,40 @@ gimp_clone_tool_paint (GimpPaintTool *paint_tool,
}
else if (first)
{
offset_x = src_x - dest_x;
offset_y = src_y - dest_y;
offset_x = clone->src_x - dest_x;
offset_y = clone->src_y - dest_y;
first = FALSE;
}
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
clone->src_x = dest_x + offset_x;
clone->src_y = dest_y + offset_y;
gimp_clone_tool_motion (paint_tool, drawable, the_src_drawable,
options->paint_options.pressure_options,
options->type,
offset_x, offset_y);
gimp_clone_motion (paint_core, drawable,
clone->src_drawable,
options->paint_options.pressure_options,
options->type,
offset_x, offset_y);
}
break;
case INIT_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
if (clone->set_source)
{
clone_set_src_drawable (drawable);
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
gimp_clone_set_src_drawable (clone, drawable);
clone->src_x = paint_core->cur_coords.x;
clone->src_y = paint_core->cur_coords.y;
first = TRUE;
}
else if (options->aligned == ALIGN_NO)
{
first = TRUE;
orig_src_x = src_x;
orig_src_y = src_y;
orig_src_x = clone->src_x;
orig_src_y = clone->src_y;
}
gimp_draw_tool_start (draw_tool, tool->gdisp);
if (clone->init_callback)
clone->init_callback (clone, clone->callback_data);
if (options->type == PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
@ -349,12 +247,13 @@ gimp_clone_tool_paint (GimpPaintTool *paint_tool,
break;
case FINISH_PAINT:
gimp_draw_tool_stop (draw_tool);
if (clone->finish_callback)
clone->finish_callback (clone, clone->callback_data);
if (options->aligned == ALIGN_NO && !first)
{
src_x = orig_src_x;
src_y = orig_src_y;
clone->src_x = orig_src_x;
clone->src_y = orig_src_y;
}
break;
@ -363,89 +262,14 @@ gimp_clone_tool_paint (GimpPaintTool *paint_tool,
}
}
void
gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp)
{
CloneOptions *options;
GimpLayer *layer;
GdkCursorType ctype = GIMP_MOUSE_CURSOR;
options = (CloneOptions *) tool->tool_info->tool_options;
if ((layer = gimp_image_get_active_layer (gdisp->gimage)))
{
int off_x, off_y;
gimp_drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
if (coords->x >= off_x &&
coords->y >= off_y &&
coords->x < (off_x + gimp_drawable_width (GIMP_DRAWABLE (layer))) &&
coords->y < (off_y + gimp_drawable_height (GIMP_DRAWABLE (layer))))
{
/* One more test--is there a selected region?
* if so, is cursor inside?
*/
if (gimp_image_mask_is_empty (gdisp->gimage))
ctype = GIMP_MOUSE_CURSOR;
else if (gimp_image_mask_value (gdisp->gimage, coords->x, coords->y))
ctype = GIMP_MOUSE_CURSOR;
}
}
if (options->type == IMAGE_CLONE)
{
if (state & GDK_CONTROL_MASK)
ctype = GIMP_CROSSHAIR_SMALL_CURSOR;
else if (! the_src_drawable)
ctype = GIMP_BAD_CURSOR;
}
tool->cursor = ctype;
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_clone_tool_draw (GimpDrawTool *draw_tool)
{
GimpTool *tool;
tool = GIMP_TOOL (draw_tool);
if (tool->state == ACTIVE)
{
CloneOptions *options;
options = (CloneOptions *) tool->tool_info->tool_options;
if (draw_tool->gdisp && options->type == IMAGE_CLONE)
{
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_CROSS,
src_x, src_y,
TARGET_WIDTH, TARGET_WIDTH,
GTK_ANCHOR_CENTER,
TRUE);
}
}
else
{
GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool);
}
}
static void
gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
int offset_x,
int offset_y)
gimp_clone_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y)
{
GimpImage *gimage;
GimpImage *src_gimage = NULL;
@ -484,12 +308,12 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
scale = paint_core->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
if (! (area = gimp_paint_core_get_paint_area (paint_core, drawable, scale)))
return;
switch (type)
@ -532,7 +356,7 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
return;
/* get the original image */
orig = gimp_paint_tool_get_orig_image (paint_tool, drawable, x1, y1, x2, y2);
orig = gimp_paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0; srcPR.y = 0;
@ -583,16 +407,18 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
switch (type)
{
case IMAGE_CLONE:
gimp_clone_tool_line_image (gimage, src_gimage, drawable,
src_drawable, s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
gimp_clone_line_image (gimage, src_gimage,
drawable, src_drawable,
s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
break;
case PATTERN_CLONE:
gimp_clone_tool_line_pattern (gimage, drawable, pattern, d,
area->x + offset_x,
area->y + y + offset_y,
destPR.bytes, destPR.w);
gimp_clone_line_pattern (gimage, drawable,
pattern, d,
area->x + offset_x,
area->y + y + offset_y,
destPR.bytes, destPR.w);
break;
}
@ -602,10 +428,10 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
opacity = 255.0 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
opacity = opacity * 2.0 * paint_core->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
gimp_paint_core_paste_canvas (paint_core, drawable,
MIN (opacity, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_paint_mode (context),
@ -613,18 +439,17 @@ gimp_clone_tool_motion (GimpPaintTool *paint_tool,
scale, CONSTANT);
}
static void
gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width)
gimp_clone_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width)
{
guchar rgb[3];
gint src_alpha, dest_alpha;
@ -648,14 +473,14 @@ gimp_clone_tool_line_image (GimpImage *dest,
}
static void
gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width)
gimp_clone_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width)
{
guchar *pat, *p;
GimpImageBaseType color_type;
@ -688,172 +513,34 @@ gimp_clone_tool_line_pattern (GimpImage *dest,
}
}
#if 0 /* leave these to the stub functions. */
static gpointer
gimp_clone_tool_non_gui_paint_func (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
static void
gimp_clone_src_drawable_disconnect_cb (GimpDrawable *drawable,
GimpClone *clone)
{
gimp_clone_tool_motion (paint_tool, drawable, non_gui_src_drawable,
&non_gui_pressure_options,
non_gui_type, non_gui_offset_x, non_gui_offset_y);
return NULL;
}
gboolean
gimp_clone_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
GimpDrawable *src_drawable = NULL;
CloneType clone_type = CLONE_DEFAULT_TYPE;
gdouble local_src_x = 0.0;
gdouble local_src_y = 0.0;
CloneOptions *options = clone_options;
if (options)
if (drawable == clone->src_drawable)
{
clone_type = options->type;
src_drawable = the_src_drawable;
local_src_x = src_x;
local_src_y = src_y;
clone->src_drawable = NULL;
}
return gimp_clone_tool_non_gui (drawable,
src_drawable,
clone_type,
local_src_x,local_src_y,
num_strokes, stroke_array);
}
gboolean
gimp_clone_tool_non_gui (GimpDrawable *drawable,
GimpDrawable *src_drawable,
CloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gdouble *stroke_array)
{
gint i;
if (gimp_paint_tool_start (&non_gui_paint_tool, drawable,
stroke_array[0], stroke_array[1]))
{
/* Set the paint core's paint func */
non_gui_paint_core.paint_func = clone_non_gui_paint_func;
non_gui_type = clone_type;
non_gui_src_drawable = src_drawable;
non_gui_paint_core.startx = non_gui_paint_core.lastx = stroke_array[0];
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
non_gui_offset_x = (int) (src_x - non_gui_paint_core.start_coords.x);
non_gui_offset_y = (int) (src_y - non_gui_paint_core.start_coords.y);
clone_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
non_gui_paint_core.cur_coords.x = stroke_array[i * 2 + 0];
non_gui_paint_core.cur_coords.y = stroke_array[i * 2 + 1];
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.last_coords.x = non_gui_paint_core.cur_coords.x;
non_gui_paint_core.last_coords.y = non_gui_paint_core.cur_coords.y;
}
/* Finish the painting */
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* Cleanup */
paint_core_cleanup ();
return TRUE;
}
else
return FALSE;
}
#endif /* 0 - non-gui functions */
static GimpToolOptions *
clone_options_new (GimpToolInfo *tool_info)
{
CloneOptions *options;
GtkWidget *vbox;
GtkWidget *frame;
options = g_new0 (CloneOptions, 1);
paint_options_init ((PaintOptions *) options, tool_info);
((GimpToolOptions *) options)->reset_func = clone_options_reset;
options->type = options->type_d = CLONE_DEFAULT_TYPE;
options->aligned = options->aligned_d = CLONE_DEFAULT_ALIGNED;
/* the main vbox */
vbox = ((GimpToolOptions *) options)->main_vbox;
frame = gimp_radio_group_new2 (TRUE, _("Source"),
G_CALLBACK (gimp_radio_button_update),
&options->type,
GINT_TO_POINTER (options->type),
_("Image Source"),
GINT_TO_POINTER (IMAGE_CLONE),
&options->type_w[0],
_("Pattern Source"),
GINT_TO_POINTER (PATTERN_CLONE),
&options->type_w[1],
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
frame = gimp_radio_group_new2 (TRUE, _("Alignment"),
G_CALLBACK (gimp_radio_button_update),
&options->aligned,
GINT_TO_POINTER (options->aligned),
_("Non Aligned"),
GINT_TO_POINTER (ALIGN_NO),
&options->aligned_w[0],
_("Aligned"),
GINT_TO_POINTER (ALIGN_YES),
&options->aligned_w[1],
_("Registered"),
GINT_TO_POINTER (ALIGN_REGISTERED),
&options->aligned_w[2],
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
return (GimpToolOptions *) options;
}
static void
clone_options_reset (GimpToolOptions *tool_options)
gimp_clone_set_src_drawable (GimpClone *clone,
GimpDrawable *drawable)
{
CloneOptions *options;
if (clone->src_drawable == drawable)
return;
options = (CloneOptions *) tool_options;
if (clone->src_drawable)
g_signal_handlers_disconnect_by_func (G_OBJECT (clone->src_drawable),
gimp_clone_src_drawable_disconnect_cb,
clone);
paint_options_reset (tool_options);
clone->src_drawable = drawable;
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->type_w[0]),
GINT_TO_POINTER (options->type_d));
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->aligned_w[0]),
GINT_TO_POINTER (options->aligned_d));
if (clone->src_drawable)
{
g_signal_connect (G_OBJECT (clone->src_drawable), "disconnect",
G_CALLBACK (gimp_clone_src_drawable_disconnect_cb),
clone);
}
}

View File

@ -16,63 +16,77 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_CLONE_TOOL_H__
#define __GIMP_CLONE_TOOL_H__
#ifndef __GIMP_CLONE_H__
#define __GIMP_CLONE_H__
#include "gimppainttool.h"
#include "gimppaintcore.h"
typedef enum
typedef enum /*< skip >*/ /*< pdb-skip >*/
{
IMAGE_CLONE,
PATTERN_CLONE
} CloneType;
ALIGN_NO,
ALIGN_YES,
ALIGN_REGISTERED
} AlignType;
#define GIMP_TYPE_CLONE_TOOL (gimp_clone_tool_get_type ())
#define GIMP_CLONE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CLONE_TOOL, GimpCloneTool))
#define GIMP_CLONE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CLONE_TOOL, GimpCloneToolClass))
#define GIMP_IS_CLONE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CLONE_TOOL))
#define GIMP_IS_CLONE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CLONE_TOOL))
#define GIMP_CLONE_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CLONE_TOOL, GimpCloneToolClass))
#define GIMP_TYPE_CLONE (gimp_clone_get_type ())
#define GIMP_CLONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CLONE, GimpClone))
#define GIMP_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CLONE, GimpCloneClass))
#define GIMP_IS_CLONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CLONE))
#define GIMP_IS_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CLONE))
#define GIMP_CLONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CLONE, GimpCloneClass))
typedef struct _GimpCloneTool GimpCloneTool;
typedef struct _GimpCloneToolClass GimpCloneToolClass;
typedef struct _GimpClone GimpClone;
typedef struct _GimpCloneClass GimpCloneClass;
struct _GimpCloneTool
struct _GimpClone
{
GimpPaintTool parent_instance;
GimpPaintCore parent_instance;
gboolean set_source;
GimpDrawable *src_drawable;
gint src_x;
gint src_y;
void (* init_callback) (GimpClone *clone,
gpointer data);
void (* finish_callback) (GimpClone *clone,
gpointer data);
void (* pretrace_callback) (GimpClone *clone,
gpointer data);
void (* posttrace_callback) (GimpClone *clone,
gpointer data);
gpointer callback_data;
};
struct _GimpCloneToolClass
struct _GimpCloneClass
{
GimpPaintToolClass parent_class;
GimpPaintCoreClass parent_class;
};
void gimp_clone_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback);
typedef struct _CloneOptions CloneOptions;
GType gimp_clone_tool_get_type (void) G_GNUC_CONST;
struct _CloneOptions
{
PaintOptions paint_options;
CloneType type;
CloneType type_d;
GtkWidget *type_w[2]; /* 2 radio buttons */
AlignType aligned;
AlignType aligned_d;
GtkWidget *aligned_w[3]; /* 3 radio buttons */
};
/* FIXME: Old style functions in need of a replacement. The only
* time these are used is to stroke paths or fill selections
* They should be somewhere else.
*/
gboolean clone_non_gui (GimpDrawable *drawable,
GimpDrawable *src_drawable,
CloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gdouble *stroke_array);
gboolean clone_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
GType gimp_clone_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_CLONE_TOOL_H__ */
#endif /* __GIMP_CLONE_H__ */

78
app/paint/paint-types.h Normal file
View File

@ -0,0 +1,78 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __PAINT_TYPES_H__
#define __PAINT_TYPES_H__
#include "core/core-types.h"
/* tools */
typedef struct _GimpPaintCore GimpPaintCore;
/* enums */
/* Brush application types */
typedef enum
{
HARD, /* pencil */
SOFT, /* paintbrush */
PRESSURE /* paintbrush with variable pressure */
} BrushApplicationMode;
/* Paint application modes */
typedef enum
{
CONSTANT, /*< nick=CONTINUOUS >*/ /* pencil, paintbrush, airbrush, clone */
INCREMENTAL /* convolve, smudge */
} PaintApplicationMode;
/* gradient paint modes */
typedef enum
{
ONCE_FORWARD, /* paint through once, then stop */
ONCE_BACKWARDS, /* paint once, then stop, but run the gradient the other way */
LOOP_SAWTOOTH, /* keep painting, looping through the grad start->end,start->end /|/|/| */
LOOP_TRIANGLE, /* keep paiting, looping though the grad start->end,end->start /\/\/\/ */
ONCE_END_COLOR /* paint once, but keep painting with the end color */
} GradientPaintMode;
typedef enum
{
DODGE,
BURN
} DodgeBurnType;
typedef enum
{
BLUR_CONVOLVE,
SHARPEN_CONVOLVE,
CUSTOM_CONVOLVE
} ConvolveType;
typedef enum
{
IMAGE_CLONE,
PATTERN_CLONE
} CloneType;
#endif /* __PAINT_TYPES_H__ */

View File

@ -32,6 +32,8 @@
#include "core/core-enums.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage-mask-select.h"
#include "paint/gimpdodgeburn.h"
#include "paint/paint-types.h"
#include "tools/gimpairbrushtool.h"
#include "tools/gimpclonetool.h"
#include "tools/gimpconvolvetool.h"
@ -106,7 +108,7 @@ airbrush_invoker (Gimp *gimp,
strokes = (gdouble *) args[3].value.pdb_pointer;
if (success)
success = airbrush_non_gui (drawable, pressure, num_strokes, strokes);
success = FALSE; /*airbrush_non_gui (drawable, pressure, num_strokes, strokes);*/
return procedural_db_return_args (&airbrush_proc, success);
}
@ -173,7 +175,7 @@ airbrush_default_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = airbrush_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*airbrush_non_gui_default (drawable, num_strokes, strokes);*/
return procedural_db_return_args (&airbrush_default_proc, success);
}
@ -251,8 +253,8 @@ clone_invoker (Gimp *gimp,
strokes = (gdouble *) args[6].value.pdb_pointer;
if (success)
success = clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);
success = FALSE; /*clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);*/
return procedural_db_return_args (&clone_proc, success);
}
@ -334,7 +336,7 @@ clone_default_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = clone_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*clone_non_gui_default (drawable, num_strokes, strokes);*/
return procedural_db_return_args (&clone_default_proc, success);
}
@ -406,7 +408,7 @@ convolve_invoker (Gimp *gimp,
strokes = (gdouble *) args[4].value.pdb_pointer;
if (success)
success = convolve_non_gui (drawable, pressure, convolve_type, num_strokes, strokes);
success = FALSE; /*convolve_non_gui (drawable, pressure, convolve_type, num_strokes, strokes);*/
return procedural_db_return_args (&convolve_proc, success);
}
@ -478,7 +480,7 @@ convolve_default_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = convolve_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*convolve_non_gui_default (drawable, num_strokes, strokes);*/
return procedural_db_return_args (&convolve_default_proc, success);
}
@ -555,7 +557,7 @@ dodgeburn_invoker (Gimp *gimp,
strokes = (gdouble *) args[5].value.pdb_pointer;
if (success)
success = gimp_dodgeburn_tool_non_gui (drawable, exposure, dodgeburn_type, dodgeburn_mode, num_strokes, strokes);
success = FALSE; /*gimp_dodgeburn_tool_non_gui (drawable, exposure, dodgeburn_type, dodgeburn_mode, num_strokes, strokes);*/
return procedural_db_return_args (&dodgeburn_proc, success);
}
@ -632,7 +634,7 @@ dodgeburn_default_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = gimp_dodgeburn_tool_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*gimp_dodgeburn_tool_non_gui_default (drawable, num_strokes, strokes);*/
return procedural_db_return_args (&dodgeburn_default_proc, success);
}
@ -704,7 +706,7 @@ eraser_invoker (Gimp *gimp,
success = FALSE;
if (success)
success = eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE);
success = FALSE; /*eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE);*/
return procedural_db_return_args (&eraser_proc, success);
}
@ -776,7 +778,7 @@ eraser_default_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = eraser_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*eraser_non_gui_default (drawable, num_strokes, strokes);*/
return procedural_db_return_args (&eraser_default_proc, success);
}
@ -853,8 +855,8 @@ paintbrush_invoker (Gimp *gimp,
success = FALSE;
if (success)
success = gimp_paintbrush_tool_non_gui (drawable, num_strokes, strokes,
fade_out, method, gradient_length);
success = FALSE; /*gimp_paintbrush_tool_non_gui (drawable, num_strokes, strokes,
fade_out, method, gradient_length);*/
return procedural_db_return_args (&paintbrush_proc, success);
}
@ -931,7 +933,7 @@ paintbrush_default_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = gimp_paintbrush_tool_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*gimp_paintbrush_tool_non_gui_default (drawable, num_strokes, strokes);*/
return procedural_db_return_args (&paintbrush_default_proc, success);
}
@ -993,7 +995,7 @@ pencil_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = pencil_non_gui (drawable, num_strokes, strokes);
success = FALSE; /*pencil_non_gui (drawable, num_strokes, strokes);'*/
return procedural_db_return_args (&pencil_proc, success);
}
@ -1060,7 +1062,7 @@ smudge_invoker (Gimp *gimp,
strokes = (gdouble *) args[3].value.pdb_pointer;
if (success)
success = gimp_smudge_tool_non_gui (drawable, pressure, num_strokes, strokes);
success = FALSE; /*gimp_smudge_tool_non_gui (drawable, pressure, num_strokes, strokes);*/
return procedural_db_return_args (&smudge_proc, success);
}
@ -1127,7 +1129,7 @@ smudge_default_invoker (Gimp *gimp,
strokes = (gdouble *) args[2].value.pdb_pointer;
if (success)
success = gimp_smudge_tool_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*gimp_smudge_tool_non_gui_default (drawable, num_strokes, strokes);*/
return procedural_db_return_args (&smudge_default_proc, success);
}

View File

@ -20,101 +20,35 @@
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplay-foreach.h"
#include "paint/gimpairbrush.h"
#include "gimpairbrushtool.h"
#include "paint_options.h"
#include "gimptool.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
/* The maximum amount of pressure that can be exerted */
#define MAX_PRESSURE 0.075
#define MAX_PRESSURE 0.075
/* Default pressure setting */
#define AIRBRUSH_DEFAULT_RATE 0.0
#define AIRBRUSH_DEFAULT_PRESSURE 10.0
#define AIRBRUSH_DEFAULT_INCREMENTAL FALSE
#define OFF 0
#define ON 1
/* the airbrush structures */
typedef struct _AirbrushTimeout AirbrushTimeout;
struct _AirbrushTimeout
{
GimpPaintTool *paint_tool;
GimpDrawable *drawable;
};
typedef struct _AirbrushOptions AirbrushOptions;
struct _AirbrushOptions
{
PaintOptions paint_options;
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
gdouble pressure;
gdouble pressure_d;
GtkObject *pressure_w;
};
/* local function prototypes */
static void gimp_airbrush_tool_class_init (GimpAirbrushToolClass *klass);
static void gimp_airbrush_tool_init (GimpAirbrushTool *airbrush);
static void gimp_airbrush_tool_finalize (GObject *object);
static void gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble pressure,
gboolean incremental);
static gint airbrush_time_out (gpointer data);
static GimpToolOptions * airbrush_options_new (GimpToolInfo *tool_info);
static void airbrush_options_reset (GimpToolOptions *tool_options);
/* local variables */
static gint timer; /* timer for successive paint applications */
static gint timer_state = OFF; /* state of airbrush tool */
static AirbrushTimeout airbrush_timeout;
static gdouble non_gui_rate;
static gdouble non_gui_pressure;
static gboolean non_gui_incremental;
static GimpPaintToolClass *parent_class = NULL;
@ -167,17 +101,11 @@ gimp_airbrush_tool_get_type (void)
static void
gimp_airbrush_tool_class_init (GimpAirbrushToolClass *klass)
{
GObjectClass *object_class;
GimpPaintToolClass *paint_tool_class;
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_airbrush_tool_finalize;
paint_tool_class->paint = gimp_airbrush_tool_paint;
}
static void
@ -189,240 +117,13 @@ gimp_airbrush_tool_init (GimpAirbrushTool *airbrush)
tool = GIMP_TOOL (airbrush);
paint_tool = GIMP_PAINT_TOOL (airbrush);
tool->tool_cursor = GIMP_AIRBRUSH_TOOL_CURSOR;
tool->tool_cursor = GIMP_AIRBRUSH_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_airbrush_tool_finalize (GObject *object)
{
if (timer_state == ON)
{
gtk_timeout_remove (timer);
timer_state = OFF;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
paint_tool->pick_colors = TRUE;
paint_tool->core = g_object_new (GIMP_TYPE_AIRBRUSH, NULL);
}
static void
gimp_airbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
AirbrushOptions *options;
PaintPressureOptions *pressure_options;
gdouble pressure;
gdouble rate;
gboolean incremental;
GimpBrush *brush;
if (! drawable)
return;
options = (AirbrushOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
pressure = options->pressure;
rate = options->rate;
incremental = options->paint_options.incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
pressure = non_gui_pressure;
rate = non_gui_rate;
incremental = non_gui_incremental;
}
brush =
gimp_context_get_brush (gimp_get_current_context (drawable->gimage->gimp));
switch (state)
{
case INIT_PAINT:
if (timer_state == ON)
{
g_warning ("killing stray timer, please report to lewing@gimp.org");
gtk_timeout_remove (timer);
timer_state = OFF;
}
break;
case MOTION_PAINT:
if (timer_state == ON)
{
gtk_timeout_remove (timer);
timer_state = OFF;
}
gimp_airbrush_tool_motion (paint_tool,
drawable,
pressure_options,
pressure,
incremental);
if (rate != 0.0)
{
gdouble timeout;
airbrush_timeout.paint_tool = paint_tool;
airbrush_timeout.drawable = drawable;
timeout = (pressure_options->rate ?
(10000 / (rate * 2.0 * paint_tool->cur_coords.pressure)) :
(10000 / rate));
timer = gtk_timeout_add (timeout, airbrush_time_out, paint_tool);
timer_state = ON;
}
break;
case FINISH_PAINT:
if (timer_state == ON)
{
gtk_timeout_remove (timer);
timer_state = OFF;
}
break;
default:
break;
}
}
static gint
airbrush_time_out (gpointer client_data)
{
GimpTool *tool;
AirbrushOptions *options;
PaintPressureOptions *pressure_options;
gdouble pressure;
gdouble rate;
gboolean incremental;
tool = GIMP_TOOL (client_data);
options = (AirbrushOptions *) tool->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
pressure = options->pressure;
rate = options->rate;
incremental = options->paint_options.incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
pressure = non_gui_pressure;
rate = non_gui_rate;
incremental = non_gui_incremental;
}
gimp_airbrush_tool_motion (airbrush_timeout.paint_tool,
airbrush_timeout.drawable,
pressure_options,
pressure,
incremental);
gdisplays_flush ();
/* restart the timer */
if (rate != 0.0)
{
if (pressure_options->rate)
{
/* set a new timer */
timer = gtk_timeout_add ((10000 / (rate * 2.0 * airbrush_timeout.paint_tool->cur_coords.pressure)),
airbrush_time_out, NULL);
return FALSE;
}
return TRUE;
}
return FALSE;
}
static void
gimp_airbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble pressure,
gboolean incremental)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
PaintApplicationMode paint_appl_mode = incremental ? INCREMENTAL : CONSTANT;
if (!drawable)
return;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
/* color the pixels */
if (pressure_options->color)
{
GimpRGB color;
gimp_gradient_get_color_at (gimp_context_get_gradient (context),
paint_tool->cur_coords.pressure, &color);
gimp_rgba_get_uchar (&color,
&col[RED_PIX],
&col[GREEN_PIX],
&col[BLUE_PIX],
&col[ALPHA_PIX]);
paint_appl_mode = INCREMENTAL;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (paint_tool->brush && paint_tool->brush->pixmap)
{
paint_appl_mode = INCREMENTAL;
gimp_paint_tool_color_area_with_pixmap (paint_tool, gimage,
drawable, area,
scale, SOFT);
}
else
{
gimp_image_get_foreground (gimage, drawable, col);
col[area->bytes - 1] = OPAQUE_OPACITY;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
if (pressure_options->pressure)
pressure = pressure * 2.0 * paint_tool->cur_coords.pressure;
/* paste the newly painted area to the image */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
MIN (pressure, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_paint_mode (gimp_get_current_context (gimage->gimp)),
SOFT, scale, paint_appl_mode);
}
#if 0
gboolean
airbrush_non_gui_default (GimpDrawable *drawable,
@ -495,6 +196,8 @@ airbrush_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif
static GimpToolOptions *
airbrush_options_new (GimpToolInfo *tool_info)
{

View File

@ -51,13 +51,4 @@ void gimp_airbrush_tool_register (Gimp *gimp,
GType gimp_airbrush_tool_get_type (void) G_GNUC_CONST;
gboolean airbrush_non_gui (GimpDrawable *drawable,
gdouble pressure,
gint num_strokes,
gdouble *stroke_array);
gboolean airbrush_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_AIRBRUSH_TOOL_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -23,37 +23,6 @@
#include "gimpdrawtool.h"
#define PAINT_TOOL_SUBSAMPLE 4
/* the different states that the painting function can be called with */
typedef enum /*< pdb-skip >*/
{
INIT_PAINT, /* Setup PaintFunc internals */
MOTION_PAINT, /* PaintFunc performs motion-related rendering */
PAUSE_PAINT, /* Unused. Reserved */
RESUME_PAINT, /* Unused. Reserved */
FINISH_PAINT, /* Cleanup and/or reset PaintFunc operation */
PRETRACE_PAINT, /* PaintFunc performs window tracing activity prior to rendering */
POSTTRACE_PAINT /* PaintFunc performs window tracing activity following rendering */
} PaintState;
typedef enum /*< pdb-skip >*/
{
TOOL_CAN_HANDLE_CHANGING_BRUSH = 0x0001, /* Set for tools that don't mind
* if the brush changes while
* painting.
*/
TOOL_TRACES_ON_WINDOW /* Set for tools that perform temporary
* rendering directly to the window. These
* require sequencing with gdisplay_flush()
* routines. See clone.c for example.
*/
} ToolFlags;
#define GIMP_TYPE_PAINT_TOOL (gimp_paint_tool_get_type ())
#define GIMP_PAINT_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINT_TOOL, GimpPaintTool))
#define GIMP_PAINT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PAINT_TOOL, GimpPaintToolClass))
@ -66,126 +35,22 @@ typedef struct _GimpPaintToolClass GimpPaintToolClass;
struct _GimpPaintTool
{
GimpDrawTool parent_instance;
GimpDrawTool parent_instance;
GimpCoords start_coords; /* starting coords */
GimpCoords cur_coords; /* current coords */
GimpCoords last_coords; /* last coords */
GdkModifierType state; /* state of buttons and keys */
gboolean pick_colors; /* pick color if ctrl or alt is pressed */
gboolean pick_state; /* was ctrl or alt pressed when clicked? */
gint state; /* state of buttons and keys */
gdouble distance; /* distance traveled by brush */
gdouble pixel_dist; /* distance in pixels */
gdouble spacing; /* spacing */
gint x1, y1; /* image space coordinate */
gint x2, y2; /* image space coords */
GimpBrush *brush; /* current brush */
gboolean pick_colors; /* pick color if ctrl or alt is pressed */
gboolean pick_state; /* was ctrl or alt pressed when clicked? */
ToolFlags flags; /* tool flags, see ToolFlags above */
/* undo blocks variables */
TileManager *undo_tiles;
TileManager *canvas_tiles;
/* paint buffers variables */
TempBuf *orig_buf;
TempBuf *canvas_buf;
/* brush buffers */
MaskBuf *pressure_brush;
MaskBuf *solid_brush;
MaskBuf *scale_brush;
MaskBuf *scale_pixmap;
MaskBuf *kernel_brushes[PAINT_TOOL_SUBSAMPLE + 1][PAINT_TOOL_SUBSAMPLE + 1];
MaskBuf *last_brush_mask;
gboolean cache_invalid;
/* don't use this one... */
GimpBrush *grr_brush;
GimpPaintCore *core;
};
struct _GimpPaintToolClass
{
GimpDrawToolClass parent_class;
/* virtual function */
void (* paint) (GimpPaintTool *tool,
GimpDrawable *drawable,
PaintState paint_state);
};
/* Special undo type */
typedef struct _PaintUndo PaintUndo;
struct _PaintUndo
{
gint tool_ID;
GType tool_type;
GimpCoords last_coords;
};
GType gimp_paint_tool_get_type (void) G_GNUC_CONST;
void gimp_paint_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
int gimp_paint_tool_start (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gdouble x,
gdouble y);
void gimp_paint_tool_interpolate (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
void gimp_paint_tool_finish (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
void gimp_paint_tool_cleanup (GimpPaintTool *paint_tool);
void gimp_paint_tool_get_color_from_gradient (GimpPaintTool *paint_tool,
GimpGradient *gradient,
gdouble gradient_length,
GimpRGB *color,
GradientPaintMode mode);
/* paint tool painting functions */
TempBuf * gimp_paint_tool_get_paint_area (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gdouble scale);
TempBuf * gimp_paint_tool_get_orig_image (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gint x1,
gint y1,
gint x2,
gint y2);
void gimp_paint_tool_paste_canvas (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gint brush_opacity,
gint image_opacity,
GimpLayerModeEffects paint_mode,
BrushApplicationMode brush_hardness,
gdouble brush_scale,
PaintApplicationMode mode);
void gimp_paint_tool_replace_canvas (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gint brush_opacity,
gint image_opacity,
BrushApplicationMode brush_hardness,
gdouble brush_scale,
PaintApplicationMode mode);
void gimp_paint_tool_color_area_with_pixmap (GimpPaintTool *paint_tool,
GimpImage *dest,
GimpDrawable *drawable,
TempBuf *area,
gdouble scale,
BrushApplicationMode mode);
GType gimp_paint_tool_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_PAINT_TOOL_H__ */

View File

@ -18,29 +18,19 @@
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpimage-mask.h"
#include "core/gimppattern.h"
#include "core/gimptoolinfo.h"
#include "paint/gimpclone.h"
#include "display/gimpdisplay.h"
#include "gimpclonetool.h"
@ -52,95 +42,44 @@
#define TARGET_WIDTH 15
#define TARGET_HEIGHT 15
/* default types */
#define CLONE_DEFAULT_TYPE IMAGE_CLONE
#define CLONE_DEFAULT_ALIGNED ALIGN_NO
/* the clone structures */
typedef enum
{
ALIGN_NO,
ALIGN_YES,
ALIGN_REGISTERED
} AlignType;
static void gimp_clone_tool_class_init (GimpCloneToolClass *klass);
static void gimp_clone_tool_init (GimpCloneTool *tool);
typedef struct _CloneOptions CloneOptions;
static void gimp_clone_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_clone_tool_motion (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp);
struct _CloneOptions
{
PaintOptions paint_options;
static void gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
CloneType type;
CloneType type_d;
GtkWidget *type_w[2]; /* 2 radio buttons */
static void gimp_clone_tool_draw (GimpDrawTool *draw_tool);
AlignType aligned;
AlignType aligned_d;
GtkWidget *aligned_w[3]; /* 3 radio buttons */
};
/* forward function declarations */
static void gimp_clone_tool_class_init (GimpCloneToolClass *klass);
static void gimp_clone_tool_init (GimpCloneTool *tool);
static void gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_clone_tool_draw (GimpDrawTool *draw_tool);
static void gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y);
static void gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width);
static void gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width);
static void gimp_clone_init_callback (GimpClone *clone,
gpointer data);
static void gimp_clone_finish_callback (GimpClone *clone,
gpointer data);
static void gimp_clone_pretrace_callback (GimpClone *clone,
gpointer data);
static void gimp_clone_posttrace_callback (GimpClone *clone,
gpointer data);
static GimpToolOptions * clone_options_new (GimpToolInfo *tool_info);
static void clone_options_reset (GimpToolOptions *options);
/* local variables */
static gint src_x = 0; /* */
static gint src_y = 0; /* position of clone src */
static gint dest_x = 0; /* */
static gint dest_y = 0; /* position of clone src */
static gint offset_x = 0; /* */
static gint offset_y = 0; /* offset for cloning */
static gint first = TRUE;
static GimpDrawable *the_src_drawable = NULL; /* source drawable */
static GimpDrawable *non_gui_src_drawable;
static gint non_gui_offset_x;
static gint non_gui_offset_y;
static CloneType non_gui_type;
static GimpPaintToolClass *parent_class;
@ -195,21 +134,19 @@ gimp_clone_tool_get_type (void)
static void
gimp_clone_tool_class_init (GimpCloneToolClass *klass)
{
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
GimpPaintToolClass *paint_tool_class;
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
tool_class = GIMP_TOOL_CLASS (klass);
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
tool_class = GIMP_TOOL_CLASS (klass);
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->button_press = gimp_clone_tool_button_press;
tool_class->motion = gimp_clone_tool_motion;
tool_class->cursor_update = gimp_clone_tool_cursor_update;
draw_tool_class->draw = gimp_clone_tool_draw;
paint_tool_class->paint = gimp_clone_tool_paint;
}
static void
@ -217,150 +154,76 @@ gimp_clone_tool_init (GimpCloneTool *clone)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpClone *clone_core;
tool = GIMP_TOOL (clone);
paint_tool = GIMP_PAINT_TOOL (clone);
tool->tool_cursor = GIMP_CLONE_TOOL_CURSOR;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_tool->flags |= TOOL_TRACES_ON_WINDOW;
clone_core = g_object_new (GIMP_TYPE_CLONE, NULL);
clone_core->init_callback = gimp_clone_init_callback;
clone_core->finish_callback = gimp_clone_finish_callback;
clone_core->pretrace_callback = gimp_clone_pretrace_callback;
clone_core->posttrace_callback = gimp_clone_posttrace_callback;
clone_core->callback_data = clone;
paint_tool->core = GIMP_PAINT_CORE (clone_core);
}
static void
clone_src_drawable_disconnect_cb (GimpDrawable *drawable,
GimpDrawable **src_drawable)
gimp_clone_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp)
{
if (drawable == *src_drawable)
GimpPaintTool *paint_tool;
paint_tool = GIMP_PAINT_TOOL (tool);
if (state & GDK_CONTROL_MASK)
{
*src_drawable = NULL;
GIMP_CLONE (paint_tool->core)->set_source = TRUE;
}
else
{
GIMP_CLONE (paint_tool->core)->set_source = FALSE;
}
GIMP_TOOL_CLASS (parent_class)->button_press (tool,
coords,
time,
state,
gdisp);
}
static void
clone_set_src_drawable (GimpDrawable *drawable)
gimp_clone_tool_motion (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp)
{
if (the_src_drawable == drawable)
return;
GimpPaintTool *paint_tool;
if (the_src_drawable)
g_signal_handlers_disconnect_by_func (G_OBJECT (the_src_drawable),
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
paint_tool = GIMP_PAINT_TOOL (tool);
the_src_drawable = drawable;
if (the_src_drawable)
if (state & GDK_CONTROL_MASK)
{
g_signal_connect (G_OBJECT (the_src_drawable), "disconnect",
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
GIMP_CLONE (paint_tool->core)->set_source = TRUE;
}
}
static void
gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
GimpTool *tool;
GimpDrawTool *draw_tool;
CloneOptions *options;
GimpContext *context;
static gint orig_src_x = 0;
static gint orig_src_y = 0;
tool = GIMP_TOOL (paint_tool);
draw_tool = GIMP_DRAW_TOOL (paint_tool);
options = (CloneOptions *) tool->tool_info->tool_options;
context = gimp_get_current_context (tool->gdisp->gimage->gimp);
switch (state)
else
{
case PRETRACE_PAINT:
gimp_draw_tool_pause (draw_tool);
break;
case POSTTRACE_PAINT:
gimp_draw_tool_resume (draw_tool);
break;
case MOTION_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
{
/* If the control key is down, move the src target and return */
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
first = TRUE;
}
else
{
/* otherwise, update the target */
dest_x = paint_tool->cur_coords.x;
dest_y = paint_tool->cur_coords.y;
if (options->aligned == ALIGN_REGISTERED)
{
offset_x = 0;
offset_y = 0;
}
else if (first)
{
offset_x = src_x - dest_x;
offset_y = src_y - dest_y;
first = FALSE;
}
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
gimp_clone_tool_motion (paint_tool, drawable, the_src_drawable,
options->paint_options.pressure_options,
options->type,
offset_x, offset_y);
}
break;
case INIT_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
{
clone_set_src_drawable (drawable);
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
first = TRUE;
}
else if (options->aligned == ALIGN_NO)
{
first = TRUE;
orig_src_x = src_x;
orig_src_y = src_y;
}
gimp_draw_tool_start (draw_tool, tool->gdisp);
if (options->type == PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
g_message (_("No patterns available for this operation."));
break;
case FINISH_PAINT:
gimp_draw_tool_stop (draw_tool);
if (options->aligned == ALIGN_NO && !first)
{
src_x = orig_src_x;
src_y = orig_src_y;
}
break;
default:
break;
GIMP_CLONE (paint_tool->core)->set_source = FALSE;
}
GIMP_TOOL_CLASS (parent_class)->motion (tool,
coords,
time,
state,
gdisp);
}
void
@ -377,7 +240,7 @@ gimp_clone_tool_cursor_update (GimpTool *tool,
if ((layer = gimp_image_get_active_layer (gdisp->gimage)))
{
int off_x, off_y;
gint off_x, off_y;
gimp_drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
@ -400,7 +263,7 @@ gimp_clone_tool_cursor_update (GimpTool *tool,
{
if (state & GDK_CONTROL_MASK)
ctype = GIMP_CROSSHAIR_SMALL_CURSOR;
else if (! the_src_drawable)
else if (! GIMP_CLONE (GIMP_PAINT_TOOL (tool)->core)->src_drawable)
ctype = GIMP_BAD_CURSOR;
}
@ -424,9 +287,14 @@ gimp_clone_tool_draw (GimpDrawTool *draw_tool)
if (draw_tool->gdisp && options->type == IMAGE_CLONE)
{
GimpClone *clone;
clone = GIMP_CLONE (GIMP_PAINT_TOOL (draw_tool)->core);
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_CROSS,
src_x, src_y,
clone->src_x,
clone->src_y,
TARGET_WIDTH, TARGET_WIDTH,
GTK_ANCHOR_CENTER,
TRUE);
@ -439,256 +307,52 @@ gimp_clone_tool_draw (GimpDrawTool *draw_tool)
}
static void
gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
int offset_x,
int offset_y)
gimp_clone_init_callback (GimpClone *clone,
gpointer data)
{
GimpImage *gimage;
GimpImage *src_gimage = NULL;
GimpContext *context;
guchar *s;
guchar *d;
TempBuf *orig;
TempBuf *area;
gpointer pr;
gint y;
gint x1, y1, x2, y2;
gint has_alpha = -1;
PixelRegion srcPR, destPR;
GimpPattern *pattern;
gint opacity;
gdouble scale;
GimpCloneTool *clone_tool;
pr = NULL;
pattern = NULL;
clone_tool = GIMP_CLONE_TOOL (data);
/* Make sure we still have a source if we are doing image cloning */
if (type == IMAGE_CLONE)
{
if (!src_drawable)
return;
if (! (src_gimage = gimp_drawable_gimage (src_drawable)))
return;
/* Determine whether the source image has an alpha channel */
has_alpha = gimp_drawable_has_alpha (src_drawable);
}
/* We always need a destination image */
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
switch (type)
{
case IMAGE_CLONE:
/* Set the paint area to transparent */
temp_buf_data_clear (area);
/* If the source gimage is different from the destination,
* then we should copy straight from the destination image
* to the canvas.
* Otherwise, we need a call to get_orig_image to make sure
* we get a copy of the unblemished (offset) image
*/
if (src_drawable != drawable)
{
x1 = CLAMP (area->x + offset_x, 0, gimp_drawable_width (src_drawable));
y1 = CLAMP (area->y + offset_y, 0, gimp_drawable_height (src_drawable));
x2 = CLAMP (area->x + offset_x + area->width,
0, gimp_drawable_width (src_drawable));
y2 = CLAMP (area->y + offset_y + area->height,
0, gimp_drawable_height (src_drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
pixel_region_init (&srcPR, gimp_drawable_data (src_drawable),
x1, y1, (x2 - x1), (y2 - y1), FALSE);
}
else
{
x1 = CLAMP (area->x + offset_x, 0, gimp_drawable_width (drawable));
y1 = CLAMP (area->y + offset_y, 0, gimp_drawable_height (drawable));
x2 = CLAMP (area->x + offset_x + area->width,
0, gimp_drawable_width (drawable));
y2 = CLAMP (area->y + offset_y + area->height,
0, gimp_drawable_height (drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
/* get the original image */
orig = gimp_paint_tool_get_orig_image (paint_tool, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0; srcPR.y = 0;
srcPR.w = x2 - x1;
srcPR.h = y2 - y1;
srcPR.rowstride = srcPR.bytes * orig->width;
srcPR.data = temp_buf_data (orig);
}
offset_x = x1 - (area->x + offset_x);
offset_y = y1 - (area->y + offset_y);
/* configure the destination */
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = srcPR.w;
destPR.h = srcPR.h;
destPR.rowstride = destPR.bytes * area->width;
destPR.data = temp_buf_data (area) + offset_y * destPR.rowstride +
offset_x * destPR.bytes;
pr = pixel_regions_register (2, &srcPR, &destPR);
break;
case PATTERN_CLONE:
pattern = gimp_context_get_pattern (context);
if (!pattern)
return;
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.rowstride = destPR.bytes * area->width;
destPR.data = temp_buf_data (area);
pr = pixel_regions_register (1, &destPR);
break;
}
for (; pr != NULL; pr = pixel_regions_process (pr))
{
s = srcPR.data;
d = destPR.data;
for (y = 0; y < destPR.h; y++)
{
switch (type)
{
case IMAGE_CLONE:
gimp_clone_tool_line_image (gimage, src_gimage, drawable,
src_drawable, s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
break;
case PATTERN_CLONE:
gimp_clone_tool_line_pattern (gimage, drawable, pattern, d,
area->x + offset_x,
area->y + y + offset_y,
destPR.bytes, destPR.w);
break;
}
d += destPR.rowstride;
}
}
opacity = 255.0 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
MIN (opacity, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_paint_mode (context),
pressure_options->pressure ? PRESSURE : SOFT,
scale, CONSTANT);
}
static void
gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width)
{
guchar rgb[3];
gint src_alpha, dest_alpha;
src_alpha = src_bytes - 1;
dest_alpha = dest_bytes - 1;
while (width--)
{
gimp_image_get_color (src, gimp_drawable_type (s_drawable), rgb, s);
gimp_image_transform_color (dest, d_drawable, rgb, d, GIMP_RGB);
if (has_alpha)
d[dest_alpha] = s[src_alpha];
else
d[dest_alpha] = OPAQUE_OPACITY;
s += src_bytes;
d += dest_bytes;
}
gimp_draw_tool_start (GIMP_DRAW_TOOL (clone_tool),
GIMP_TOOL (clone_tool)->gdisp);
}
static void
gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width)
gimp_clone_finish_callback (GimpClone *clone,
gpointer data)
{
guchar *pat, *p;
GimpImageBaseType color_type;
gint alpha;
gint i;
GimpCloneTool *clone_tool;
/* Make sure x, y are positive */
while (x < 0)
x += pattern->mask->width;
while (y < 0)
y += pattern->mask->height;
clone_tool = GIMP_CLONE_TOOL (data);
/* Get a pointer to the appropriate scanline of the pattern buffer */
pat = temp_buf_data (pattern->mask) +
(y % pattern->mask->height) * pattern->mask->width * pattern->mask->bytes;
color_type = (pattern->mask->bytes == 3) ? GIMP_RGB : GIMP_GRAY;
alpha = bytes - 1;
for (i = 0; i < width; i++)
{
p = pat + ((i + x) % pattern->mask->width) * pattern->mask->bytes;
gimp_image_transform_color (dest, drawable, p, d, color_type);
d[alpha] = OPAQUE_OPACITY;
d += bytes;
}
gimp_draw_tool_stop (GIMP_DRAW_TOOL (clone_tool));
}
#if 0 /* leave these to the stub functions. */
static void
gimp_clone_pretrace_callback (GimpClone *clone,
gpointer data)
{
GimpCloneTool *clone_tool;
clone_tool = GIMP_CLONE_TOOL (data);
gimp_draw_tool_pause (GIMP_DRAW_TOOL (clone_tool));
}
static void
gimp_clone_posttrace_callback (GimpClone *clone,
gpointer data)
{
GimpCloneTool *clone_tool;
clone_tool = GIMP_CLONE_TOOL (data);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (clone_tool));
}
#if 0
static gpointer
gimp_clone_tool_non_gui_paint_func (GimpPaintTool *paint_tool,
@ -779,7 +443,10 @@ gimp_clone_tool_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif /* 0 - non-gui functions */
#endif
/* too options stuff */
static GimpToolOptions *
clone_options_new (GimpToolInfo *tool_info)

View File

@ -23,13 +23,6 @@
#include "gimppainttool.h"
typedef enum
{
IMAGE_CLONE,
PATTERN_CLONE
} CloneType;
#define GIMP_TYPE_CLONE_TOOL (gimp_clone_tool_get_type ())
#define GIMP_CLONE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CLONE_TOOL, GimpCloneTool))
#define GIMP_CLONE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CLONE_TOOL, GimpCloneToolClass))
@ -58,21 +51,4 @@ void gimp_clone_tool_register (Gimp *gimp,
GType gimp_clone_tool_get_type (void) G_GNUC_CONST;
/* FIXME: Old style functions in need of a replacement. The only
* time these are used is to stroke paths or fill selections
* They should be somewhere else.
*/
gboolean clone_non_gui (GimpDrawable *drawable,
GimpDrawable *src_drawable,
CloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gdouble *stroke_array);
gboolean clone_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_CLONE_TOOL_H__ */

View File

@ -37,6 +37,8 @@
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "paint/gimpconvolve.h"
#include "gimpconvolvetool.h"
#include "paint_options.h"
@ -54,109 +56,22 @@
#define DEFAULT_CONVOLVE_TYPE BLUR_CONVOLVE
/* Different clip relationships between a blur-blob and edges:
see convolve_motion */
static void gimp_convolve_tool_class_init (GimpConvolveToolClass *klass);
static void gimp_convolve_tool_init (GimpConvolveTool *tool);
typedef enum
{
CONVOLVE_NCLIP, /* Left or top edge */
CONVOLVE_NOT_CLIPPED, /* No edges */
CONVOLVE_PCLIP /* Right or bottom edge */
} ConvolveClipType;
static void gimp_convolve_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_convolve_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static GimpToolOptions * convolve_options_new (GimpToolInfo *tool_info);
static void convolve_options_reset (GimpToolOptions *options);
/* the convolve structures */
typedef struct _ConvolveOptions ConvolveOptions;
struct _ConvolveOptions
{
PaintOptions paint_options;
ConvolveType type;
ConvolveType type_d;
GtkWidget *type_w[2];
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
};
/* forward function declarations */
static void gimp_convolve_tool_class_init (GimpConvolveToolClass *klass);
static void gimp_convolve_tool_init (GimpConvolveTool *tool);
static void gimp_convolve_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_convolve_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_convolve_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
ConvolveType type,
gdouble rate);
static void calculate_matrix (ConvolveType type,
gdouble rate);
static void integer_matrix (gfloat *source,
gint *dest,
gint size);
static void copy_matrix (gfloat *src,
gfloat *dest,
gint size);
static gint sum_matrix (gint *matrix,
gint size);
static GimpToolOptions * convolve_options_new (GimpToolInfo *tool_info);
static void convolve_options_reset (GimpToolOptions *options);
/* local variables */
static gint matrix [25];
static gint matrix_size;
static gint matrix_divisor;
static ConvolveType non_gui_type;
static gdouble non_gui_rate;
static gfloat custom_matrix [25] =
{
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
};
static gfloat blur_matrix [25] =
{
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 1, MIN_BLUR, 1, 0,
0, 1, 1, 1, 0,
0, 0 ,0, 0, 0,
};
static gfloat sharpen_matrix [25] =
{
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 1, MIN_SHARPEN, 1, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
};
static GimpPaintToolClass *parent_class;
@ -212,55 +127,31 @@ gimp_convolve_tool_get_type (void)
static void
gimp_convolve_tool_class_init (GimpConvolveToolClass *klass)
{
GimpToolClass *tool_class;
GimpPaintToolClass *paint_tool_class;
GimpToolClass *tool_class;
tool_class = GIMP_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
tool_class = GIMP_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->modifier_key = gimp_convolve_tool_modifier_key;
tool_class->cursor_update = gimp_convolve_tool_cursor_update;
paint_tool_class->paint = gimp_convolve_tool_paint;
}
static void
gimp_convolve_tool_init (GimpConvolveTool *convolve)
{
GimpTool *tool;
GimpTool *tool;
GimpPaintTool *paint_tool;
tool = GIMP_TOOL (convolve);
tool = GIMP_TOOL (convolve);
paint_tool = GIMP_PAINT_TOOL (convolve);
tool->tool_cursor = GIMP_BLUR_TOOL_CURSOR;
tool->cursor_modifier = GIMP_CURSOR_MODIFIER_NONE;
tool->toggle_tool_cursor = GIMP_BLUR_TOOL_CURSOR;
tool->toggle_cursor_modifier = GIMP_CURSOR_MODIFIER_MINUS;
}
static void
gimp_convolve_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
ConvolveOptions *options;
options = (ConvolveOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
switch (state)
{
case MOTION_PAINT:
gimp_convolve_tool_motion (paint_tool,
drawable,
options->paint_options.pressure_options,
options->type,
options->rate);
break;
default:
break;
}
paint_tool->core = g_object_new (GIMP_TYPE_CONVOLVE, NULL);
}
static void
@ -308,304 +199,9 @@ gimp_convolve_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_convolve_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
ConvolveType type,
double rate)
{
TempBuf *area;
guchar *temp_data;
PixelRegion srcPR;
PixelRegion destPR;
gdouble scale;
ConvolveClipType area_hclip = CONVOLVE_NOT_CLIPPED;
ConvolveClipType area_vclip = CONVOLVE_NOT_CLIPPED;
gint marginx = 0;
gint marginy = 0;
GimpContext *context;
if (! gimp_drawable_gimage (drawable))
return;
#if 0
/* If the image type is indexed, don't convolve */
if (gimp_drawable_is_indexed (drawable))
return;
/* If the brush is smaller than the convolution matrix, don't convolve */
if ((paint_tool->brush->mask->width < matrix_size) ||
(paint_tool->brush->mask->height < matrix_size))
return;
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
/* Get image region around current brush (mask bbox + 1 pixel) */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
/* configure the source pixel region */
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
area->x, area->y, area->width, area->height, FALSE);
/* Configure the destination pixel region - a paint_core TempBuf */
destPR.bytes = area->bytes;
destPR.tiles = NULL;
destPR.x = 0;
destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.rowstride = area->width * destPR.bytes;
destPR.data = temp_buf_data (area);
if (pressure_options->rate)
rate = rate * 2.0 * paint_tool->cur_coords.pressure;
calculate_matrix (type, rate);
/* Image region near edges? If so, paint area will be clipped */
/* with respect to brush mask + 1 pixel border (# 19285) */
if ((marginx = (gint) paint_tool->cur_coords.x - paint_tool->brush->mask->width / 2 - 1) != area->x)
area_hclip = CONVOLVE_NCLIP;
else if ((marginx = area->width - paint_tool->brush->mask->width - 2) != 0)
area_hclip = CONVOLVE_PCLIP;
if ((marginy = (gint) paint_tool->cur_coords.y - paint_tool->brush->mask->height / 2 - 1) != area->y)
area_vclip = CONVOLVE_NCLIP;
else if ((marginy = area->height - paint_tool->brush->mask->height - 2) != 0)
area_vclip = CONVOLVE_PCLIP;
/* Has the TempBuf been clipped by a canvas edge or two ? */
if ((area_hclip == CONVOLVE_NOT_CLIPPED) &&
(area_vclip == CONVOLVE_NOT_CLIPPED))
{
/* No clipping... */
/* Standard case: copy src to temp. convolve temp to dest. */
/* Brush defines pipe size and no edge adjustments are needed. */
/* If the source has no alpha, then add alpha pixels */
/* Because paint_core.c is alpha-only code. See below. */
PixelRegion tempPR;
tempPR.x = 0;
tempPR.y = 0;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.tiles = NULL;
if (! gimp_drawable_has_alpha (drawable))
{
/* note: this particular approach needlessly convolves the totally-
opaque alpha channel. A faster approach would be to keep
tempPR the same number of bytes as srcPR, and extend the
paint_core_replace_canvas API to handle non-alpha images. */
tempPR.bytes = srcPR.bytes + 1;
tempPR.rowstride = tempPR.bytes * tempPR.w;
temp_data = g_malloc (tempPR.h * tempPR.rowstride);
tempPR.data = temp_data;
add_alpha_region (&srcPR, &tempPR);
}
else
{
tempPR.bytes = srcPR.bytes;
tempPR.rowstride = tempPR.bytes * tempPR.w;
temp_data = g_malloc (tempPR.h * tempPR.rowstride);
tempPR.data = temp_data;
copy_region (&srcPR, &tempPR);
}
/* Convolve the region */
tempPR.x = 0;
tempPR.y = 0;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.data = temp_data;
convolve_region (&tempPR, &destPR, matrix, matrix_size,
matrix_divisor, GIMP_NORMAL_CONVOL);
/* Free the allocated temp space */
g_free (temp_data);
}
else
{
/* TempBuf clipping has occured on at least one edge...
* Edge case: expand area under brush margin px on near edge(s), convolve
* expanded buffers. copy src -> ovrsz1 convolve ovrsz1 -> ovrsz2
* copy-with-crop ovrsz2 -> dest
*/
PixelRegion ovrsz1PR;
PixelRegion ovrsz2PR;
guchar *ovrsz1_data = NULL;
guchar *ovrsz2_data = NULL;
guchar *fillcolor;
fillcolor = gimp_drawable_get_color_at
(drawable,
CLAMP ((gint) paint_tool->cur_coords.x,
0, gimp_drawable_width (drawable) - 1),
CLAMP ((gint) paint_tool->cur_coords.y,
0, gimp_drawable_height (drawable) - 1));
marginx *= (marginx < 0) ? -1 : 0;
marginy *= (marginy < 0) ? -1 : 0;
ovrsz2PR.x = 0;
ovrsz2PR.y = 0;
ovrsz2PR.w = area->width + marginx;
ovrsz2PR.h = area->height + marginy;
ovrsz2PR.bytes = (gimp_drawable_has_alpha (drawable))? srcPR.bytes : srcPR.bytes + 1;
ovrsz2PR.offx = 0;
ovrsz2PR.offy = 0;
ovrsz2PR.rowstride = ovrsz2PR.bytes * ovrsz2PR.w;
ovrsz2PR.tiles = NULL;
ovrsz2_data = g_malloc (ovrsz2PR.h * ovrsz2PR.rowstride);
ovrsz2PR.data = ovrsz2_data;
ovrsz1PR.x = 0;
ovrsz1PR.y = 0;
ovrsz1PR.w = area->width + marginx;
ovrsz1PR.h = area->height + marginy;
ovrsz1PR.bytes = (gimp_drawable_has_alpha (drawable))? srcPR.bytes : srcPR.bytes + 1;
ovrsz1PR.offx = 0;
ovrsz1PR.offy = 0;
ovrsz1PR.rowstride = ovrsz2PR.bytes * ovrsz2PR.w;
ovrsz1PR.tiles = NULL;
ovrsz1_data = g_malloc (ovrsz1PR.h * ovrsz1PR.rowstride);
ovrsz1PR.data = ovrsz1_data;
color_region (&ovrsz1PR, (const guchar *)fillcolor);
ovrsz1PR.x = (area_hclip == CONVOLVE_NCLIP)? marginx : 0;
ovrsz1PR.y = (area_vclip == CONVOLVE_NCLIP)? marginy : 0;
ovrsz1PR.w = area->width;
ovrsz1PR.h = area->height;
ovrsz1PR.data = ovrsz1_data + (ovrsz1PR.rowstride * ovrsz1PR.y) + (ovrsz1PR.bytes * ovrsz1PR.x);
if (! gimp_drawable_has_alpha (drawable))
add_alpha_region (&srcPR, &ovrsz1PR);
else
copy_region (&srcPR, &ovrsz1PR);
/* Convolve the region */
ovrsz1PR.x = 0;
ovrsz1PR.y = 0;
ovrsz1PR.w = area->width + marginx;
ovrsz1PR.h = area->height + marginy;
ovrsz1PR.data = ovrsz1_data;
convolve_region (&ovrsz1PR, &ovrsz2PR, matrix, matrix_size,
matrix_divisor, GIMP_NORMAL_CONVOL);
/* Crop and copy to destination */
ovrsz2PR.x = (area_hclip == CONVOLVE_NCLIP)? marginx : 0;
ovrsz2PR.y = (area_vclip == CONVOLVE_NCLIP)? marginy : 0;
ovrsz2PR.w = area->width;
ovrsz2PR.h = area->height;
ovrsz2PR.data = ovrsz2_data + (ovrsz2PR.rowstride * ovrsz2PR.y) + (ovrsz2PR.bytes * ovrsz2PR.x);
copy_region (&ovrsz2PR, &destPR);
g_free(ovrsz1_data);
g_free(ovrsz2_data);
g_free(fillcolor);
}
context = gimp_get_current_context (gimp_drawable_gimage (drawable)->gimp);
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_replace_canvas (paint_tool, drawable, OPAQUE_OPACITY,
(gint) (gimp_context_get_opacity (context) * 255),
pressure_options->pressure ? PRESSURE : SOFT,
scale, INCREMENTAL);
}
static void
calculate_matrix (ConvolveType type,
gdouble rate)
{
gfloat percent;
/* find percent of tool pressure */
percent = MIN (rate / 100.0, 1.0);
/* get the appropriate convolution matrix and size and divisor */
switch (type)
{
case BLUR_CONVOLVE:
matrix_size = 5;
blur_matrix [12] = MIN_BLUR + percent * (MAX_BLUR - MIN_BLUR);
copy_matrix (blur_matrix, custom_matrix, matrix_size);
break;
case SHARPEN_CONVOLVE:
matrix_size = 5;
sharpen_matrix [12] = MIN_SHARPEN + percent * (MAX_SHARPEN - MIN_SHARPEN);
copy_matrix (sharpen_matrix, custom_matrix, matrix_size);
break;
case CUSTOM_CONVOLVE:
matrix_size = 5;
break;
}
integer_matrix (custom_matrix, matrix, matrix_size);
matrix_divisor = sum_matrix (matrix, matrix_size);
if (!matrix_divisor)
matrix_divisor = 1;
}
static void
integer_matrix (gfloat *source,
gint *dest,
gint size)
{
gint i;
#define PRECISION 10000
for (i = 0; i < size*size; i++)
*dest++ = (gint) (*source ++ * PRECISION);
}
static void
copy_matrix (gfloat *src,
gfloat *dest,
gint size)
{
gint i;
for (i = 0; i < size*size; i++)
*dest++ = *src++;
}
static gint
sum_matrix (gint *matrix,
gint size)
{
gint sum = 0;
size *= size;
while (size --)
sum += *matrix++;
return sum;
}
#if 0 /* Leave these to the STUBs */
static gpointer
convolve_non_gui_paint_func (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
@ -676,7 +272,10 @@ convolve_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif /* 0 - non-gui functions */
#endif
/* tool options stuff */
static GimpToolOptions *
convolve_options_new (GimpToolInfo *tool_info)

View File

@ -23,14 +23,6 @@
#include "gimppainttool.h"
typedef enum
{
BLUR_CONVOLVE,
SHARPEN_CONVOLVE,
CUSTOM_CONVOLVE
} ConvolveType;
#define GIMP_TYPE_CONVOLVE_TOOL (gimp_convolve_tool_get_type ())
#define GIMP_CONVOLVE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CONVOLVE_TOOL, GimpConvolveTool))
#define GIMP_CONVOLVE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CONVOLVE_TOOL, GimpConvolveToolClass))
@ -59,15 +51,4 @@ void gimp_convolve_tool_register (Gimp *gimp,
GType gimp_convolve_tool_get_type (void) G_GNUC_CONST;
/* FIXME: These need to disappear */
gboolean convolve_non_gui (GimpDrawable *drawable,
gdouble rate,
ConvolveType type,
gint num_strokes,
gdouble *stroke_array);
gboolean convolve_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_CONVOLVE_TOOL_H__ */

View File

@ -19,117 +19,46 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/gimplut.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpdrawable.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "paint/gimpdodgeburn.h"
#include "gimpdodgeburntool.h"
#include "paint_options.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
/* Default values */
#define DODGEBURN_DEFAULT_EXPOSURE 50.0
#define DODGEBURN_DEFAULT_TYPE DODGE
#define DODGEBURN_DEFAULT_MODE GIMP_HIGHLIGHTS
/* the dodgeburn structures */
typedef struct _DodgeBurnOptions DodgeBurnOptions;
static void gimp_dodgeburn_tool_class_init (GimpDodgeBurnToolClass *klass);
static void gimp_dodgeburn_tool_init (GimpDodgeBurnTool *dodgeburn);
struct _DodgeBurnOptions
{
PaintOptions paint_options;
DodgeBurnType type;
DodgeBurnType type_d;
GtkWidget *type_w[2];
GimpTransferMode mode; /*highlights, midtones, shadows*/
GimpTransferMode mode_d;
GtkWidget *mode_w[3];
gdouble exposure;
gdouble exposure_d;
GtkObject *exposure_w;
GimpLut *lut;
};
static void gimp_dodgeburn_tool_class_init (GimpDodgeBurnToolClass *klass);
static void gimp_dodgeburn_tool_init (GimpDodgeBurnTool *dodgeburn);
static void gimp_dodgeburn_tool_make_luts (GimpPaintTool *paint_tool,
gdouble db_exposure,
DodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable);
static void gimp_dodgeburn_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_dodgeburn_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_dodgeburn_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gdouble dodgeburn_exposure,
GimpLut *lut);
static gfloat gimp_dodgeburn_tool_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_tool_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static gfloat gimp_dodgeburn_tool_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value);
static void gimp_dodgeburn_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_dodgeburn_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static GimpToolOptions * gimp_dodgeburn_tool_options_new (GimpToolInfo *tool_info);
static void gimp_dodgeburn_tool_options_reset (GimpToolOptions *tool_options);
static gdouble non_gui_exposure;
static GimpLut *non_gui_lut;
static GimpPaintToolClass *parent_class = NULL;
/* functions */
void
gimp_dodgeburn_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
@ -177,18 +106,14 @@ gimp_dodgeburn_tool_get_type (void)
static void
gimp_dodgeburn_tool_class_init (GimpDodgeBurnToolClass *klass)
{
GimpToolClass *tool_class;
GimpPaintToolClass *paint_tool_class;
GimpToolClass *tool_class;
tool_class = GIMP_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
tool_class = GIMP_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->modifier_key = gimp_dodgeburn_tool_modifier_key;
tool_class->cursor_update = gimp_dodgeburn_tool_cursor_update;
paint_tool_class->paint = gimp_dodgeburn_tool_paint;
}
static void
@ -203,46 +128,7 @@ gimp_dodgeburn_tool_init (GimpDodgeBurnTool *dodgeburn)
tool->tool_cursor = GIMP_DODGE_TOOL_CURSOR;
tool->toggle_tool_cursor = GIMP_BURN_TOOL_CURSOR;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_dodgeburn_tool_make_luts (GimpPaintTool *paint_tool,
gdouble db_exposure,
DodgeBurnType type,
GimpTransferMode mode,
GimpLut *lut,
GimpDrawable *drawable)
{
GimpLutFunc lut_func;
gint nchannels = gimp_drawable_bytes (drawable);
static gfloat exposure;
exposure = db_exposure / 100.0;
/* make the exposure negative if burn for luts*/
if (type == BURN)
exposure = -exposure;
switch (mode)
{
case GIMP_HIGHLIGHTS:
lut_func = gimp_dodgeburn_tool_highlights_lut_func;
break;
case GIMP_MIDTONES:
lut_func = gimp_dodgeburn_tool_midtones_lut_func;
break;
case GIMP_SHADOWS:
lut_func = gimp_dodgeburn_tool_shadows_lut_func;
break;
default:
lut_func = NULL;
break;
}
gimp_lut_setup_exact (lut,
lut_func, (gpointer) &exposure,
nchannels);
paint_tool->core = g_object_new (GIMP_TYPE_DODGEBURN, NULL);
}
static void
@ -292,244 +178,8 @@ gimp_dodgeburn_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_dodgeburn_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
DodgeBurnOptions *options;
PaintPressureOptions *pressure_options;
gdouble exposure;
GimpLut *lut;
options = (DodgeBurnOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
exposure = options->exposure;
lut = options->lut;
}
else
{
pressure_options = &non_gui_pressure_options;
exposure = non_gui_exposure;
lut = non_gui_lut;
}
switch (state)
{
case INIT_PAINT:
if (options)
{
options->lut = gimp_lut_new ();
gimp_dodgeburn_tool_make_luts (paint_tool,
options->exposure,
options->type,
options->mode,
options->lut,
drawable);
lut = options->lut;
}
break;
case MOTION_PAINT:
gimp_dodgeburn_tool_motion (paint_tool,
drawable,
pressure_options,
exposure,
lut);
break;
case FINISH_PAINT:
if (options && options->lut)
{
gimp_lut_free (options->lut);
options->lut = NULL;
}
break;
default:
break;
}
}
static void
gimp_dodgeburn_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
double dodgeburn_exposure,
GimpLut *lut)
{
GimpImage *gimage;
TempBuf *area;
TempBuf *orig;
PixelRegion srcPR, destPR, tempPR;
guchar *temp_data;
gint opacity;
gdouble scale;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
/* If the image type is indexed, don't dodgeburn */
if ((gimp_drawable_type (drawable) == GIMP_INDEXED_IMAGE) ||
(gimp_drawable_type (drawable) == GIMP_INDEXEDA_IMAGE))
return;
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
/* Constant painting --get a copy of the orig drawable (with no
* paint from this stroke yet)
*/
{
gint x1, y1, x2, y2;
x1 = CLAMP (area->x, 0, gimp_drawable_width (drawable));
y1 = CLAMP (area->y, 0, gimp_drawable_height (drawable));
x2 = CLAMP (area->x + area->width, 0, gimp_drawable_width (drawable));
y2 = CLAMP (area->y + area->height, 0, gimp_drawable_height (drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
/* get the original untouched image */
orig = gimp_paint_tool_get_orig_image (paint_tool, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0;
srcPR.y = 0;
srcPR.w = x2 - x1;
srcPR.h = y2 - y1;
srcPR.rowstride = srcPR.bytes * orig->width;
srcPR.data = temp_buf_data (orig);
}
/* tempPR will hold the dodgeburned region*/
tempPR.bytes = srcPR.bytes;
tempPR.x = srcPR.x;
tempPR.y = srcPR.y;
tempPR.w = srcPR.w;
tempPR.h = srcPR.h;
tempPR.rowstride = tempPR.bytes * tempPR.w;
temp_data = g_malloc (tempPR.h * tempPR.rowstride);
tempPR.data = temp_data;
/* DodgeBurn the region */
gimp_lut_process (lut, &srcPR, &tempPR);
/* The dest is the paint area we got above (= canvas_buf) */
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.rowstride = area->width * destPR.bytes;
destPR.data = temp_buf_data (area);
/* Now add an alpha to the dodgeburned region
and put this in area = canvas_buf */
if (! gimp_drawable_has_alpha (drawable))
add_alpha_region (&tempPR, &destPR);
else
copy_region (&tempPR, &destPR);
opacity =
255 * gimp_context_get_opacity (gimp_get_current_context (gimage->gimp));
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
/* Replace the newly dodgedburned area (canvas_buf) to the gimage*/
gimp_paint_tool_replace_canvas (paint_tool, drawable,
MIN (opacity, 255),
OPAQUE_OPACITY,
pressure_options->pressure ? PRESSURE : SOFT,
scale, CONSTANT);
g_free (temp_data);
}
static gfloat
gimp_dodgeburn_tool_highlights_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
gfloat exposure = *exposure_ptr;
gfloat factor = 1.0 + exposure * (.333333);
if ((nchannels == 2 && channel == 1) ||
(nchannels == 4 && channel == 3))
return value;
return factor * value;
}
static gfloat
gimp_dodgeburn_tool_midtones_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
gfloat exposure = *exposure_ptr;
gfloat factor;
if ((nchannels == 2 && channel == 1) ||
(nchannels == 4 && channel == 3))
return value;
if (exposure < 0)
factor = 1.0 - exposure * (.333333);
else
factor = 1/(1.0 + exposure);
return pow (value, factor);
}
static gfloat
gimp_dodgeburn_tool_shadows_lut_func (gpointer user_data,
gint nchannels,
gint channel,
gfloat value)
{
gfloat *exposure_ptr = (gfloat *) user_data;
gfloat exposure = *exposure_ptr;
gfloat new_value;
gfloat factor;
if ((nchannels == 2 && channel == 1) ||
(nchannels == 4 && channel == 3))
return value;
if (exposure >= 0)
{
factor = 0.333333 * exposure;
new_value = factor + value - factor * value;
}
else /* exposure < 0 */
{
factor = -0.333333 * exposure;
if (value < factor)
new_value = 0;
else /*factor <= value <=1*/
new_value = (value - factor)/(1 - factor);
}
return new_value;
}
/* non-gui stuff */
#if 0
gboolean
gimp_dodgeburn_tool_non_gui_default (GimpDrawable *drawable,
@ -618,6 +268,8 @@ gimp_dodgeburn_tool_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif
/* tool options stuff */

View File

@ -23,13 +23,6 @@
#include "gimppainttool.h"
typedef enum
{
DODGE,
BURN
} DodgeBurnType;
#define GIMP_TYPE_DODGEBURN_TOOL (gimp_dodgeburn_tool_get_type ())
#define GIMP_DODGEBURN_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DODGEBURN_TOOL, GimpDodgeBurnTool))
#define GIMP_IS_DODGEBURN_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DODGEBURN_TOOL))
@ -57,16 +50,4 @@ void gimp_dodgeburn_tool_register (Gimp *gimp,
GType gimp_dodgeburn_tool_get_type (void) G_GNUC_CONST;
gboolean gimp_dodgeburn_tool_non_gui (GimpDrawable *drawable,
gdouble exposure,
DodgeBurnType type,
GimpTransferMode mode,
gint num_strokes,
gdouble *stroke_array);
gboolean gimp_dodgeburn_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_DODGEBURN_TOOL_H__ */

View File

@ -19,26 +19,17 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "paint/gimperaser.h"
#include "gimperasertool.h"
#include "paint_options.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
@ -48,22 +39,6 @@
#define ERASER_DEFAULT_ANTI_ERASE FALSE
typedef struct _EraserOptions EraserOptions;
struct _EraserOptions
{
PaintOptions paint_options;
gboolean hard;
gboolean hard_d;
GtkWidget *hard_w;
gboolean anti_erase;
gboolean anti_erase_d;
GtkWidget *anti_erase_w;
};
static void gimp_eraser_tool_class_init (GimpEraserToolClass *klass);
static void gimp_eraser_tool_init (GimpEraserTool *eraser);
@ -77,31 +52,13 @@ static void gimp_eraser_tool_cursor_update (GimpTool *tool,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_eraser_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_eraser_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean hard,
gboolean incremental,
gboolean anti_erase);
static GimpToolOptions * gimp_eraser_tool_options_new (GimpToolInfo *tool_info);
static void gimp_eraser_tool_options_reset (GimpToolOptions *tool_options);
/* local variables */
static gboolean non_gui_hard = ERASER_DEFAULT_HARD;
static gboolean non_gui_incremental = ERASER_DEFAULT_INCREMENTAL;
static gboolean non_gui_anti_erase = ERASER_DEFAULT_ANTI_ERASE;
static GimpPaintToolClass *parent_class = NULL;
/* functions */
void
gimp_eraser_tool_register (Gimp *gimp,
GimpToolRegisterCallback callback)
@ -149,18 +106,14 @@ gimp_eraser_tool_get_type (void)
static void
gimp_eraser_tool_class_init (GimpEraserToolClass *klass)
{
GimpToolClass *tool_class;
GimpPaintToolClass *paint_tool_class;
GimpToolClass *tool_class;
tool_class = GIMP_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
tool_class = GIMP_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->modifier_key = gimp_eraser_tool_modifier_key;
tool_class->cursor_update = gimp_eraser_tool_cursor_update;
paint_tool_class->paint = gimp_eraser_tool_paint;
}
static void
@ -177,7 +130,7 @@ gimp_eraser_tool_init (GimpEraserTool *eraser)
tool->toggle_tool_cursor = GIMP_ERASER_TOOL_CURSOR;
tool->toggle_cursor_modifier = GIMP_CURSOR_MODIFIER_MINUS;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_tool->core = g_object_new (GIMP_TYPE_ERASER, NULL);
}
static void
@ -214,112 +167,8 @@ gimp_eraser_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_eraser_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
EraserOptions *options;
PaintPressureOptions *pressure_options;
gboolean hard;
gboolean incremental;
gboolean anti_erase;
options = (EraserOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (options)
{
pressure_options = options->paint_options.pressure_options;
hard = options->hard;
incremental = options->paint_options.incremental;
anti_erase = options->anti_erase;
}
else
{
pressure_options = &non_gui_pressure_options;
hard = non_gui_hard;
incremental = non_gui_incremental;
anti_erase = non_gui_anti_erase;
}
switch (state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
gimp_eraser_tool_motion (paint_tool,
drawable,
pressure_options,
hard,
incremental,
anti_erase);
break;
case FINISH_PAINT:
break;
default:
break;
}
}
static void
gimp_eraser_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean hard,
gboolean incremental,
gboolean anti_erase)
{
GimpImage *gimage;
GimpContext *context;
gint opacity;
TempBuf *area;
guchar col[MAX_CHANNELS];
gdouble scale;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
gimp_image_get_background (gimage, drawable, col);
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
/* set the alpha channel */
col[area->bytes - 1] = OPAQUE_OPACITY;
/* color the pixels */
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
opacity = 255 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being
* worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
MIN (opacity, 255),
gimp_context_get_opacity (context) * 255,
anti_erase ? GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE,
hard ? HARD : (pressure_options->pressure ? PRESSURE : SOFT),
scale,
incremental ? INCREMENTAL : CONSTANT);
}
/* non-gui stuff */
#if 0
gboolean
eraser_non_gui_default (GimpDrawable *drawable,
@ -400,6 +249,8 @@ eraser_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif
/* tool options stuff */

View File

@ -51,15 +51,4 @@ void gimp_eraser_tool_register (Gimp *gimp,
GType gimp_eraser_tool_get_type (void) G_GNUC_CONST;
gboolean eraser_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array,
gint hardness,
gint method,
gboolean anti_erase);
gboolean eraser_non_gui_default (GimpDrawable *paint_core,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_ERASER_TOOL_H__ */

View File

@ -20,24 +20,11 @@
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpbase/gimpbase.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "paint/gimppaintbrush.h"
#include "gimppaintbrushtool.h"
#include "paint_options.h"
@ -52,22 +39,6 @@
static void gimp_paintbrush_tool_class_init (GimpPaintbrushToolClass *klass);
static void gimp_paintbrush_tool_init (GimpPaintbrushTool *tool);
static void gimp_paintbrush_tool_paint (GimpPaintTool *paint_core,
GimpDrawable *drawable,
PaintState state);
static void gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
PaintGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GradientPaintMode gradient_type);
/* local variables */
static gboolean non_gui_incremental = PAINTBRUSH_DEFAULT_INCREMENTAL;
static GimpPaintToolClass *parent_class = NULL;
@ -129,8 +100,6 @@ gimp_paintbrush_tool_class_init (GimpPaintbrushToolClass *klass)
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
paint_tool_class->paint = gimp_paintbrush_tool_paint;
}
static void
@ -142,225 +111,14 @@ gimp_paintbrush_tool_init (GimpPaintbrushTool *paintbrush)
tool = GIMP_TOOL (paintbrush);
paint_tool = GIMP_PAINT_TOOL (paintbrush);
tool->tool_cursor = GIMP_PAINTBRUSH_TOOL_CURSOR;
tool->tool_cursor = GIMP_PAINTBRUSH_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_paintbrush_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
PaintOptions *paint_options;
PaintPressureOptions *pressure_options;
PaintGradientOptions *gradient_options;
gboolean incremental;
GimpImage *gimage;
gdouble fade_out;
gdouble gradient_length;
gdouble unit_factor;
gimage = gimp_drawable_gimage (drawable);
g_return_if_fail (gimage != NULL);
if (! gimage)
return;
paint_options = (PaintOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (paint_options)
{
pressure_options = paint_options->pressure_options;
gradient_options = paint_options->gradient_options;
incremental = paint_options->incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
gradient_options = &non_gui_gradient_options;
incremental = non_gui_incremental;
}
switch (state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
switch (gradient_options->fade_unit)
{
case GIMP_UNIT_PIXEL:
fade_out = gradient_options->fade_out;
break;
case GIMP_UNIT_PERCENT:
fade_out = (MAX (gimage->width, gimage->height) *
gradient_options->fade_out / 100);
break;
default:
unit_factor = gimp_unit_get_factor (gradient_options->fade_unit);
fade_out = (gradient_options->fade_out *
MAX (gimage->xresolution,
gimage->yresolution) / unit_factor);
break;
}
switch (gradient_options->gradient_unit)
{
case GIMP_UNIT_PIXEL:
gradient_length = gradient_options->gradient_length;
break;
case GIMP_UNIT_PERCENT:
gradient_length = (MAX (gimage->width, gimage->height) *
gradient_options->gradient_length / 100);
break;
default:
unit_factor = gimp_unit_get_factor (gradient_options->gradient_unit);
gradient_length = (gradient_options->gradient_length *
MAX (gimage->xresolution,
gimage->yresolution) / unit_factor);
break;
}
gimp_paintbrush_tool_motion (paint_tool, drawable,
pressure_options,
gradient_options,
gradient_options->use_fade ? fade_out : 0,
gradient_options->use_gradient ? gradient_length : 0,
incremental,
gradient_options->gradient_type);
break;
case FINISH_PAINT:
break;
default:
break;
}
}
static void
gimp_paintbrush_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
PaintGradientOptions *gradient_options,
gdouble fade_out,
gdouble gradient_length,
gboolean incremental,
GradientPaintMode gradient_type)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
gdouble x, paint_left;
guchar local_blend = OPAQUE_OPACITY;
guchar temp_blend = OPAQUE_OPACITY;
guchar col[MAX_CHANNELS];
GimpRGB color;
gint mode;
gint opacity;
gdouble scale;
PaintApplicationMode paint_appl_mode = incremental ? INCREMENTAL : CONSTANT;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
if (pressure_options->color)
gradient_length = 1.0; /* not really used, only for if cases */
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
/* factor in the fade out value */
if (fade_out)
{
/* Model the amount of paint left as a gaussian curve */
x = ((double) paint_tool->pixel_dist / fade_out);
paint_left = exp (- x * x * 5.541); /* ln (1/255) */
local_blend = (int) (255 * paint_left);
}
if (local_blend)
{
/* set the alpha channel */
temp_blend = local_blend;
mode = gradient_type;
if (gradient_length)
{
GimpGradient *gradient;
gradient = gimp_context_get_gradient (context);
if (pressure_options->color)
gimp_gradient_get_color_at (gradient,
paint_tool->cur_coords.pressure,
&color);
else
gimp_paint_tool_get_color_from_gradient (paint_tool,
gradient,
gradient_length,
&color,
mode);
temp_blend = (gint) ((color.a * local_blend));
gimp_rgb_get_uchar (&color,
&col[RED_PIX],
&col[GREEN_PIX],
&col[BLUE_PIX]);
col[ALPHA_PIX] = OPAQUE_OPACITY;
/* always use incremental mode with gradients */
/* make the gui cool later */
paint_appl_mode = INCREMENTAL;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
/* we check to see if this is a pixmap, if so composite the
* pixmap image into the area instead of the color
*/
else if (paint_tool->brush && paint_tool->brush->pixmap)
{
gimp_paint_tool_color_area_with_pixmap (paint_tool, gimage, drawable,
area,
scale, SOFT);
paint_appl_mode = INCREMENTAL;
}
else
{
gimp_image_get_foreground (gimage, drawable, col);
col[area->bytes - 1] = OPAQUE_OPACITY;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
opacity = (gdouble) temp_blend;
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
gimp_paint_tool_paste_canvas (paint_tool, drawable,
MIN (opacity, 255),
gimp_context_get_opacity (context) * 255,
gimp_context_get_paint_mode (context),
pressure_options->pressure ? PRESSURE : SOFT,
scale, paint_appl_mode);
}
paint_tool->pick_colors = TRUE;
paint_tool->core = g_object_new (GIMP_TYPE_PAINTBRUSH, NULL);
}
/* non-gui stuff */
#if 0
static GimpPaintbrushTool *non_gui_paintbrush = NULL;
@ -461,3 +219,5 @@ gimp_paintbrush_tool_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif

View File

@ -51,15 +51,4 @@ void gimp_paintbrush_tool_register (Gimp *gimp,
GType gimp_paintbrush_tool_get_type (void) G_GNUC_CONST;
gboolean gimp_paintbrush_tool_non_gui (GimpDrawable *drawable,
gint num_srokes,
gdouble *stroke_array,
gdouble fade_out,
gint incremental,
gdouble gradient_length);
gboolean gimp_paintbrush_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_PAINTBRUSH_TOOL_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -23,37 +23,6 @@
#include "gimpdrawtool.h"
#define PAINT_TOOL_SUBSAMPLE 4
/* the different states that the painting function can be called with */
typedef enum /*< pdb-skip >*/
{
INIT_PAINT, /* Setup PaintFunc internals */
MOTION_PAINT, /* PaintFunc performs motion-related rendering */
PAUSE_PAINT, /* Unused. Reserved */
RESUME_PAINT, /* Unused. Reserved */
FINISH_PAINT, /* Cleanup and/or reset PaintFunc operation */
PRETRACE_PAINT, /* PaintFunc performs window tracing activity prior to rendering */
POSTTRACE_PAINT /* PaintFunc performs window tracing activity following rendering */
} PaintState;
typedef enum /*< pdb-skip >*/
{
TOOL_CAN_HANDLE_CHANGING_BRUSH = 0x0001, /* Set for tools that don't mind
* if the brush changes while
* painting.
*/
TOOL_TRACES_ON_WINDOW /* Set for tools that perform temporary
* rendering directly to the window. These
* require sequencing with gdisplay_flush()
* routines. See clone.c for example.
*/
} ToolFlags;
#define GIMP_TYPE_PAINT_TOOL (gimp_paint_tool_get_type ())
#define GIMP_PAINT_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINT_TOOL, GimpPaintTool))
#define GIMP_PAINT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PAINT_TOOL, GimpPaintToolClass))
@ -66,126 +35,22 @@ typedef struct _GimpPaintToolClass GimpPaintToolClass;
struct _GimpPaintTool
{
GimpDrawTool parent_instance;
GimpDrawTool parent_instance;
GimpCoords start_coords; /* starting coords */
GimpCoords cur_coords; /* current coords */
GimpCoords last_coords; /* last coords */
GdkModifierType state; /* state of buttons and keys */
gboolean pick_colors; /* pick color if ctrl or alt is pressed */
gboolean pick_state; /* was ctrl or alt pressed when clicked? */
gint state; /* state of buttons and keys */
gdouble distance; /* distance traveled by brush */
gdouble pixel_dist; /* distance in pixels */
gdouble spacing; /* spacing */
gint x1, y1; /* image space coordinate */
gint x2, y2; /* image space coords */
GimpBrush *brush; /* current brush */
gboolean pick_colors; /* pick color if ctrl or alt is pressed */
gboolean pick_state; /* was ctrl or alt pressed when clicked? */
ToolFlags flags; /* tool flags, see ToolFlags above */
/* undo blocks variables */
TileManager *undo_tiles;
TileManager *canvas_tiles;
/* paint buffers variables */
TempBuf *orig_buf;
TempBuf *canvas_buf;
/* brush buffers */
MaskBuf *pressure_brush;
MaskBuf *solid_brush;
MaskBuf *scale_brush;
MaskBuf *scale_pixmap;
MaskBuf *kernel_brushes[PAINT_TOOL_SUBSAMPLE + 1][PAINT_TOOL_SUBSAMPLE + 1];
MaskBuf *last_brush_mask;
gboolean cache_invalid;
/* don't use this one... */
GimpBrush *grr_brush;
GimpPaintCore *core;
};
struct _GimpPaintToolClass
{
GimpDrawToolClass parent_class;
/* virtual function */
void (* paint) (GimpPaintTool *tool,
GimpDrawable *drawable,
PaintState paint_state);
};
/* Special undo type */
typedef struct _PaintUndo PaintUndo;
struct _PaintUndo
{
gint tool_ID;
GType tool_type;
GimpCoords last_coords;
};
GType gimp_paint_tool_get_type (void) G_GNUC_CONST;
void gimp_paint_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
int gimp_paint_tool_start (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gdouble x,
gdouble y);
void gimp_paint_tool_interpolate (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
void gimp_paint_tool_finish (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
void gimp_paint_tool_cleanup (GimpPaintTool *paint_tool);
void gimp_paint_tool_get_color_from_gradient (GimpPaintTool *paint_tool,
GimpGradient *gradient,
gdouble gradient_length,
GimpRGB *color,
GradientPaintMode mode);
/* paint tool painting functions */
TempBuf * gimp_paint_tool_get_paint_area (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gdouble scale);
TempBuf * gimp_paint_tool_get_orig_image (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gint x1,
gint y1,
gint x2,
gint y2);
void gimp_paint_tool_paste_canvas (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gint brush_opacity,
gint image_opacity,
GimpLayerModeEffects paint_mode,
BrushApplicationMode brush_hardness,
gdouble brush_scale,
PaintApplicationMode mode);
void gimp_paint_tool_replace_canvas (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
gint brush_opacity,
gint image_opacity,
BrushApplicationMode brush_hardness,
gdouble brush_scale,
PaintApplicationMode mode);
void gimp_paint_tool_color_area_with_pixmap (GimpPaintTool *paint_tool,
GimpImage *dest,
GimpDrawable *drawable,
TempBuf *area,
gdouble scale,
BrushApplicationMode mode);
GType gimp_paint_tool_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_PAINT_TOOL_H__ */

View File

@ -20,22 +20,11 @@
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpgradient.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "paint/gimppencil.h"
#include "gimppenciltool.h"
#include "paint_options.h"
@ -43,23 +32,9 @@
#include "libgimp/gimpintl.h"
#define PENCIL_INCREMENTAL_DEFAULT FALSE
static void gimp_pencil_tool_class_init (GimpPencilToolClass *klass);
static void gimp_pencil_tool_init (GimpPencilTool *pancil);
static void gimp_pencil_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_pencil_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean incremental);
/* private variables */
static gboolean non_gui_incremental = PENCIL_INCREMENTAL_DEFAULT;
static GimpPaintToolClass *parent_class = NULL;
@ -118,8 +93,6 @@ gimp_pencil_tool_class_init (GimpPencilToolClass *klass)
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
paint_tool_class->paint = gimp_pencil_tool_paint;
}
static void
@ -131,125 +104,13 @@ gimp_pencil_tool_init (GimpPencilTool *pencil)
tool = GIMP_TOOL (pencil);
paint_tool = GIMP_PAINT_TOOL (pencil);
tool->tool_cursor = GIMP_PENCIL_TOOL_CURSOR;
tool->tool_cursor = GIMP_PENCIL_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
}
static void
gimp_pencil_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
PaintOptions *paint_options;
PaintPressureOptions *pressure_options;
gboolean incremental;
paint_options = (PaintOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
if (paint_options)
{
pressure_options = paint_options->pressure_options;
incremental = paint_options->incremental;
}
else
{
pressure_options = &non_gui_pressure_options;
incremental = non_gui_incremental;
}
switch (state)
{
case INIT_PAINT:
break;
case MOTION_PAINT:
gimp_pencil_tool_motion (paint_tool, drawable,
pressure_options, incremental);
break;
case FINISH_PAINT:
break;
default:
break;
}
}
static void
gimp_pencil_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintPressureOptions *pressure_options,
gboolean incremental)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
guchar col[MAX_CHANNELS];
gint opacity;
gdouble scale;
PaintApplicationMode paint_appl_mode = incremental ? INCREMENTAL : CONSTANT;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
/* color the pixels */
if (pressure_options->color)
{
GimpRGB color;
gimp_gradient_get_color_at (gimp_context_get_gradient (context),
paint_tool->cur_coords.pressure, &color);
gimp_rgba_get_uchar (&color,
&col[RED_PIX],
&col[GREEN_PIX],
&col[BLUE_PIX],
&col[ALPHA_PIX]);
paint_appl_mode = INCREMENTAL;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (paint_tool->brush && paint_tool->brush->pixmap)
{
/* if its a pixmap, do pixmap stuff */
gimp_paint_tool_color_area_with_pixmap (paint_tool, gimage, drawable,
area, scale, HARD);
paint_appl_mode = INCREMENTAL;
}
else
{
gimp_image_get_foreground (gimage, drawable, col);
col[area->bytes - 1] = OPAQUE_OPACITY;
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
opacity = 255 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
MIN (opacity, 255),
gimp_context_get_opacity (context) * 255,
gimp_context_get_paint_mode (context),
HARD, scale, paint_appl_mode);
paint_tool->pick_colors = TRUE;
paint_tool->core = g_object_new (GIMP_TYPE_PENCIL, NULL);
}
#if 0
/* non-gui stuff */
@ -258,42 +119,45 @@ pencil_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array)
{
static GimpPencilTool *non_gui_pencil = NULL;
static GimpPencil *non_gui_pencil = NULL;
GimpPaintTool *paint_tool;
GimpPaintCore *core;
gint i;
if (! non_gui_pencil)
{
non_gui_pencil = g_object_new (GIMP_TYPE_PENCIL_TOOL, NULL);
non_gui_pencil = g_object_new (GIMP_TYPE_PENCIL, NULL);
}
paint_tool = GIMP_PAINT_TOOL (non_gui_pencil);
if (gimp_paint_tool_start (paint_tool, drawable,
core = GIMP_PAINT_CORE (non_gui_pencil);
if (gimp_paint_core_start (core,
drawable,
stroke_array[0],
stroke_array[1]))
{
paint_tool->start_coords.x = paint_tool->last_coords.x = stroke_array[0];
paint_tool->start_coords.y = paint_tool->last_coords.y = stroke_array[1];
core->start_coords.x = core->last_coords.x = stroke_array[0];
core->start_coords.y = core->last_coords.y = stroke_array[1];
gimp_pencil_tool_paint (paint_tool, drawable, MOTION_PAINT);
gimp_paint_core_paint (core, drawable, NULL, MOTION_PAINT);
for (i = 1; i < num_strokes; i++)
{
paint_tool->cur_coords.x = stroke_array[i * 2 + 0];
paint_tool->cur_coords.y = stroke_array[i * 2 + 1];
core->cur_coords.x = stroke_array[i * 2 + 0];
core->cur_coords.y = stroke_array[i * 2 + 1];
gimp_paint_tool_interpolate (paint_tool, drawable);
gimp_paint_core_interpolate (core, drawable);
paint_tool->last_coords.x = paint_tool->cur_coords.x;
paint_tool->last_coords.y = paint_tool->cur_coords.y;
core->last_coords.x = core->cur_coords.x;
core->last_coords.y = core->cur_coords.y;
}
gimp_paint_tool_finish (paint_tool, drawable);
gimp_paint_core_finish (core, drawable);
return TRUE;
}
return FALSE;
}
#endif

View File

@ -34,6 +34,7 @@
#define GIMP_IS_PENCIL_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PENCIL_TOOL))
#define GIMP_PENCIL_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PENCIL_TOOL, GimpPencilToolClass))
typedef struct _GimpPencilTool GimpPencilTool;
typedef struct _GimpPencilToolClass GimpPencilToolClass;
@ -54,13 +55,4 @@ void gimp_pencil_tool_register (Gimp *gimp,
GType gimp_pencil_tool_get_type (void) G_GNUC_CONST;
/* FIXME: Get rid of this non_gui stuff someday. Preferably make
* everything use it interally for ease of macro recording.
*/
gboolean pencil_non_gui (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_PENCIL_TOOL_H__ */

View File

@ -19,85 +19,30 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "paint/gimpsmudge.h"
#include "gimpsmudgetool.h"
#include "paint_options.h"
#include "tool_manager.h"
#include "libgimp/gimpintl.h"
/* default defines */
#define SMUDGE_DEFAULT_RATE 50.0
/* the smudge structures */
typedef struct _SmudgeOptions SmudgeOptions;
struct _SmudgeOptions
{
PaintOptions paint_options;
gdouble rate;
gdouble rate_d;
GtkObject *rate_w;
};
#define SMUDGE_DEFAULT_RATE 50.0
/* function prototypes */
static void gimp_smudge_tool_class_init (GimpSmudgeToolClass *klass);
static void gimp_smudge_tool_init (GimpSmudgeTool *tool);
static void gimp_smudge_tool_class_init (GimpSmudgeToolClass *klass);
static void gimp_smudge_tool_init (GimpSmudgeTool *tool);
static void gimp_smudge_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_smudge_tool_motion (GimpPaintTool *paint_tool,
PaintPressureOptions *pressure_options,
gdouble smudge_rate,
GimpDrawable *drawable);
static gboolean gimp_smudge_tool_start (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
static void gimp_smudge_tool_finish (GimpPaintTool *paint_tool,
GimpDrawable *drawable);
static GimpToolOptions * smudge_options_new (GimpToolInfo *tool_info);
static void smudge_options_reset (GimpToolOptions *tool_options);
static void gimp_smudge_tool_nonclipped_painthit_coords (GimpPaintTool *paint_tool,
gint *x,
gint *y,
gint *w,
gint *h);
static void gimp_smudge_tool_allocate_accum_buffer (gint w,
gint h,
gint bytes,
guchar *do_fill);
static GimpToolOptions * smudge_options_new (GimpToolInfo *tool_info);
static void smudge_options_reset (GimpToolOptions *tool_options);
/* local variables */
static PixelRegion accumPR;
static guchar *accum_data = NULL;
static gdouble non_gui_rate;
static GimpPaintToolClass *parent_class = NULL;
@ -156,8 +101,6 @@ gimp_smudge_tool_class_init (GimpSmudgeToolClass *klass)
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
paint_tool_class->paint = gimp_smudge_tool_paint;
}
static void
@ -169,278 +112,14 @@ gimp_smudge_tool_init (GimpSmudgeTool *smudge)
tool = GIMP_TOOL (smudge);
paint_tool = GIMP_PAINT_TOOL (smudge);
tool->tool_cursor = GIMP_SMUDGE_TOOL_CURSOR;
tool->tool_cursor = GIMP_SMUDGE_TOOL_CURSOR;
paint_tool->pick_colors = TRUE;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_tool->pick_colors = TRUE;
paint_tool->core = g_object_new (GIMP_TYPE_SMUDGE, NULL);
}
static void
gimp_smudge_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
SmudgeOptions *options;
/* initialization fails if the user starts outside the drawable */
static gboolean initialized = FALSE;
options = (SmudgeOptions *) GIMP_TOOL (paint_tool)->tool_info->tool_options;
switch (state)
{
case MOTION_PAINT:
if (! initialized)
initialized = gimp_smudge_tool_start (paint_tool, drawable);
if (initialized)
gimp_smudge_tool_motion (paint_tool,
options->paint_options.pressure_options,
options->rate,
drawable);
break;
case FINISH_PAINT:
gimp_smudge_tool_finish (paint_tool, drawable);
initialized = FALSE;
break;
default:
break;
}
return;
}
static void
gimp_smudge_tool_finish (GimpPaintTool *paint_tool,
GimpDrawable *drawable)
{
if (accum_data)
{
g_free (accum_data);
accum_data = NULL;
}
}
static void
gimp_smudge_tool_nonclipped_painthit_coords (GimpPaintTool *paint_tool,
gint *x,
gint *y,
gint *w,
gint *h)
{
/* Note: these are the brush mask size plus a border of 1 pixel */
*x = (gint) paint_tool->cur_coords.x - paint_tool->brush->mask->width/2 - 1;
*y = (gint) paint_tool->cur_coords.y - paint_tool->brush->mask->height/2 - 1;
*w = paint_tool->brush->mask->width + 2;
*h = paint_tool->brush->mask->height + 2;
}
static gboolean
gimp_smudge_tool_start (GimpPaintTool *paint_tool,
GimpDrawable *drawable)
{
GimpImage *gimage;
TempBuf *area;
PixelRegion srcPR;
gint x, y, w, h;
gint was_clipped;
guchar *do_fill = NULL;
if (! (gimage = gimp_drawable_gimage (drawable)))
return FALSE;
/* If the image type is indexed, don't smudge */
if (gimp_drawable_is_indexed (drawable))
return FALSE;
area = gimp_paint_tool_get_paint_area (paint_tool, drawable, 1.0);
if (!area)
return FALSE;
/* adjust the x and y coordinates to the upper left corner of the brush */
gimp_smudge_tool_nonclipped_painthit_coords (paint_tool, &x, &y, &w, &h);
if (x != area->x || y != area->y || w != area->width || h != area->height)
was_clipped = TRUE;
else
was_clipped = FALSE;
/* When clipped, accum_data may contain pixels that map to
off-canvas pixels of the under-the-brush image, particulary
when the brush image contains an edge or corner of the
image. These off-canvas pixels are not a part of the current
composite, but may be composited in later generations. do_fill
contains a copy of the color of the pixel at the center of the
brush; assumed this is a reasonable choice for off- canvas pixels
that may enter into the blend */
if (was_clipped)
do_fill = gimp_drawable_get_color_at (drawable,
CLAMP ((gint) paint_tool->cur_coords.x,
0, gimp_drawable_width (drawable) - 1),
CLAMP ((gint) paint_tool->cur_coords.y,
0, gimp_drawable_height (drawable) - 1));
gimp_smudge_tool_allocate_accum_buffer (w, h,
gimp_drawable_bytes (drawable),
do_fill);
accumPR.x = area->x - x;
accumPR.y = area->y - y;
accumPR.w = area->width;
accumPR.h = area->height;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data
+ accumPR.rowstride * accumPR.y
+ accumPR.x * accumPR.bytes;
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
area->x, area->y, area->width, area->height, FALSE);
/* copy the region under the original painthit. */
copy_region (&srcPR, &accumPR);
accumPR.x = area->x - x;
accumPR.y = area->y - y;
accumPR.w = area->width;
accumPR.h = area->height;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data
+ accumPR.rowstride * accumPR.y
+ accumPR.x * accumPR.bytes;
if (do_fill)
g_free(do_fill);
return TRUE;
}
static void
gimp_smudge_tool_allocate_accum_buffer (gint w,
gint h,
gint bytes,
guchar *do_fill)
{
/* Allocate the accumulation buffer */
accumPR.bytes = bytes;
accum_data = g_malloc (w * h * bytes);
if (do_fill != NULL)
{
/* guchar color[3] = {0,0,0}; */
accumPR.x = 0;
accumPR.y = 0;
accumPR.w = w;
accumPR.h = h;
accumPR.rowstride = accumPR.bytes * w;
accumPR.data = accum_data;
color_region (&accumPR, (const guchar*)do_fill);
}
}
static void
gimp_smudge_tool_motion (GimpPaintTool *paint_tool,
PaintPressureOptions *pressure_options,
gdouble smudge_rate,
GimpDrawable *drawable)
{
GimpImage *gimage;
GimpContext *context;
TempBuf *area;
PixelRegion srcPR, destPR, tempPR;
gdouble rate;
gint opacity;
gint x, y, w, h;
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
/* If the image type is indexed, don't smudge */
if (gimp_drawable_is_indexed (drawable))
return;
gimp_smudge_tool_nonclipped_painthit_coords (paint_tool, &x, &y, &w, &h);
/* Get the paint area */
/* Smudge won't scale! */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, 1.0)))
return;
/* srcPR will be the pixels under the current painthit from
the drawable*/
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
area->x, area->y, area->width, area->height, FALSE);
/* Enable pressure sensitive rate */
if (pressure_options->rate)
rate = MIN (smudge_rate / 100.0 * paint_tool->cur_coords.pressure * 2.0, 1.0);
else
rate = smudge_rate / 100.0;
/* The tempPR will be the built up buffer (for smudge) */
tempPR.bytes = accumPR.bytes;
tempPR.rowstride = accumPR.rowstride;
tempPR.x = area->x - x;
tempPR.y = area->y - y;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.data = accum_data +
tempPR.rowstride * tempPR.y + tempPR.x * tempPR.bytes;
/* The dest will be the paint area we got above (= canvas_buf) */
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.rowstride = area->width * area->bytes;
destPR.data = temp_buf_data (area);
/*
Smudge uses the buffer Accum.
For each successive painthit Accum is built like this
Accum = rate*Accum + (1-rate)*I.
where I is the pixels under the current painthit.
Then the paint area (canvas_buf) is built as
(Accum,1) (if no alpha),
*/
blend_region (&srcPR, &tempPR, &tempPR, ROUND (rate * 255.0));
/* re-init the tempPR */
tempPR.bytes = accumPR.bytes;
tempPR.rowstride = accumPR.rowstride;
tempPR.x = area->x - x;
tempPR.y = area->y - y;
tempPR.w = area->width;
tempPR.h = area->height;
tempPR.data = accum_data
+ tempPR.rowstride * tempPR.y
+ tempPR.x * tempPR.bytes;
if (! gimp_drawable_has_alpha (drawable))
add_alpha_region (&tempPR, &destPR);
else
copy_region (&tempPR, &destPR);
opacity = 255 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
/*Replace the newly made paint area to the gimage*/
gimp_paint_tool_replace_canvas (paint_tool, drawable,
MIN (opacity, 255),
OPAQUE_OPACITY,
pressure_options->pressure ? PRESSURE : SOFT,
1.0, INCREMENTAL);
}
#if 0
static GimpSmudgeTool *non_gui_smudge = NULL;
@ -517,6 +196,11 @@ gimp_smudge_tool_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif
/* tool options stuff */
static GimpToolOptions *
smudge_options_new (GimpToolInfo *tool_info)
{

View File

@ -23,13 +23,6 @@
#include "gimppainttool.h"
typedef enum
{
SMUDGE_TYPE_SMUDGE,
SMUDGE_TYPE_STREAK
} SmudgeType;
#define GIMP_TYPE_SMUDGE_TOOL (gimp_smudge_tool_get_type ())
#define GIMP_SMUDGE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SMUDGE_TOOL, GimpSmudgeTool))
#define GIMP_SMUDGE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SMUDGE_TOOL, GimpSmudgeToolClass))
@ -58,14 +51,4 @@ void gimp_smudge_tool_register (Gimp *gimp,
GType gimp_smudge_tool_get_type (void) G_GNUC_CONST;
/* FIXME: this antique code doesn't follow the coding style */
gboolean gimp_smudge_tool_non_gui (GimpDrawable *drawable,
gdouble rate,
gint num_strokes,
gdouble *stroke_array);
gboolean gimp_smudge_tool_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_SMUDGE_TOOL_H__ */

View File

@ -18,29 +18,19 @@
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
#include "paint-funcs/paint-funcs.h"
#include "core/gimp.h"
#include "core/gimpbrush.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpimage-mask.h"
#include "core/gimppattern.h"
#include "core/gimptoolinfo.h"
#include "paint/gimpclone.h"
#include "display/gimpdisplay.h"
#include "gimpclonetool.h"
@ -52,95 +42,44 @@
#define TARGET_WIDTH 15
#define TARGET_HEIGHT 15
/* default types */
#define CLONE_DEFAULT_TYPE IMAGE_CLONE
#define CLONE_DEFAULT_ALIGNED ALIGN_NO
/* the clone structures */
typedef enum
{
ALIGN_NO,
ALIGN_YES,
ALIGN_REGISTERED
} AlignType;
static void gimp_clone_tool_class_init (GimpCloneToolClass *klass);
static void gimp_clone_tool_init (GimpCloneTool *tool);
typedef struct _CloneOptions CloneOptions;
static void gimp_clone_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_clone_tool_motion (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp);
struct _CloneOptions
{
PaintOptions paint_options;
static void gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
CloneType type;
CloneType type_d;
GtkWidget *type_w[2]; /* 2 radio buttons */
static void gimp_clone_tool_draw (GimpDrawTool *draw_tool);
AlignType aligned;
AlignType aligned_d;
GtkWidget *aligned_w[3]; /* 3 radio buttons */
};
/* forward function declarations */
static void gimp_clone_tool_class_init (GimpCloneToolClass *klass);
static void gimp_clone_tool_init (GimpCloneTool *tool);
static void gimp_clone_tool_cursor_update (GimpTool *tool,
GimpCoords *coords,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_clone_tool_draw (GimpDrawTool *draw_tool);
static void gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state);
static void gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
gint offset_x,
gint offset_y);
static void gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width);
static void gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width);
static void gimp_clone_init_callback (GimpClone *clone,
gpointer data);
static void gimp_clone_finish_callback (GimpClone *clone,
gpointer data);
static void gimp_clone_pretrace_callback (GimpClone *clone,
gpointer data);
static void gimp_clone_posttrace_callback (GimpClone *clone,
gpointer data);
static GimpToolOptions * clone_options_new (GimpToolInfo *tool_info);
static void clone_options_reset (GimpToolOptions *options);
/* local variables */
static gint src_x = 0; /* */
static gint src_y = 0; /* position of clone src */
static gint dest_x = 0; /* */
static gint dest_y = 0; /* position of clone src */
static gint offset_x = 0; /* */
static gint offset_y = 0; /* offset for cloning */
static gint first = TRUE;
static GimpDrawable *the_src_drawable = NULL; /* source drawable */
static GimpDrawable *non_gui_src_drawable;
static gint non_gui_offset_x;
static gint non_gui_offset_y;
static CloneType non_gui_type;
static GimpPaintToolClass *parent_class;
@ -195,21 +134,19 @@ gimp_clone_tool_get_type (void)
static void
gimp_clone_tool_class_init (GimpCloneToolClass *klass)
{
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
GimpPaintToolClass *paint_tool_class;
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
tool_class = GIMP_TOOL_CLASS (klass);
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
tool_class = GIMP_TOOL_CLASS (klass);
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
tool_class->button_press = gimp_clone_tool_button_press;
tool_class->motion = gimp_clone_tool_motion;
tool_class->cursor_update = gimp_clone_tool_cursor_update;
draw_tool_class->draw = gimp_clone_tool_draw;
paint_tool_class->paint = gimp_clone_tool_paint;
}
static void
@ -217,150 +154,76 @@ gimp_clone_tool_init (GimpCloneTool *clone)
{
GimpTool *tool;
GimpPaintTool *paint_tool;
GimpClone *clone_core;
tool = GIMP_TOOL (clone);
paint_tool = GIMP_PAINT_TOOL (clone);
tool->tool_cursor = GIMP_CLONE_TOOL_CURSOR;
paint_tool->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
paint_tool->flags |= TOOL_TRACES_ON_WINDOW;
clone_core = g_object_new (GIMP_TYPE_CLONE, NULL);
clone_core->init_callback = gimp_clone_init_callback;
clone_core->finish_callback = gimp_clone_finish_callback;
clone_core->pretrace_callback = gimp_clone_pretrace_callback;
clone_core->posttrace_callback = gimp_clone_posttrace_callback;
clone_core->callback_data = clone;
paint_tool->core = GIMP_PAINT_CORE (clone_core);
}
static void
clone_src_drawable_disconnect_cb (GimpDrawable *drawable,
GimpDrawable **src_drawable)
gimp_clone_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp)
{
if (drawable == *src_drawable)
GimpPaintTool *paint_tool;
paint_tool = GIMP_PAINT_TOOL (tool);
if (state & GDK_CONTROL_MASK)
{
*src_drawable = NULL;
GIMP_CLONE (paint_tool->core)->set_source = TRUE;
}
else
{
GIMP_CLONE (paint_tool->core)->set_source = FALSE;
}
GIMP_TOOL_CLASS (parent_class)->button_press (tool,
coords,
time,
state,
gdisp);
}
static void
clone_set_src_drawable (GimpDrawable *drawable)
gimp_clone_tool_motion (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp)
{
if (the_src_drawable == drawable)
return;
GimpPaintTool *paint_tool;
if (the_src_drawable)
g_signal_handlers_disconnect_by_func (G_OBJECT (the_src_drawable),
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
paint_tool = GIMP_PAINT_TOOL (tool);
the_src_drawable = drawable;
if (the_src_drawable)
if (state & GDK_CONTROL_MASK)
{
g_signal_connect (G_OBJECT (the_src_drawable), "disconnect",
G_CALLBACK (clone_src_drawable_disconnect_cb),
&the_src_drawable);
GIMP_CLONE (paint_tool->core)->set_source = TRUE;
}
}
static void
gimp_clone_tool_paint (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
PaintState state)
{
GimpTool *tool;
GimpDrawTool *draw_tool;
CloneOptions *options;
GimpContext *context;
static gint orig_src_x = 0;
static gint orig_src_y = 0;
tool = GIMP_TOOL (paint_tool);
draw_tool = GIMP_DRAW_TOOL (paint_tool);
options = (CloneOptions *) tool->tool_info->tool_options;
context = gimp_get_current_context (tool->gdisp->gimage->gimp);
switch (state)
else
{
case PRETRACE_PAINT:
gimp_draw_tool_pause (draw_tool);
break;
case POSTTRACE_PAINT:
gimp_draw_tool_resume (draw_tool);
break;
case MOTION_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
{
/* If the control key is down, move the src target and return */
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
first = TRUE;
}
else
{
/* otherwise, update the target */
dest_x = paint_tool->cur_coords.x;
dest_y = paint_tool->cur_coords.y;
if (options->aligned == ALIGN_REGISTERED)
{
offset_x = 0;
offset_y = 0;
}
else if (first)
{
offset_x = src_x - dest_x;
offset_y = src_y - dest_y;
first = FALSE;
}
src_x = dest_x + offset_x;
src_y = dest_y + offset_y;
gimp_clone_tool_motion (paint_tool, drawable, the_src_drawable,
options->paint_options.pressure_options,
options->type,
offset_x, offset_y);
}
break;
case INIT_PAINT:
if (paint_tool->state & GDK_CONTROL_MASK)
{
clone_set_src_drawable (drawable);
src_x = paint_tool->cur_coords.x;
src_y = paint_tool->cur_coords.y;
first = TRUE;
}
else if (options->aligned == ALIGN_NO)
{
first = TRUE;
orig_src_x = src_x;
orig_src_y = src_y;
}
gimp_draw_tool_start (draw_tool, tool->gdisp);
if (options->type == PATTERN_CLONE)
if (! gimp_context_get_pattern (context))
g_message (_("No patterns available for this operation."));
break;
case FINISH_PAINT:
gimp_draw_tool_stop (draw_tool);
if (options->aligned == ALIGN_NO && !first)
{
src_x = orig_src_x;
src_y = orig_src_y;
}
break;
default:
break;
GIMP_CLONE (paint_tool->core)->set_source = FALSE;
}
GIMP_TOOL_CLASS (parent_class)->motion (tool,
coords,
time,
state,
gdisp);
}
void
@ -377,7 +240,7 @@ gimp_clone_tool_cursor_update (GimpTool *tool,
if ((layer = gimp_image_get_active_layer (gdisp->gimage)))
{
int off_x, off_y;
gint off_x, off_y;
gimp_drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
@ -400,7 +263,7 @@ gimp_clone_tool_cursor_update (GimpTool *tool,
{
if (state & GDK_CONTROL_MASK)
ctype = GIMP_CROSSHAIR_SMALL_CURSOR;
else if (! the_src_drawable)
else if (! GIMP_CLONE (GIMP_PAINT_TOOL (tool)->core)->src_drawable)
ctype = GIMP_BAD_CURSOR;
}
@ -424,9 +287,14 @@ gimp_clone_tool_draw (GimpDrawTool *draw_tool)
if (draw_tool->gdisp && options->type == IMAGE_CLONE)
{
GimpClone *clone;
clone = GIMP_CLONE (GIMP_PAINT_TOOL (draw_tool)->core);
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_CROSS,
src_x, src_y,
clone->src_x,
clone->src_y,
TARGET_WIDTH, TARGET_WIDTH,
GTK_ANCHOR_CENTER,
TRUE);
@ -439,256 +307,52 @@ gimp_clone_tool_draw (GimpDrawTool *draw_tool)
}
static void
gimp_clone_tool_motion (GimpPaintTool *paint_tool,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
PaintPressureOptions *pressure_options,
CloneType type,
int offset_x,
int offset_y)
gimp_clone_init_callback (GimpClone *clone,
gpointer data)
{
GimpImage *gimage;
GimpImage *src_gimage = NULL;
GimpContext *context;
guchar *s;
guchar *d;
TempBuf *orig;
TempBuf *area;
gpointer pr;
gint y;
gint x1, y1, x2, y2;
gint has_alpha = -1;
PixelRegion srcPR, destPR;
GimpPattern *pattern;
gint opacity;
gdouble scale;
GimpCloneTool *clone_tool;
pr = NULL;
pattern = NULL;
clone_tool = GIMP_CLONE_TOOL (data);
/* Make sure we still have a source if we are doing image cloning */
if (type == IMAGE_CLONE)
{
if (!src_drawable)
return;
if (! (src_gimage = gimp_drawable_gimage (src_drawable)))
return;
/* Determine whether the source image has an alpha channel */
has_alpha = gimp_drawable_has_alpha (src_drawable);
}
/* We always need a destination image */
if (! (gimage = gimp_drawable_gimage (drawable)))
return;
context = gimp_get_current_context (gimage->gimp);
if (pressure_options->size)
scale = paint_tool->cur_coords.pressure;
else
scale = 1.0;
/* Get a region which can be used to paint to */
if (! (area = gimp_paint_tool_get_paint_area (paint_tool, drawable, scale)))
return;
switch (type)
{
case IMAGE_CLONE:
/* Set the paint area to transparent */
temp_buf_data_clear (area);
/* If the source gimage is different from the destination,
* then we should copy straight from the destination image
* to the canvas.
* Otherwise, we need a call to get_orig_image to make sure
* we get a copy of the unblemished (offset) image
*/
if (src_drawable != drawable)
{
x1 = CLAMP (area->x + offset_x, 0, gimp_drawable_width (src_drawable));
y1 = CLAMP (area->y + offset_y, 0, gimp_drawable_height (src_drawable));
x2 = CLAMP (area->x + offset_x + area->width,
0, gimp_drawable_width (src_drawable));
y2 = CLAMP (area->y + offset_y + area->height,
0, gimp_drawable_height (src_drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
pixel_region_init (&srcPR, gimp_drawable_data (src_drawable),
x1, y1, (x2 - x1), (y2 - y1), FALSE);
}
else
{
x1 = CLAMP (area->x + offset_x, 0, gimp_drawable_width (drawable));
y1 = CLAMP (area->y + offset_y, 0, gimp_drawable_height (drawable));
x2 = CLAMP (area->x + offset_x + area->width,
0, gimp_drawable_width (drawable));
y2 = CLAMP (area->y + offset_y + area->height,
0, gimp_drawable_height (drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
/* get the original image */
orig = gimp_paint_tool_get_orig_image (paint_tool, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0; srcPR.y = 0;
srcPR.w = x2 - x1;
srcPR.h = y2 - y1;
srcPR.rowstride = srcPR.bytes * orig->width;
srcPR.data = temp_buf_data (orig);
}
offset_x = x1 - (area->x + offset_x);
offset_y = y1 - (area->y + offset_y);
/* configure the destination */
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = srcPR.w;
destPR.h = srcPR.h;
destPR.rowstride = destPR.bytes * area->width;
destPR.data = temp_buf_data (area) + offset_y * destPR.rowstride +
offset_x * destPR.bytes;
pr = pixel_regions_register (2, &srcPR, &destPR);
break;
case PATTERN_CLONE:
pattern = gimp_context_get_pattern (context);
if (!pattern)
return;
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
destPR.w = area->width;
destPR.h = area->height;
destPR.rowstride = destPR.bytes * area->width;
destPR.data = temp_buf_data (area);
pr = pixel_regions_register (1, &destPR);
break;
}
for (; pr != NULL; pr = pixel_regions_process (pr))
{
s = srcPR.data;
d = destPR.data;
for (y = 0; y < destPR.h; y++)
{
switch (type)
{
case IMAGE_CLONE:
gimp_clone_tool_line_image (gimage, src_gimage, drawable,
src_drawable, s, d, has_alpha,
srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
break;
case PATTERN_CLONE:
gimp_clone_tool_line_pattern (gimage, drawable, pattern, d,
area->x + offset_x,
area->y + y + offset_y,
destPR.bytes, destPR.w);
break;
}
d += destPR.rowstride;
}
}
opacity = 255.0 * gimp_context_get_opacity (context);
if (pressure_options->opacity)
opacity = opacity * 2.0 * paint_tool->cur_coords.pressure;
/* paste the newly painted canvas to the gimage which is being worked on */
gimp_paint_tool_paste_canvas (paint_tool, drawable,
MIN (opacity, 255),
(gint) (gimp_context_get_opacity (context) * 255),
gimp_context_get_paint_mode (context),
pressure_options->pressure ? PRESSURE : SOFT,
scale, CONSTANT);
}
static void
gimp_clone_tool_line_image (GimpImage *dest,
GimpImage *src,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
guchar *s,
guchar *d,
gint has_alpha,
gint src_bytes,
gint dest_bytes,
gint width)
{
guchar rgb[3];
gint src_alpha, dest_alpha;
src_alpha = src_bytes - 1;
dest_alpha = dest_bytes - 1;
while (width--)
{
gimp_image_get_color (src, gimp_drawable_type (s_drawable), rgb, s);
gimp_image_transform_color (dest, d_drawable, rgb, d, GIMP_RGB);
if (has_alpha)
d[dest_alpha] = s[src_alpha];
else
d[dest_alpha] = OPAQUE_OPACITY;
s += src_bytes;
d += dest_bytes;
}
gimp_draw_tool_start (GIMP_DRAW_TOOL (clone_tool),
GIMP_TOOL (clone_tool)->gdisp);
}
static void
gimp_clone_tool_line_pattern (GimpImage *dest,
GimpDrawable *drawable,
GimpPattern *pattern,
guchar *d,
gint x,
gint y,
gint bytes,
gint width)
gimp_clone_finish_callback (GimpClone *clone,
gpointer data)
{
guchar *pat, *p;
GimpImageBaseType color_type;
gint alpha;
gint i;
GimpCloneTool *clone_tool;
/* Make sure x, y are positive */
while (x < 0)
x += pattern->mask->width;
while (y < 0)
y += pattern->mask->height;
clone_tool = GIMP_CLONE_TOOL (data);
/* Get a pointer to the appropriate scanline of the pattern buffer */
pat = temp_buf_data (pattern->mask) +
(y % pattern->mask->height) * pattern->mask->width * pattern->mask->bytes;
color_type = (pattern->mask->bytes == 3) ? GIMP_RGB : GIMP_GRAY;
alpha = bytes - 1;
for (i = 0; i < width; i++)
{
p = pat + ((i + x) % pattern->mask->width) * pattern->mask->bytes;
gimp_image_transform_color (dest, drawable, p, d, color_type);
d[alpha] = OPAQUE_OPACITY;
d += bytes;
}
gimp_draw_tool_stop (GIMP_DRAW_TOOL (clone_tool));
}
#if 0 /* leave these to the stub functions. */
static void
gimp_clone_pretrace_callback (GimpClone *clone,
gpointer data)
{
GimpCloneTool *clone_tool;
clone_tool = GIMP_CLONE_TOOL (data);
gimp_draw_tool_pause (GIMP_DRAW_TOOL (clone_tool));
}
static void
gimp_clone_posttrace_callback (GimpClone *clone,
gpointer data)
{
GimpCloneTool *clone_tool;
clone_tool = GIMP_CLONE_TOOL (data);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (clone_tool));
}
#if 0
static gpointer
gimp_clone_tool_non_gui_paint_func (GimpPaintTool *paint_tool,
@ -779,7 +443,10 @@ gimp_clone_tool_non_gui (GimpDrawable *drawable,
return FALSE;
}
#endif /* 0 - non-gui functions */
#endif
/* too options stuff */
static GimpToolOptions *
clone_options_new (GimpToolInfo *tool_info)

View File

@ -23,13 +23,6 @@
#include "gimppainttool.h"
typedef enum
{
IMAGE_CLONE,
PATTERN_CLONE
} CloneType;
#define GIMP_TYPE_CLONE_TOOL (gimp_clone_tool_get_type ())
#define GIMP_CLONE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CLONE_TOOL, GimpCloneTool))
#define GIMP_CLONE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CLONE_TOOL, GimpCloneToolClass))
@ -58,21 +51,4 @@ void gimp_clone_tool_register (Gimp *gimp,
GType gimp_clone_tool_get_type (void) G_GNUC_CONST;
/* FIXME: Old style functions in need of a replacement. The only
* time these are used is to stroke paths or fill selections
* They should be somewhere else.
*/
gboolean clone_non_gui (GimpDrawable *drawable,
GimpDrawable *src_drawable,
CloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gdouble *stroke_array);
gboolean clone_non_gui_default (GimpDrawable *drawable,
gint num_strokes,
gdouble *stroke_array);
#endif /* __GIMP_CLONE_TOOL_H__ */

View File

@ -20,6 +20,7 @@
#define __TOOLS_TYPES_H__
#include "paint/paint-types.h"
#include "display/display-types.h"
@ -66,31 +67,6 @@ typedef void (* GimpToolRegisterFunc) (Gimp *gimp,
/* enums */
/* Brush application types */
typedef enum
{
HARD, /* pencil */
SOFT, /* paintbrush */
PRESSURE /* paintbrush with variable pressure */
} BrushApplicationMode;
/* Paint application modes */
typedef enum
{
CONSTANT, /*< nick=CONTINUOUS >*/ /* pencil, paintbrush, airbrush, clone */
INCREMENTAL /* convolve, smudge */
} PaintApplicationMode;
/* gradient paint modes */
typedef enum
{
ONCE_FORWARD, /* paint through once, then stop */
ONCE_BACKWARDS, /* paint once, then stop, but run the gradient the other way */
LOOP_SAWTOOTH, /* keep painting, looping through the grad start->end,start->end /|/|/| */
LOOP_TRIANGLE, /* keep paiting, looping though the grad start->end,end->start /\/\/\/ */
ONCE_END_COLOR /* paint once, but keep painting with the end color */
} GradientPaintMode;
typedef enum /*< pdb-skip >*/
{
SELECTION_ADD = CHANNEL_OP_ADD,

View File

@ -47,6 +47,8 @@
#include "core/gimpparasite.h"
#include "core/gimpparasitelist.h"
#include "paint/gimppaintcore.h"
#include "tools/gimpbycolorselecttool.h"
#include "tools/gimptool.h"
#include "tools/gimpdrawtool.h"
@ -1265,48 +1267,50 @@ undo_pop_transform (GimpImage *gimage,
UndoType type,
gpointer tu_ptr)
{
GimpTool *active_tool;
GimpTransformTool *tt;
TransformUndo *tu;
TileManager *temp;
gdouble d;
gint i;
GimpTool *active_tool;
active_tool = tool_manager_get_active (gimage->gimp);
/* Can't have ANY tool selected - maybe a plugin running */
if (active_tool == NULL)
return TRUE;
tt = (GimpTransformTool *) active_tool;
tu = (TransformUndo *) tu_ptr;
path_transform_do_undo (gimage, tu->path_undo);
/* only pop if the active tool is the tool that pushed this undo */
if (tu->tool_ID != active_tool->ID)
return TRUE;
/* swap the transformation information arrays */
for (i = 0; i < TRAN_INFO_SIZE; i++)
if (active_tool)
{
d = tu->trans_info[i];
tu->trans_info[i] = tt->trans_info[i];
tt->trans_info[i] = d;
}
GimpTransformTool *tt;
TransformUndo *tu;
/* swap the original buffer--the source buffer for repeated transforms
*/
temp = tu->original;
tu->original = tt->original;
tt->original = temp;
tt = (GimpTransformTool *) active_tool;
tu = (TransformUndo *) tu_ptr;
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tt->original)
{
active_tool->state = ACTIVE;
path_transform_do_undo (gimage, tu->path_undo);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tt));
/* only pop if the active tool is the tool that pushed this undo */
if (tu->tool_ID == active_tool->ID)
{
TileManager *temp;
gdouble d;
gint i;
/* swap the transformation information arrays */
for (i = 0; i < TRAN_INFO_SIZE; i++)
{
d = tu->trans_info[i];
tu->trans_info[i] = tt->trans_info[i];
tt->trans_info[i] = d;
}
/* swap the original buffer--the source buffer for repeated transforms
*/
temp = tu->original;
tu->original = tt->original;
tt->original = temp;
/* If we're re-implementing the first transform, reactivate tool */
if (state == REDO && tt->original)
{
active_tool->state = ACTIVE;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tt));
}
}
}
return TRUE;
@ -1338,7 +1342,7 @@ undo_push_paint (GimpImage *gimage,
Undo *new;
if ((new = undo_push (gimage,
sizeof (PaintUndo), PAINT_UNDO, FALSE)))
sizeof (GimpPaintCoreUndo), PAINT_UNDO, FALSE)))
{
new->data = pu_ptr;
new->pop_func = undo_pop_paint;
@ -1359,28 +1363,30 @@ undo_pop_paint (GimpImage *gimage,
UndoType type,
gpointer pu_ptr)
{
GimpTool *active_tool;
GimpPaintTool *pt;
PaintUndo *pu;
GimpCoords tmp_coords;
GimpTool *active_tool;
active_tool = tool_manager_get_active (gimage->gimp);
/* Can't have ANY tool selected - maybe a plugin running */
if (active_tool == NULL)
return TRUE;
if (active_tool)
{
GimpPaintTool *pt;
GimpPaintCoreUndo *pu;
pt = (GimpPaintTool *) active_tool;
pu = (PaintUndo *) pu_ptr;
pt = (GimpPaintTool *) active_tool;
pu = (GimpPaintCoreUndo *) pu_ptr;
/* only pop if the active tool is the tool that pushed this undo */
if (pu->tool_ID != active_tool->ID)
return TRUE;
/* only pop if the active paint core is the one that pushed this undo */
if (pu->core_ID == pt->core->ID)
{
GimpCoords tmp_coords;
/* swap the paint core information */
tmp_coords = pt->last_coords;
pt->last_coords = pu->last_coords;
pu->last_coords = tmp_coords;
/* swap the paint core information */
tmp_coords = pt->core->last_coords;
pt->core->last_coords = pu->last_coords;
pu->last_coords = tmp_coords;
}
}
return TRUE;
}
@ -1390,9 +1396,9 @@ undo_free_paint (UndoState state,
UndoType type,
gpointer pu_ptr)
{
PaintUndo *pu;
GimpPaintCoreUndo *pu;
pu = (PaintUndo *) pu_ptr;
pu = (GimpPaintCoreUndo *) pu_ptr;
g_free (pu);
}

View File

@ -840,6 +840,7 @@ app/core/Makefile
app/display/Makefile
app/file/Makefile
app/gui/Makefile
app/paint/Makefile
app/paint-funcs/Makefile
app/pdb/Makefile
app/plug-in/Makefile

View File

@ -84,17 +84,19 @@ main (int argc,
int i, j;
double x, y;
printf ("/* paint_core_kernels.h\n"
printf ("/* gimppaintcore-kernels.h\n"
" *\n"
" * This file was generated using kernelgen as found in the tools dir.\n");
printf (" * (threshold = %g)\n", THRESHOLD);
printf (" */\n\n");
printf ("#ifndef __GIMP_PAINT_CORE_KERNELS_H__\n");
printf ("#define __GIMP_PAINT_CORE_KERNELS_H__\n\n");
printf ("#define KERNEL_WIDTH %d\n", KERNEL_WIDTH);
printf ("#define KERNEL_HEIGHT %d\n", KERNEL_HEIGHT);
printf ("#define KERNEL_SUBSAMPLE %d\n", SUBSAMPLE);
printf ("\n\n");
printf ("/* Brush pixel subsampling kernels */\n");
printf ("static const int subsample[%d][%d][%d] = {\n",
printf ("static const int subsample[%d][%d][%d] =\n{\n",
SUBSAMPLE + 1, SUBSAMPLE + 1, KERNEL_WIDTH * KERNEL_HEIGHT);
for (j = 0; j <= SUBSAMPLE; j++)
@ -115,7 +117,9 @@ main (int argc,
printf (" }%c\n", j < SUBSAMPLE ? ',' : ' ');
}
printf ("};\n");
printf ("};\n\n");
printf ("#endif /* __GIMP_PAINT_CORE_KERNELS_H__\n");
exit (0);
}

View File

@ -56,11 +56,9 @@ enum_headers = \
../../app/base/base-enums.h \
../../app/core/core-types.h \
../../app/core/core-enums.h \
../../app/paint/paint-types.h \
../../app/plug-in/plug-in-types.h \
../../app/tools/tools-types.h \
../../app/tools/gimpclonetool.h \
../../app/tools/gimpconvolvetool.h \
../../app/tools/gimpdodgeburntool.h \
../../app/tools/gimphuesaturationtool.h \
../../app/tools/gimptexttool.h

View File

@ -354,6 +354,55 @@ package Gimp::CodeGen::enums;
GIMP_MIDTONES => '1',
GIMP_HIGHLIGHTS => '2' }
},
BrushApplicationMode =>
{ contig => 1,
header => 'paint/paint-types.h',
symbols => [ qw(HARD SOFT PRESSURE) ],
mapping => { HARD => '0',
SOFT => '1',
PRESSURE => '2' }
},
PaintApplicationMode =>
{ contig => 1,
header => 'paint/paint-types.h',
symbols => [ qw(CONSTANT INCREMENTAL) ],
mapping => { CONSTANT => '0',
INCREMENTAL => '1' },
nicks => { CONSTANT => 'CONTINUOUS' }
},
GradientPaintMode =>
{ contig => 1,
header => 'paint/paint-types.h',
symbols => [ qw(ONCE_FORWARD ONCE_BACKWARDS LOOP_SAWTOOTH
LOOP_TRIANGLE ONCE_END_COLOR) ],
mapping => { ONCE_FORWARD => '0',
ONCE_BACKWARDS => '1',
LOOP_SAWTOOTH => '2',
LOOP_TRIANGLE => '3',
ONCE_END_COLOR => '4' }
},
DodgeBurnType =>
{ contig => 1,
header => 'paint/paint-types.h',
symbols => [ qw(DODGE BURN) ],
mapping => { DODGE => '0',
BURN => '1' }
},
ConvolveType =>
{ contig => 1,
header => 'paint/paint-types.h',
symbols => [ qw(BLUR_CONVOLVE SHARPEN_CONVOLVE CUSTOM_CONVOLVE) ],
mapping => { BLUR_CONVOLVE => '0',
SHARPEN_CONVOLVE => '1',
CUSTOM_CONVOLVE => '2' }
},
CloneType =>
{ contig => 1,
header => 'paint/paint-types.h',
symbols => [ qw(IMAGE_CLONE PATTERN_CLONE) ],
mapping => { IMAGE_CLONE => '0',
PATTERN_CLONE => '1' }
},
GimpRunMode =>
{ contig => 1,
header => 'plug-in/plug-in-types.h',
@ -376,55 +425,6 @@ package Gimp::CodeGen::enums;
PLUG_IN_GRAYA_IMAGE => '1 << 4',
PLUG_IN_INDEXEDA_IMAGE => '1 << 5' }
},
BrushApplicationMode =>
{ contig => 1,
header => 'tools/tools-types.h',
symbols => [ qw(HARD SOFT PRESSURE) ],
mapping => { HARD => '0',
SOFT => '1',
PRESSURE => '2' }
},
PaintApplicationMode =>
{ contig => 1,
header => 'tools/tools-types.h',
symbols => [ qw(CONSTANT INCREMENTAL) ],
mapping => { CONSTANT => '0',
INCREMENTAL => '1' },
nicks => { CONSTANT => 'CONTINUOUS' }
},
GradientPaintMode =>
{ contig => 1,
header => 'tools/tools-types.h',
symbols => [ qw(ONCE_FORWARD ONCE_BACKWARDS LOOP_SAWTOOTH
LOOP_TRIANGLE ONCE_END_COLOR) ],
mapping => { ONCE_FORWARD => '0',
ONCE_BACKWARDS => '1',
LOOP_SAWTOOTH => '2',
LOOP_TRIANGLE => '3',
ONCE_END_COLOR => '4' }
},
CloneType =>
{ contig => 1,
header => 'tools/gimpclonetool.h',
symbols => [ qw(IMAGE_CLONE PATTERN_CLONE) ],
mapping => { IMAGE_CLONE => '0',
PATTERN_CLONE => '1' }
},
ConvolveType =>
{ contig => 1,
header => 'tools/gimpconvolvetool.h',
symbols => [ qw(BLUR_CONVOLVE SHARPEN_CONVOLVE CUSTOM_CONVOLVE) ],
mapping => { BLUR_CONVOLVE => '0',
SHARPEN_CONVOLVE => '1',
CUSTOM_CONVOLVE => '2' }
},
DodgeBurnType =>
{ contig => 1,
header => 'tools/gimpdodgeburntool.h',
symbols => [ qw(DODGE BURN) ],
mapping => { DODGE => '0',
BURN => '1' }
},
HueRange =>
{ contig => 1,
header => 'tools/gimphuesaturationtool.h',

View File

@ -70,7 +70,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpairbrushtool.h") ],
code => <<'CODE'
success = airbrush_non_gui (drawable, pressure, num_strokes, strokes);
success = FALSE; /*airbrush_non_gui (drawable, pressure, num_strokes, strokes);*/
CODE
);
}
@ -98,7 +98,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpairbrushtool.h") ],
code => <<'CODE'
success = airbrush_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*airbrush_non_gui_default (drawable, num_strokes, strokes);*/
CODE
);
}
@ -140,8 +140,8 @@ HELP
%invoke = (
headers => [ qw("tools/gimpclonetool.h") ],
code => <<'CODE'
success = clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);
success = FALSE; /*clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);*/
CODE
);
}
@ -170,7 +170,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpclonetool.h") ],
code => <<'CODE'
success = clone_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*clone_non_gui_default (drawable, num_strokes, strokes);*/
CODE
);
}
@ -198,7 +198,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpconvolvetool.h") ],
code => <<'CODE'
success = convolve_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*convolve_non_gui_default (drawable, num_strokes, strokes);*/
CODE
);
}
@ -228,7 +228,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpconvolvetool.h") ],
code => <<'CODE'
success = convolve_non_gui (drawable, pressure, convolve_type, num_strokes, strokes);
success = FALSE; /*convolve_non_gui (drawable, pressure, convolve_type, num_strokes, strokes);*/
CODE
);
}
@ -254,7 +254,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimperasertool.h") ],
code => <<'CODE'
success = eraser_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*eraser_non_gui_default (drawable, num_strokes, strokes);*/
CODE
);
}
@ -284,7 +284,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimperasertool.h") ],
code => <<'CODE'
success = eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE);
success = FALSE; /*eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE);*/
CODE
);
}
@ -314,7 +314,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimperasertool.h") ],
code => <<'CODE'
success = eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE);
success = FALSE; /*eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE);*/
CODE
);
}
@ -352,8 +352,8 @@ HELP
%invoke = (
headers => [ qw("tools/gimppaintbrushtool.h") ],
code => <<'CODE'
success = gimp_paintbrush_tool_non_gui (drawable, num_strokes, strokes,
fade_out, method, gradient_length);
success = FALSE; /*gimp_paintbrush_tool_non_gui (drawable, num_strokes, strokes,
fade_out, method, gradient_length);*/
CODE
);
}
@ -389,7 +389,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimppaintbrushtool.h") ],
code => <<'CODE'
success = gimp_paintbrush_tool_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*gimp_paintbrush_tool_non_gui_default (drawable, num_strokes, strokes);*/
CODE
);
}
@ -414,7 +414,9 @@ HELP
%invoke = (
headers => [ qw("tools/gimppenciltool.h") ],
code => 'success = pencil_non_gui (drawable, num_strokes, strokes);'
code => <<'CODE'
success = FALSE; /*pencil_non_gui (drawable, num_strokes, strokes);'*/
CODE
);
}
@ -440,7 +442,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpsmudgetool.h") ],
code => <<'CODE'
success = gimp_smudge_tool_non_gui (drawable, pressure, num_strokes, strokes);
success = FALSE; /*gimp_smudge_tool_non_gui (drawable, pressure, num_strokes, strokes);*/
CODE
);
}
@ -468,7 +470,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpsmudgetool.h") ],
code => <<'CODE'
success = gimp_smudge_tool_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*gimp_smudge_tool_non_gui_default (drawable, num_strokes, strokes);*/
CODE
);
}
@ -498,9 +500,9 @@ HELP
);
%invoke = (
headers => [ qw("tools/gimpdodgeburntool.h") ],
headers => [ qw("paint/gimpdodgeburn.h") ],
code => <<'CODE'
success = gimp_dodgeburn_tool_non_gui (drawable, exposure, dodgeburn_type, dodgeburn_mode, num_strokes, strokes);
success = FALSE; /*gimp_dodgeburn_tool_non_gui (drawable, exposure, dodgeburn_type, dodgeburn_mode, num_strokes, strokes);*/
CODE
);
}
@ -527,7 +529,7 @@ HELP
%invoke = (
headers => [ qw("tools/gimpdodgeburntool.h") ],
code => <<'CODE'
success = gimp_dodgeburn_tool_non_gui_default (drawable, num_strokes, strokes);
success = FALSE; /*gimp_dodgeburn_tool_non_gui_default (drawable, num_strokes, strokes);*/
CODE
);
}