? .brush_notes.txt.swp ? brush_notes.txt ? color-jitter-smudge-rotate-brush.diff ? cscope.files ? cscope.out ? gimp-adrian-12-15-2005-against-HEAD.diff ? gimp-color-jitter-smudge-brush.diff ? gimp-smudge-paint-cvs.diff ? gimp-smudge-paint.diff ? app/base/brush-rotate.c ? app/base/brush-rotate.h ? app/paint/gimp-paintbrush.c.diff ? app/paint/gimp-texture-proof-of-concept.diff ? plug-ins/pygimp/.deps ? plug-ins/pygimp/.libs ? plug-ins/pygimp/_gimpenums.la ? plug-ins/pygimp/gimp.la ? plug-ins/pygimp/gimpcolor.la ? plug-ins/pygimp/gimpcolormodule.lo ? plug-ins/pygimp/gimpenumsmodule.lo ? plug-ins/pygimp/gimpmodule.lo ? plug-ins/pygimp/gimpprocbrowser.la ? plug-ins/pygimp/procbrowser.lo ? plug-ins/pygimp/pygimp-display.lo ? plug-ins/pygimp/pygimp-drawable.lo ? plug-ins/pygimp/pygimp-image.lo ? plug-ins/pygimp/pygimp-parasite.lo ? plug-ins/pygimp/pygimp-pdb.lo ? plug-ins/pygimp/pygimp-rgb.lo ? plug-ins/pygimp/pygimp-tile.lo ? plug-ins/twain/.deps ? plug-ins/winsnap/.deps Index: app/base/Makefile.am =================================================================== RCS file: /cvs/gnome/gimp/app/base/Makefile.am,v retrieving revision 1.38 diff -u -r1.38 Makefile.am --- app/base/Makefile.am 27 Jul 2005 22:52:33 -0000 1.38 +++ app/base/Makefile.am 15 Dec 2005 19:45:38 -0000 @@ -12,6 +12,8 @@ boundary.h \ brush-scale.c \ brush-scale.h \ + brush-rotate.c \ + brush-rotate.h \ color-balance.c \ color-balance.h \ colorize.c \ Index: app/base/temp-buf.c =================================================================== RCS file: /cvs/gnome/gimp/app/base/temp-buf.c,v retrieving revision 1.77 diff -u -r1.77 temp-buf.c --- app/base/temp-buf.c 3 Sep 2005 21:56:07 -0000 1.77 +++ app/base/temp-buf.c 15 Dec 2005 19:45:38 -0000 @@ -19,7 +19,7 @@ #include "config.h" #include - +#include #include #include "libgimpbase/gimpbase.h" @@ -392,6 +392,89 @@ } return dest; +} + +/* angle is radians */ +TempBuf * +temp_buf_rotate (TempBuf *src, + gdouble angle) +{ + TempBuf *dest = NULL; + guchar *src_data = NULL; + guchar *dest_data = NULL; + gint x; + gint y; + gint rows; + gint cols; + + gint dest_rows; + gint dest_cols; + + gint dest_index = 0; + gint source_index =0; + + printf("got here buf_rotate \n"); + // return src; + //new_width = (src->width/2 * cos(angle)) + (src->height/2 * sin(angle)); + //new_height = (src->height/2 * cos(angle)) - (src->width/2 * sin(angle)); + + cols = src->width; + rows = src->height; + + dest_rows = cols; + dest_cols = rows; + // flip the col/rows for the new image + dest = temp_buf_new (dest_cols, + dest_rows, + src->bytes, + 0, 0, NULL); + + src_data = temp_buf_data (src); + dest_data = temp_buf_data (dest); + + gint i; + + printf("x: %i y: %i\n", src->width, src->height); + printf("cols: %i rows: %i\n", cols, rows); + printf("dest_cols: %i dest_rows: %i\n", dest_cols, dest_rows); + dest_index = 0; + for (x = 0; x < dest_cols; x++) + { + for (y = 0; y < dest_rows; y++) + { + //source_index = ((rows -y -1) *cols) + x ; + source_index = ((cols - y - 1) * rows) + x; + printf("x,y %.2i,%.2i %i %i ", x, y, source_index, dest_index); + for (i = 0; i < src->bytes; i++) + { + dest_data[dest_index++] = src_data[source_index]; + } + } + printf("\n"); + } + +/* printf("x: %i y: %i\n", src->width, src->height); */ +/* printf("cols: %i rows: %i\n", cols, rows); */ +/* dest_index = 0; */ +/* for (y = 0; y < cols; y++) */ +/* { */ +/* for (x = 0; x < rows; x++) */ +/* { */ +/* source_index = ((rows -x -1) *cols) + y ; */ +/* printf("x,y %.2i,%.2i %i %i ", x, y, source_index, dest_index); */ +/* for (i = 0; i < src->bytes; i++) */ +/* { */ +/* dest_data[dest_index++] = src_data[source_index]; */ +/* } */ +/* } */ +/* printf("\n"); */ +/* } */ + + // dest = temp_buf_new (rows, cols, src->bytes, 0,0, dest_data); + + printf("dest->h, %i, dest->w, %i\n", dest->height, dest->width); + return dest; + } TempBuf * Index: app/base/temp-buf.h =================================================================== RCS file: /cvs/gnome/gimp/app/base/temp-buf.h,v retrieving revision 1.15 diff -u -r1.15 temp-buf.h --- app/base/temp-buf.h 8 Jun 2005 11:27:30 -0000 1.15 +++ app/base/temp-buf.h 15 Dec 2005 19:45:38 -0000 @@ -54,6 +54,9 @@ TempBuf * temp_buf_scale (TempBuf *buf, gint width, gint height); +TempBuf * temp_buf_rotate (TempBuf *buf, + gdouble angle); + TempBuf * temp_buf_copy_area (TempBuf *src, TempBuf *dest, gint x, Index: app/paint/gimpbrushcore.c =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimpbrushcore.c,v retrieving revision 1.22 diff -u -r1.22 gimpbrushcore.c --- app/paint/gimpbrushcore.c 7 Dec 2005 21:11:53 -0000 1.22 +++ app/paint/gimpbrushcore.c 15 Dec 2005 19:45:38 -0000 @@ -25,6 +25,7 @@ #include "paint-types.h" #include "base/brush-scale.h" +#include "base/brush-rotate.h" #include "base/pixel-region.h" #include "base/temp-buf.h" @@ -107,9 +108,18 @@ MaskBuf *brush_mask, gdouble scale); +static MaskBuf * gimp_brush_core_rotate_mask (GimpBrushCore *core, + MaskBuf *brush_mask, + gdouble angle); + +static MaskBuf * gimp_brush_core_rotate_pixmap (GimpBrushCore *core, + MaskBuf *brush_mask, + gdouble angle); + static MaskBuf * gimp_brush_core_get_brush_mask (GimpBrushCore *core, GimpBrushApplicationMode brush_hardness, - gdouble scale); + gdouble scale, + gdouble angle); static void gimp_brush_core_invalidate_cache (GimpBrush *brush, GimpBrushCore *core); @@ -172,6 +182,7 @@ core->brush = NULL; core->spacing = 1.0; core->scale = 1.0; + core->angle = 0.0; core->pressure_brush = NULL; @@ -192,6 +203,15 @@ core->last_scale_pixmap_width = 0; core->last_scale_pixmap_height = 0; + core->rotate_brush = NULL; + core->last_rotate_brush = NULL; + core->last_rotate_angle = 0.0; + + core->rotate_pixmap = NULL; + core->last_rotate_pixmap = NULL; + core->last_rotate_angle = 0.0; + + g_assert (BRUSH_CORE_SUBSAMPLE == KERNEL_SUBSAMPLE); for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++) @@ -238,6 +258,16 @@ temp_buf_free (core->scale_pixmap); core->scale_pixmap = NULL; } + if (core->rotate_brush) + { + temp_buf_free (core->rotate_brush); + core->rotate_brush = NULL; + } + if (core->rotate_pixmap) + { + temp_buf_free (core->rotate_pixmap); + core->rotate_pixmap = NULL; + } for (i = 0; i < KERNEL_SUBSAMPLE + 1; i++) for (j = 0; j < KERNEL_SUBSAMPLE + 1; j++) @@ -647,6 +677,16 @@ bytes = gimp_drawable_bytes_with_alpha (drawable); + /* this seems a bit special cased, why just pressure -> size mapping here? wheres + the xtilt/ytilt/velocity/stroke length/stroke angle/external controller/modulation + sources/etc. + + This is just to get the size of the paint area to sample, but still, anything that + can change the size or shape of the brush needs tp be able to figure that out at + this point. + + -akl FIXME */ + if (GIMP_BRUSH_CORE_GET_CLASS (core)->use_scale) { GimpPressureOptions *pressure_options = paint_options->pressure_options; @@ -659,6 +699,7 @@ core->scale = 1.0; } + /* pass in angle, to calculate rotate brush size -akl FIXME */ gimp_brush_core_calc_brush_size (core, core->brush->mask, core->scale, &brush_width, &brush_height); @@ -736,7 +777,8 @@ { MaskBuf *brush_mask = gimp_brush_core_get_brush_mask (core, brush_hardness, - core->scale); + core->scale, + core->angle); if (brush_mask) { @@ -779,7 +821,8 @@ { MaskBuf *brush_mask = gimp_brush_core_get_brush_mask (core, brush_hardness, - core->scale); + core->scale, + core->angle); if (brush_mask) { @@ -1192,6 +1235,7 @@ gint dest_width; gint dest_height; + printf("got here, gimp_brush_core_scale_mask; %f\n", scale); scale = CLAMP (scale, 0.0, 1.0); if (scale == 0.0) @@ -1272,9 +1316,102 @@ } static MaskBuf * +gimp_brush_core_rotate_mask (GimpBrushCore *core, + MaskBuf *brush_mask, + gdouble angle) +{ + MaskBuf *foo; + gint dest_height; + gint dest_width; + + if (angle == 0.0) + return brush_mask; + + /* FIXME */ + /* insert caching bits here... */ + /* need to verify both angle and size to use cache */ + /* but for now just check the angle so we can test + the rotation stuff */ + + /* comment out for now, since we will just always rotate just for kicks */ + +/* if (! core->cache_invalid && */ +/* brush_mask == core->last_rotate_brush && */ +/* core->rotate_brush && */ +/* angle == core->last_rotate_angle) */ +/* { */ +/* return core->rotate_brush; */ +/* } */ + + core->last_rotate_brush = brush_mask; + core->last_rotate_angle = angle; + + if (core->rotate_brush) + mask_buf_free (core->rotate_brush); + + if (brush_mask == NULL) + { + printf ("whytf is brush_mask null?\n"); + return NULL; + } + + core->rotate_brush = brush_rotate_mask (brush_mask, + angle); + core->cache_invalid = TRUE; + core->solid_cache_invalid = TRUE; + + + return core->rotate_brush; + + +} + +static MaskBuf * +gimp_brush_core_rotate_pixmap (GimpBrushCore *core, + MaskBuf *brush_mask, + gdouble angle) +{ + + if (angle == 0) + return brush_mask; + + /* FIXME */ + /* insert caching bits here... */ + /* need to verify both angle and size to use cache */ + /* but for now just check the angle so we can test + the rotation stuff */ + + if (! core->cache_invalid && + brush_mask == core->last_rotate_pixmap && + core->rotate_pixmap && + angle == core->last_rotate_angle) + { + return core->rotate_pixmap; + } + + core->last_rotate_pixmap = brush_mask; + core->last_rotate_angle = angle; + + if (core->rotate_pixmap) + mask_buf_free (core->rotate_pixmap); + + core->rotate_pixmap = brush_rotate_mask (brush_mask, + angle); + + core->cache_invalid = TRUE; + + return core->rotate_pixmap; + +} + + + + +static MaskBuf * gimp_brush_core_get_brush_mask (GimpBrushCore *core, GimpBrushApplicationMode brush_hardness, - gdouble scale) + gdouble scale, + gdouble angle) { GimpPaintCore *paint_core = GIMP_PAINT_CORE (core); MaskBuf *mask; @@ -1284,9 +1421,20 @@ else mask = core->brush->mask; - if (! mask) - return NULL; + + + /* not sure if this is the right place to put this? seems like it could + go in the select_brush stuff as well, but then, that could be said about + the scale code as well. Anyone understand why it's done here and not there + (in select_brush, the stuff the imagepipe stuff uses...? + mask = gimp_brush_core_rotate_mask (core, core->brush->mask, 3.14); + */ + if (! mask) + { + printf("mask is NULL\n"); + return NULL; + } switch (brush_hardness) { case GIMP_BRUSH_SOFT: @@ -1355,6 +1503,7 @@ if (! pixmap_mask) return; + if (mode != GIMP_BRUSH_HARD) brush_mask = gimp_brush_core_scale_mask (core, core->brush->mask, Index: app/paint/gimpbrushcore.h =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimpbrushcore.h,v retrieving revision 1.8 diff -u -r1.8 gimpbrushcore.h --- app/paint/gimpbrushcore.h 4 Oct 2005 20:16:52 -0000 1.8 +++ app/paint/gimpbrushcore.h 15 Dec 2005 19:45:38 -0000 @@ -21,6 +21,7 @@ #include "gimppaintcore.h" +#include "base/pixel-region.h" #define BRUSH_CORE_SUBSAMPLE 4 @@ -47,6 +48,7 @@ GimpBrush *brush; gdouble spacing; gdouble scale; + gdouble angle; /* brush buffers */ MaskBuf *pressure_brush; @@ -65,10 +67,25 @@ gint last_scale_pixmap_width; gint last_scale_pixmap_height; + MaskBuf *rotate_brush; + MaskBuf *last_rotate_brush; + gdouble last_scale_angle; + + MaskBuf *rotate_pixmap; + MaskBuf *last_rotate_pixmap; + gdouble last_rotate_angle; + + MaskBuf *kernel_brushes[BRUSH_CORE_SUBSAMPLE + 1][BRUSH_CORE_SUBSAMPLE + 1]; MaskBuf *last_brush_mask; gboolean cache_invalid; + + /* used when smudging */ + gboolean initialized; + PixelRegion accumPR; + guchar *accum_data; + gdouble jitter; Index: app/paint/gimpclone.c =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimpclone.c,v retrieving revision 1.126 diff -u -r1.126 gimpclone.c --- app/paint/gimpclone.c 7 Dec 2005 21:17:12 -0000 1.126 +++ app/paint/gimpclone.c 15 Dec 2005 19:45:38 -0000 @@ -62,14 +62,7 @@ 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); + static void gimp_clone_set_src_drawable (GimpClone *clone, GimpDrawable *drawable); @@ -424,7 +417,7 @@ } } -static void +void gimp_clone_line_pattern (GimpImage *dest, GimpDrawable *drawable, GimpPattern *pattern, @@ -448,9 +441,12 @@ while (y < 0) y += pattern->mask->height; + //printf("x2: %i y2: %i\n", x, y); /* Get a pointer to the appropriate scanline of the pattern buffer */ pat = temp_buf_data (pattern->mask) + (y % pattern->mask->height) * pattern->mask->width * pat_bytes; + + //printf("y pat->m->height: %i\n", y % pattern->mask->height); color_type = (pat_bytes == 3 || pat_bytes == 4) ? GIMP_RGB : GIMP_GRAY; Index: app/paint/gimpclone.h =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimpclone.h,v retrieving revision 1.27 diff -u -r1.27 gimpclone.h --- app/paint/gimpclone.h 29 Aug 2005 20:48:26 -0000 1.27 +++ app/paint/gimpclone.h 15 Dec 2005 19:45:38 -0000 @@ -63,5 +63,13 @@ GType gimp_clone_get_type (void) G_GNUC_CONST; +void gimp_clone_line_pattern (GimpImage *dest, + GimpDrawable *drawable, + GimpPattern *pattern, + guchar *d, + gint x, + gint y, + gint bytes, + gint width); #endif /* __GIMP_CLONE_H__ */ Index: app/paint/gimppaintbrush.c =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimppaintbrush.c,v retrieving revision 1.55 diff -u -r1.55 gimppaintbrush.c --- app/paint/gimppaintbrush.c 7 Dec 2005 21:11:53 -0000 1.55 +++ app/paint/gimppaintbrush.c 15 Dec 2005 19:45:38 -0000 @@ -35,21 +35,45 @@ #include "core/gimpdrawable.h" #include "core/gimpgradient.h" #include "core/gimpimage.h" +#include "core/gimppattern.h" +#include "core/gimppickable.h" #include "gimppaintbrush.h" #include "gimppaintoptions.h" +#include "gimpsmudge.h" +#include "gimpclone.h" #include "gimp-intl.h" +static gboolean gimp_paintbrush_start (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *options); + +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, GimpPaintOptions *paint_options, GimpPaintState paint_state, guint32 time); +void _gimp_paintbrush_smudge_motion (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + gdouble opacity); + + +static void gimp_paintbrush_nonclipped_painthit_coords (GimpPaintCore *paint_core, + gint *x, + gint *y, + gint *w, + gint *h); + +/* static GimpPaintCoreClass *parent_class = NULL; */ G_DEFINE_TYPE (GimpPaintbrush, gimp_paintbrush, GIMP_TYPE_BRUSH_CORE); +#define parent_class gimp_paintbrush_parent_class void @@ -85,18 +109,219 @@ GimpPaintState paint_state, guint32 time) { + + gboolean use_smudge; + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); + + use_smudge = gimp_paint_options_get_smudge(paint_options); + + switch (paint_state) { - case GIMP_PAINT_STATE_MOTION: + + case GIMP_PAINT_STATE_INIT: + printf("gh0 init\n"); _gimp_paintbrush_motion (paint_core, drawable, paint_options, GIMP_OPACITY_OPAQUE); + + if (use_smudge) + { + + printf("gh0.1 init-smudge\n"); + //brush_core->orig_spacing = brush_core->spacing; + //brush_core->spacing = 1.0/100.0; + printf("spacing %f\n", brush_core->spacing); + brush_core->initialized = gimp_paintbrush_start (paint_core, drawable, + paint_options); + } + + case GIMP_PAINT_STATE_MOTION: + + if (use_smudge) + { + _gimp_paintbrush_smudge_motion (paint_core, drawable, paint_options, + GIMP_OPACITY_OPAQUE); + } + else + { + _gimp_paintbrush_motion (paint_core, drawable, paint_options, + GIMP_OPACITY_OPAQUE); + } + + break; + + case GIMP_PAINT_STATE_FINISH: + printf("gh2 finish\n"); + if (brush_core->accum_data) + { + g_free(brush_core->accum_data); + brush_core->accum_data = NULL; + } + brush_core->initialized = FALSE; break; + default: break; } } +static gboolean +gimp_paintbrush_start (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options) +{ + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); + GimpImage *gimage; + TempBuf *area; + PixelRegion srcPR; + gint x,y,w,h; + gint bytes; + + gimage = gimp_item_get_image (GIMP_ITEM (drawable)); + + if (gimp_drawable_is_indexed (drawable)) + return FALSE; + + area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options); + if (! area) + return FALSE; + + /* adjust the x and y coordinates to the upper left corner of the brush */ + gimp_paintbrush_nonclipped_painthit_coords (paint_core, &x, &y, &w, &h); + + /* Allocate the accumulation buffer */ + bytes = gimp_drawable_bytes (drawable); + brush_core->accum_data = g_malloc (w * h * bytes); + /* If clipped, prefill the smudge buffer + with the color at the brush position. */ + if (x != area->x || y != area->y || w != area->width || h != area->height) + { + guchar *fill; + + fill = gimp_pickable_get_color_at (GIMP_PICKABLE (drawable), + CLAMP ((gint) paint_core->cur_coords.x, + 0, gimp_item_width (GIMP_ITEM (drawable)) - 1), + CLAMP ((gint) paint_core->cur_coords.y, + 0, gimp_item_height (GIMP_ITEM (drawable)) - 1)); + g_return_val_if_fail (fill != NULL, FALSE); + + pixel_region_init_data (&srcPR, brush_core->accum_data, + bytes, bytes * w, + 0, 0, w, h ); + + color_region (&srcPR, fill); + g_free (fill); + } + + + pixel_region_init (&srcPR, gimp_drawable_data (drawable), + area->x, area->y, area->width, area->height, FALSE); + + pixel_region_init_data (&brush_core->accumPR, brush_core->accum_data, + bytes, bytes * w, + area->x - x, + area->y - y, + area->width, + area->height); + + + /* copy the region under the original painthit. */ + copy_region (&srcPR, &brush_core->accumPR); + + pixel_region_init_data (&brush_core->accumPR, + brush_core->accum_data, + bytes, bytes * w, + area->x - x, + area->y -y, + area->width, + area->height); + + return TRUE; + + } + +void +_gimp_paintbrush_smudge_motion (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + gdouble opacity) +{ + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); + GimpContext *context = GIMP_CONTEXT (paint_options); + GimpImage *gimage; + TempBuf *area; + PixelRegion srcPR, destPR, tempPR; + gdouble rate; + gint x,y,w,h; + + gimage = gimp_item_get_image (GIMP_ITEM (drawable)); + + opacity *= gimp_paint_options_get_fade (paint_options, gimage, + paint_core->pixel_dist); + + rate = gimp_paint_options_get_smudge(paint_options) / 100.0; + + if (opacity == 0.0) + return; + + + gimp_paintbrush_nonclipped_painthit_coords (paint_core, &x, &y, &w, &h); + + /* Get the paint area (Smudge won't scale!) */ + area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options); + if (! area) + 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); + + pixel_region_init_data ( &tempPR, brush_core->accum_data, + brush_core->accumPR.bytes, + brush_core->accumPR.rowstride, + area->x - x, + area->y - y, + area->width, + area->height); + + + /* The dest will be the paint area we got above (= canvas_buf) */ + + pixel_region_init_temp_buf (&destPR, area, + 0, 0, area->width, area->height); + + + blend_region (&srcPR, &tempPR, &tempPR, ROUND (rate * 255.0)); + + /* re-init the tempPR */ + pixel_region_init_data (&tempPR, brush_core->accum_data, + brush_core->accumPR.bytes, + brush_core->accumPR.rowstride, + area->x - x, + area->y - y, + area->width, + area->height); + + + if (! gimp_drawable_has_alpha (drawable)) + add_alpha_region (&tempPR, &destPR); + else + copy_region (&tempPR, &destPR); + + + opacity = 100.0; + gimp_brush_core_replace_canvas (GIMP_BRUSH_CORE (paint_core), drawable, + MIN (opacity, GIMP_OPACITY_OPAQUE), + gimp_context_get_opacity (context), + gimp_paint_options_get_brush_mode (paint_options), + GIMP_PAINT_INCREMENTAL); + +} + + + + void _gimp_paintbrush_motion (GimpPaintCore *paint_core, GimpDrawable *drawable, @@ -106,14 +331,32 @@ GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); GimpContext *context = GIMP_CONTEXT (paint_options); GimpPressureOptions *pressure_options = paint_options->pressure_options; + GimpColorJitterOptions *color_jitter_options; GimpImage *gimage; + PixelRegion brushPR; + PixelRegion patternPR; + guchar *p; + GimpPattern *pattern = NULL; GimpRGB gradient_color; + GimpRGB foreground_color; + GimpHSV random_color; + gdouble hue; + gdouble sat; + gdouble val; + gpointer pr = NULL; + TempBuf *area; + TempBuf *pattern_buf; + guchar col[MAX_CHANNELS]; GimpPaintApplicationMode paint_appl_mode; + gint y; + gboolean active[MAX_CHANNELS] = { TRUE, TRUE, TRUE, TRUE }; + gint brush_h; + gint brush_w; - gimage = gimp_item_get_image (GIMP_ITEM (drawable)); + gimage = gimp_item_get_image (GIMP_ITEM (drawable)); opacity *= gimp_paint_options_get_fade (paint_options, gimage, paint_core->pixel_dist); if (opacity == 0.0) @@ -122,9 +365,121 @@ paint_appl_mode = paint_options->application_mode; area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options); + + brush_h = brush_core->main_brush->mask->height; + brush_w = brush_core->main_brush->mask->width; + if (! area) return; + /* So, wtf is this? the idea, create a new pixel_region the size of the brush, and fill it with + the data from a pattern, but with it "fixed", just like in clone. then we composite the brush image + mulitplied into the pattern/texture image, into a new brush image. Then we use that new brush image + as the new brush, now with "texture" + + Thats the theory anyway, but this is a prototype. Before were done, we need to add a new Texture + type, texture dialog, textuere data factory, etc. And plug it into the gui, and add it to th + "context" stuff, etc" + + */ + + pattern = gimp_context_get_pattern (context); + if (pattern) + { + /* create a tempbuf, and resize it to the same size as the brush data, then make + a pixel_region of it. Now, I'm assuming that combine_region needs the regions to + be the same size, so I make patternPR and brushPR the same size. + + But, it seems like maybe I should make both of them the size of the area (aka, the to + be painted area) since the combine region keeps wanting to walk off the end of the + pattern region. But doing that doesnt seem to help any. + + */ + pattern_buf = NULL; + pattern_buf = temp_buf_copy (gimp_pattern_get_mask (pattern), pattern_buf); + pattern_buf = temp_buf_resize (pattern_buf, + pattern_buf->bytes, + 0,0, + brush_w, + brush_h); + /* create a pixel_region from the tmp_buf */ + pixel_region_init_temp_buf (&patternPR, + pattern_buf, + 0, 0, + area->width, + area->height); + + pr = pixel_regions_register(1, &patternPR); + + /* copy the pattern info into a pixel region we can composite with + the brush */ + + /* patternPR is coming up with garbage... not sure why */ + + for (; pr != NULL; pr = pixel_regions_process (pr)) + { + p = patternPR.data; + + /* copy line by line from pattern to patternPR*/ + for (y = 0; y < patternPR.h; y++) + { + /* This seems to work for cloning from patterns, so I'm not sure whats up. It looks + like its doing the right thing, and is creating the proper size regions and all that, and + I don't actually get any segfaults here, but later on in combine_region. But it wouldn't + surprise me if something was wrong here */ + gimp_clone_line_pattern (gimage, + drawable, + pattern, + p, + area->x, /* note, note offset here, I think that makes this always "registered" which I think we want..? */ + area->y + y, + patternPR.bytes, + patternPR.w); + p += patternPR.rowstride; + } + + } + + + /* brushPR looks to do the right thing */ + pixel_region_init_temp_buf (&brushPR, + brush_core->brush->mask, + 0, 0, + brush_w, + brush_h); + + + printf("gh3, about to combine_regions\n"); + + printf("pattern x: %i y: %i w: %i h: %i bytes: %i\n", patternPR.x, patternPR.y, patternPR.w, patternPR.h, patternPR.bytes); + /* This is the part that always seems to want to segfauly. Basically, deep inside of combine_regions, the code is walking off + the end of the patternPR region. It seems like it wants to go one row past the last row, for reasons unknown. All the pixel + region sizes seem correct, as best I can tell. + */ + combine_regions (&patternPR, + &brushPR, + &brushPR, + NULL, + NULL, + 128, + GIMP_NORMAL_MODE, + active, + COMBINE_INTEN_INTEN); + + printf("brush x: %i y: %i w: %i h: %i bytes: %i\n", brushPR.x, brushPR.y, brushPR.w, brushPR.h, brushPR.bytes); + + } + + /* it seems like maybe theres a better place to be finally setting what color + we are going to paint with, but alas... */ + + /* use the pixmap if we have that, other wise use the forground or the gradient, + and if we have a randomizer, use it */ + + /* we probably want some methods to shift the color in hue/sat/val land as a first + pass, though RGB components is easy as well */ + + if (gimp_paint_options_get_gradient_color (paint_options, gimage, paint_core->cur_coords.pressure, paint_core->pixel_dist, @@ -154,15 +509,51 @@ paint_appl_mode = GIMP_PAINT_INCREMENTAL; } - else + else { + /* normal painting with the foreground color */ gimp_image_get_foreground (gimage, drawable, context, col); col[area->bytes - 1] = OPAQUE_OPACITY; + gimp_rgb_set_uchar(&foreground_color, col[0],col[1],col[2]); + gimp_rgb_to_hsv(&foreground_color, &random_color); + /* why do we use an accessor for this? it's just paint_options->color_jitter_options... -akl */ + color_jitter_options = gimp_paint_options_get_color_jitter(paint_options, gimage); + if (color_jitter_options->use_color_jitter) + { + /* I'm not sure what the best way to apply the "jitter amount". This an attempt to make the jitter amount + relative to percentage of the normal values, but thats kind of weird, and doesnt work at all for say, black. + + Maybe just +/- rand(amount) is better? dunno, need to play around some and wee what we feels better */ + + /* this is code the does the sorta percentage based approach above + random_color.h = random_color.h + g_random_double_range (-(color_options->color_jitter_hue_amounthue * random_color.h), (color_options->hue * random_color.h)); + random_color.s = random_color.s + g_random_double_range (-(color_options->sat * random_color.s), (color_options->sat * random_color.s)); + random_color.v = random_color.v + g_random_double_range (-(color_options->val * random_color.v), (colval * random_color.v)); + + */ + + hue = color_jitter_options->color_jitter_hue_amount; + sat = color_jitter_options->color_jitter_sat_amount; + val = color_jitter_options->color_jitter_val_amount; + random_color.h = random_color.h + g_random_double_range (-hue, hue); + random_color.s = random_color.s + g_random_double_range (-sat, sat); + random_color.v = random_color.v + g_random_double_range (-val, val); + + /* printf("randomized: h: %f s: %f v: %f\n", random_color.h, random_color.s, random_color.v); */ + gimp_hsv_to_rgb(&random_color, &foreground_color); + gimp_rgb_get_uchar(&foreground_color, &col[0], &col[1], &col[2]); + } + /* this stuff looks like crap without incremenatal mode */ + paint_appl_mode = GIMP_PAINT_INCREMENTAL; color_pixels (temp_buf_data (area), col, area->width * area->height, area->bytes); } + /* we should refactor this a bit, since we want to seperate the stuff that picks the + color and the stuff that colors the "area" (aka, the brush data to be composited). + So we can make the "randomize color" stuff once, and not for each options */ + if (pressure_options->opacity) opacity *= PRESSURE_SCALE * paint_core->cur_coords.pressure; @@ -172,4 +563,21 @@ gimp_context_get_paint_mode (context), gimp_paint_options_get_brush_mode (paint_options), paint_appl_mode); +} + + +static void +gimp_paintbrush_nonclipped_painthit_coords (GimpPaintCore *paint_core, + gint *x, + gint *y, + gint *w, + gint *h) +{ + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); + + /* Note: these are the brush mask size plus a border of 1 pixel */ + *x = (gint) paint_core->cur_coords.x - brush_core->brush->mask->width / 2 - 1; + *y = (gint) paint_core->cur_coords.y - brush_core->brush->mask->height / 2 - 1; + *w = brush_core->brush->mask->width + 2; + *h = brush_core->brush->mask->height + 2; } Index: app/paint/gimppaintoptions.c =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimppaintoptions.c,v retrieving revision 1.28 diff -u -r1.28 gimppaintoptions.c --- app/paint/gimppaintoptions.c 7 Dec 2005 21:11:53 -0000 1.28 +++ app/paint/gimppaintoptions.c 15 Dec 2005 19:45:38 -0000 @@ -51,12 +51,20 @@ #define DEFAULT_USE_JITTER FALSE #define DEFAULT_JITTER_AMOUNT 0.2 + +#define DEFAULT_USE_SMUDGE FALSE +#define DEFAULT_SMUDGE_AMOUNT 0.0 + #define DEFAULT_USE_GRADIENT FALSE #define DEFAULT_GRADIENT_REVERSE FALSE #define DEFAULT_GRADIENT_REPEAT GIMP_REPEAT_TRIANGULAR #define DEFAULT_GRADIENT_LENGTH 100.0 #define DEFAULT_GRADIENT_UNIT GIMP_UNIT_PIXEL +#define DEFAULT_USE_COLOR_JITTER FALSE +#define DEFAULT_COLOR_JITTER_HUE_AMOUNT 0.2 +#define DEFAULT_COLOR_JITTER_SAT_AMOUNT 0.2 +#define DEFAULT_COLOR_JITTER_VAL_AMOUNT 0.2 enum { @@ -80,7 +88,13 @@ PROP_GRADIENT_LENGTH, PROP_GRADIENT_UNIT, PROP_USE_JITTER, - PROP_JITTER_AMOUNT + PROP_JITTER_AMOUNT, + PROP_USE_SMUDGE, + PROP_SMUDGE_AMOUNT, + PROP_USE_COLOR_JITTER, + PROP_COLOR_JITTER_HUE_AMOUNT, + PROP_COLOR_JITTER_SAT_AMOUNT, + PROP_COLOR_JITTER_VAL_AMOUNT }; @@ -181,6 +195,35 @@ 0.0, 50.0, DEFAULT_JITTER_AMOUNT, 0); + + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_USE_SMUDGE, + "use-smudge", NULL, + DEFAULT_USE_SMUDGE, + 0); + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SMUDGE_AMOUNT, + "smudge-amount", NULL, + 0.0, 100.0, DEFAULT_SMUDGE_AMOUNT, + 0); + + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_USE_COLOR_JITTER, + "use-color-jitter", NULL, + DEFAULT_USE_COLOR_JITTER, + 0); + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_COLOR_JITTER_HUE_AMOUNT, + "color-jitter-hue-amount", NULL, + 0.0, 100.0, DEFAULT_COLOR_JITTER_HUE_AMOUNT, + 0); + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_COLOR_JITTER_SAT_AMOUNT, + "color-jitter-sat-amount", NULL, + 0.0, 100.0, DEFAULT_COLOR_JITTER_SAT_AMOUNT, + 0); + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_COLOR_JITTER_VAL_AMOUNT, + "color-jitter-val-amount", NULL, + 0.0, 100.0, DEFAULT_COLOR_JITTER_VAL_AMOUNT, + 0); + + + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_USE_GRADIENT, "use-gradient", NULL, DEFAULT_USE_GRADIENT, 0); @@ -211,6 +254,8 @@ options->fade_options = g_new0 (GimpFadeOptions, 1); options->gradient_options = g_new0 (GimpGradientOptions, 1); options->jitter_options = g_new0 (GimpJitterOptions, 1); + options->smudge_options = g_new0 (GimpPaintSmudgeOptions, 1); + options->color_jitter_options = g_new0 (GimpColorJitterOptions, 1); } static void @@ -225,6 +270,8 @@ g_free (options->fade_options); g_free (options->gradient_options); g_free (options->jitter_options); + g_free (options->smudge_options); + g_free (options->color_jitter_options); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -240,11 +287,15 @@ GimpFadeOptions *fade_options; GimpGradientOptions *gradient_options; GimpJitterOptions *jitter_options; + GimpPaintSmudgeOptions *smudge_options; + GimpColorJitterOptions *color_jitter_options; pressure_options = options->pressure_options; fade_options = options->fade_options; gradient_options = options->gradient_options; jitter_options = options->jitter_options; + smudge_options = options->smudge_options; + color_jitter_options = options->color_jitter_options; switch (property_id) { @@ -298,6 +349,13 @@ jitter_options->jitter_amount = g_value_get_double (value); break; + case PROP_USE_SMUDGE: + smudge_options->use_smudge = g_value_get_boolean (value); + break; + case PROP_SMUDGE_AMOUNT: + smudge_options->smudge_amount = g_value_get_double (value); + break; + case PROP_USE_GRADIENT: gradient_options->use_gradient = g_value_get_boolean (value); break; @@ -314,6 +372,19 @@ gradient_options->gradient_unit = g_value_get_int (value); break; + case PROP_USE_COLOR_JITTER: + color_jitter_options->use_color_jitter = g_value_get_boolean (value); + break; + case PROP_COLOR_JITTER_HUE_AMOUNT: + color_jitter_options->color_jitter_hue_amount = g_value_get_double(value); + break; + case PROP_COLOR_JITTER_SAT_AMOUNT: + color_jitter_options->color_jitter_sat_amount = g_value_get_double(value); + break; + case PROP_COLOR_JITTER_VAL_AMOUNT: + color_jitter_options->color_jitter_val_amount = g_value_get_double(value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -331,11 +402,15 @@ GimpFadeOptions *fade_options; GimpGradientOptions *gradient_options; GimpJitterOptions *jitter_options; + GimpPaintSmudgeOptions *smudge_options; + GimpColorJitterOptions *color_jitter_options; pressure_options = options->pressure_options; fade_options = options->fade_options; gradient_options = options->gradient_options; jitter_options = options->jitter_options; + smudge_options = options->smudge_options; + color_jitter_options = options->color_jitter_options; switch (property_id) { @@ -389,6 +464,13 @@ g_value_set_double (value, jitter_options->jitter_amount); break; + case PROP_USE_SMUDGE: + g_value_set_boolean (value, smudge_options->use_smudge); + break; + case PROP_SMUDGE_AMOUNT: + g_value_set_double (value, smudge_options->smudge_amount); + break; + case PROP_USE_GRADIENT: g_value_set_boolean (value, gradient_options->use_gradient); break; @@ -405,6 +487,19 @@ g_value_set_int (value, gradient_options->gradient_unit); break; + case PROP_USE_COLOR_JITTER: + g_value_set_boolean (value, color_jitter_options->use_color_jitter); + break; + case PROP_COLOR_JITTER_HUE_AMOUNT: + g_value_set_double (value, color_jitter_options->color_jitter_hue_amount); + break; + case PROP_COLOR_JITTER_SAT_AMOUNT: + g_value_set_double (value, color_jitter_options->color_jitter_sat_amount); + break; + case PROP_COLOR_JITTER_VAL_AMOUNT: + g_value_set_double (value, color_jitter_options->color_jitter_val_amount); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -503,6 +598,21 @@ return GIMP_OPACITY_OPAQUE; } + +gdouble +gimp_paint_options_get_smudge (GimpPaintOptions *paint_options) +{ + GimpPaintSmudgeOptions *smudge_options; + + smudge_options = paint_options->smudge_options; + + if (smudge_options->use_smudge) + return smudge_options->smudge_amount; + + return 0.0; +} + + gdouble gimp_paint_options_get_jitter (GimpPaintOptions *paint_options, GimpImage *gimage) @@ -516,6 +626,20 @@ return 0.0; } + + +GimpColorJitterOptions * +gimp_paint_options_get_color_jitter (GimpPaintOptions *paint_options, + GimpImage *gimage) +{ + GimpColorJitterOptions *color_jitter_options; + + color_jitter_options = paint_options->color_jitter_options; + + return color_jitter_options; + +} + gboolean gimp_paint_options_get_gradient_color (GimpPaintOptions *paint_options, Index: app/paint/gimppaintoptions.h =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimppaintoptions.h,v retrieving revision 1.21 diff -u -r1.21 gimppaintoptions.h --- app/paint/gimppaintoptions.h 3 Oct 2005 19:03:13 -0000 1.21 +++ app/paint/gimppaintoptions.h 15 Dec 2005 19:45:39 -0000 @@ -34,6 +34,8 @@ typedef struct _GimpFadeOptions GimpFadeOptions; typedef struct _GimpGradientOptions GimpGradientOptions; typedef struct _GimpJitterOptions GimpJitterOptions; +typedef struct _GimpPaintSmudgeOptions GimpPaintSmudgeOptions; +typedef struct _GimpColorJitterOptions GimpColorJitterOptions; struct _GimpPressureOptions { @@ -59,6 +61,14 @@ gdouble jitter_amount; }; + +struct _GimpPaintSmudgeOptions +{ + gboolean use_smudge; + gdouble smudge_amount; +}; + + struct _GimpGradientOptions { gboolean use_gradient; @@ -68,6 +78,15 @@ GimpRepeatMode gradient_repeat; }; +struct _GimpColorJitterOptions +{ + gboolean use_color_jitter; + gdouble color_jitter_hue_amount; + gdouble color_jitter_sat_amount; + gdouble color_jitter_val_amount; +}; + + #define GIMP_TYPE_PAINT_OPTIONS (gimp_paint_options_get_type ()) #define GIMP_PAINT_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINT_OPTIONS, GimpPaintOptions)) @@ -94,6 +113,8 @@ GimpFadeOptions *fade_options; GimpGradientOptions *gradient_options; GimpJitterOptions *jitter_options; + GimpPaintSmudgeOptions *smudge_options; + GimpColorJitterOptions *color_jitter_options; }; struct _GimpPaintOptionsClass @@ -116,8 +137,15 @@ gdouble pixel_dist, GimpRGB *color); -gdouble gimp_paint_options_get_jitter (GimpPaintOptions *paint_options, - GimpImage *gimage); +gdouble gimp_paint_options_get_smudge (GimpPaintOptions *paint_options); + +gdouble gimp_paint_options_get_jitter (GimpPaintOptions *paint_options, + GimpImage *gimage); + + +GimpColorJitterOptions * gimp_paint_options_get_color_jitter (GimpPaintOptions *paint_options, + GimpImage *gimage); + GimpBrushApplicationMode gimp_paint_options_get_brush_mode (GimpPaintOptions *paint_options); Index: app/paint/gimpsmudge.c =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimpsmudge.c,v retrieving revision 1.71 diff -u -r1.71 gimpsmudge.c --- app/paint/gimpsmudge.c 7 Dec 2005 21:11:53 -0000 1.71 +++ app/paint/gimpsmudge.c 15 Dec 2005 19:45:39 -0000 @@ -43,11 +43,7 @@ static void gimp_smudge_finalize (GObject *object); -static void gimp_smudge_paint (GimpPaintCore *paint_core, - GimpDrawable *drawable, - GimpPaintOptions *paint_options, - GimpPaintState paint_state, - guint32 time); + static gboolean gimp_smudge_start (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options); @@ -94,25 +90,26 @@ static void gimp_smudge_init (GimpSmudge *smudge) { - smudge->initialized = FALSE; - smudge->accum_data = NULL; + } static void gimp_smudge_finalize (GObject *object) { GimpSmudge *smudge = GIMP_SMUDGE (object); + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (object); - if (smudge->accum_data) + + if (brush_core->accum_data) { - g_free (smudge->accum_data); - smudge->accum_data = NULL; + g_free (brush_core->accum_data); + brush_core->accum_data = NULL; } G_OBJECT_CLASS (parent_class)->finalize (object); } -static void +void gimp_smudge_paint (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, @@ -120,26 +117,28 @@ guint32 time) { GimpSmudge *smudge = GIMP_SMUDGE (paint_core); + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); + switch (paint_state) { case GIMP_PAINT_STATE_MOTION: /* initialization fails if the user starts outside the drawable */ - if (! smudge->initialized) - smudge->initialized = gimp_smudge_start (paint_core, drawable, - paint_options); + if (! brush_core->initialized) + brush_core->initialized = gimp_smudge_start (paint_core, drawable, + paint_options); - if (smudge->initialized) + if (brush_core->initialized) gimp_smudge_motion (paint_core, drawable, paint_options); break; case GIMP_PAINT_STATE_FINISH: - if (smudge->accum_data) + if (brush_core->accum_data) { - g_free (smudge->accum_data); - smudge->accum_data = NULL; + g_free (brush_core->accum_data); + brush_core->accum_data = NULL; } - smudge->initialized = FALSE; + brush_core->initialized = FALSE; break; default: @@ -155,6 +154,8 @@ GimpPaintOptions *paint_options) { GimpSmudge *smudge = GIMP_SMUDGE (paint_core); + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); + GimpImage *gimage; TempBuf *area; PixelRegion srcPR; @@ -173,10 +174,10 @@ /* adjust the x and y coordinates to the upper left corner of the brush */ gimp_smudge_nonclipped_painthit_coords (paint_core, &x, &y, &w, &h); - + /* Allocate the accumulation buffer */ bytes = gimp_drawable_bytes (drawable); - smudge->accum_data = g_malloc (w * h * bytes); + brush_core->accum_data = g_malloc (w * h * bytes); /* If clipped, prefill the smudge buffer with the color at the brush position. */ @@ -191,7 +192,7 @@ 0, gimp_item_height (GIMP_ITEM (drawable)) - 1)); g_return_val_if_fail (fill != NULL, FALSE); - pixel_region_init_data (&srcPR, smudge->accum_data, + pixel_region_init_data (&srcPR, brush_core->accum_data, bytes, bytes * w, 0, 0, w, h); @@ -202,7 +203,7 @@ pixel_region_init (&srcPR, gimp_drawable_data (drawable), area->x, area->y, area->width, area->height, FALSE); - pixel_region_init_data (&smudge->accumPR, smudge->accum_data, + pixel_region_init_data (&brush_core->accumPR, brush_core->accum_data, bytes, bytes * w, area->x - x, area->y - y, @@ -210,9 +211,9 @@ area->height); /* copy the region under the original painthit. */ - copy_region (&srcPR, &smudge->accumPR); + copy_region (&srcPR, &brush_core->accumPR); - pixel_region_init_data (&smudge->accumPR, smudge->accum_data, + pixel_region_init_data (&brush_core->accumPR, brush_core->accum_data, bytes, bytes * w, area->x - x, area->y - y, @@ -228,6 +229,7 @@ GimpPaintOptions *paint_options) { GimpSmudge *smudge = GIMP_SMUDGE (paint_core); + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); GimpSmudgeOptions *options = GIMP_SMUDGE_OPTIONS (paint_options); GimpContext *context = GIMP_CONTEXT (paint_options); GimpPressureOptions *pressure_options = paint_options->pressure_options; @@ -267,9 +269,9 @@ rate = options->rate / 100.0; /* The tempPR will be the built up buffer (for smudge) */ - pixel_region_init_data (&tempPR, smudge->accum_data, - smudge->accumPR.bytes, - smudge->accumPR.rowstride, + pixel_region_init_data (&tempPR, brush_core->accum_data, + brush_core->accumPR.bytes, + brush_core->accumPR.rowstride, area->x - x, area->y - y, area->width, @@ -290,9 +292,9 @@ blend_region (&srcPR, &tempPR, &tempPR, ROUND (rate * 255.0)); /* re-init the tempPR */ - pixel_region_init_data (&tempPR, smudge->accum_data, - smudge->accumPR.bytes, - smudge->accumPR.rowstride, + pixel_region_init_data (&tempPR, brush_core->accum_data, + brush_core->accumPR.bytes, + brush_core->accumPR.rowstride, area->x - x, area->y - y, area->width, Index: app/paint/gimpsmudge.h =================================================================== RCS file: /cvs/gnome/gimp/app/paint/gimpsmudge.h,v retrieving revision 1.18 diff -u -r1.18 gimpsmudge.h --- app/paint/gimpsmudge.h 25 May 2004 20:41:09 -0000 1.18 +++ app/paint/gimpsmudge.h 15 Dec 2005 19:45:39 -0000 @@ -56,5 +56,10 @@ GType gimp_smudge_get_type (void) G_GNUC_CONST; +void gimp_smudge_paint (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + GimpPaintState paint_state, + guint32 time); #endif /* __GIMP_SMUDGE_H__ */ Index: app/paint-funcs/paint-funcs.c =================================================================== RCS file: /cvs/gnome/gimp/app/paint-funcs/paint-funcs.c,v retrieving revision 1.182 diff -u -r1.182 paint-funcs.c --- app/paint-funcs/paint-funcs.c 9 Nov 2005 09:55:45 -0000 1.182 +++ app/paint-funcs/paint-funcs.c 15 Dec 2005 19:45:39 -0000 @@ -2105,7 +2105,7 @@ off_y + dest->y + y); d += dest->rowstride; - if (mask) + if (mask) m += mask->rowstride; } } @@ -4275,6 +4275,7 @@ { hint = TILEROWHINT_UNDEFINED; + printf("paint-funcs.c: %i\n", h); if (transparency_quickskip_possible) { hint = tile_get_rowhint (src2->curtile, (src2->offy + h)); @@ -4578,6 +4579,7 @@ default: has_alpha1 = has_alpha2 = FALSE; } + st.opacity = opacity; st.mode = mode; Index: app/tools/gimppaintoptions-gui.c =================================================================== RCS file: /cvs/gnome/gimp/app/tools/gimppaintoptions-gui.c,v retrieving revision 1.111 diff -u -r1.111 gimppaintoptions-gui.c --- app/tools/gimppaintoptions-gui.c 19 Nov 2005 22:19:14 -0000 1.111 +++ app/tools/gimppaintoptions-gui.c 15 Dec 2005 19:45:39 -0000 @@ -68,6 +68,15 @@ GimpPaintOptions *paint_options, GType tool_type); +static GtkWidget * smudge_options_gui (GimpPaintSmudgeOptions *smudge, + GimpPaintOptions *paint_options, + GType tool_type); + +static GtkWidget * color_jitter_options_gui (GimpColorJitterOptions *color_jitter, + GimpPaintOptions *paint_options, + GType tool_type); + + /* public functions */ GtkWidget * @@ -163,7 +172,27 @@ gtk_widget_show (frame); } + + frame = smudge_options_gui (options->smudge_options, + options, tool_type); + + if (frame) + { + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + } + + + frame = color_jitter_options_gui (options->color_jitter_options, + options, tool_type); + if (frame) + { + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + } + /* the "incremental" toggle */ + if (tool_type == GIMP_TYPE_PENCIL_TOOL || tool_type == GIMP_TYPE_PAINTBRUSH_TOOL || tool_type == GIMP_TYPE_ERASER_TOOL) @@ -370,6 +399,57 @@ } static GtkWidget * +smudge_options_gui (GimpPaintSmudgeOptions *smudge, + GimpPaintOptions *paint_options, + GType tool_type) +{ + GObject *config = G_OBJECT (paint_options); + GtkWidget *frame = NULL; + GtkWidget *table; + GtkWidget *spinbutton; + GtkWidget *button; + + if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL) || + tool_type == GIMP_TYPE_CLONE_TOOL || + tool_type == GIMP_TYPE_CONVOLVE_TOOL || + tool_type == GIMP_TYPE_DODGE_BURN_TOOL || + tool_type == GIMP_TYPE_ERASER_TOOL || + tool_type == GIMP_TYPE_SMUDGE_TOOL) + { + frame = gimp_frame_new (NULL); + + button = gimp_prop_check_button_new (config, "use-smudge", + _("Apply Smudge")); + + gtk_frame_set_label_widget (GTK_FRAME (frame), button); + gtk_widget_show (button); + + table = gtk_table_new (1, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_container_add (GTK_CONTAINER (frame), table); + if (smudge->use_smudge) + gtk_widget_show (table); + + g_signal_connect_object (button, "toggled", + G_CALLBACK (gimp_toggle_button_set_visible), + table, 0); + + spinbutton = gimp_prop_spin_button_new (config, "smudge-amount", + 0.1, 1, 2); + + + gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 6); + + gimp_table_attach_aligned (GTK_TABLE (table), 0, 0, + _("Amount:"), 0.0, 0.5, + spinbutton, 1, FALSE); + + } + return frame; + +} + +static GtkWidget * jitter_options_gui (GimpJitterOptions *jitter, GimpPaintOptions *paint_options, GType tool_type) @@ -413,6 +493,61 @@ } return frame; +} + +static GtkWidget * +color_jitter_options_gui (GimpColorJitterOptions *color_jitter, + GimpPaintOptions *paint_options, + GType tool_type) +{ + GObject *config = G_OBJECT (paint_options); + GtkWidget *frame = NULL; + + if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL)) + { + GtkWidget *table; + GtkWidget *button; + + + frame = gimp_frame_new (NULL); + + button = gimp_prop_check_button_new (config, "use-color-jitter", + _("Apply Color Jitter")); + + gtk_frame_set_label_widget (GTK_FRAME (frame), button); + gtk_widget_show(button); + + table = gtk_table_new (1, 5, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_container_add (GTK_CONTAINER (frame), table); + + if (color_jitter->use_color_jitter) + gtk_widget_show (table); + + g_signal_connect_object (button, "toggled", + G_CALLBACK (gimp_toggle_button_set_visible), + table, 0); + + gimp_prop_scale_entry_new (config, "color-jitter-hue-amount", + GTK_TABLE (table), 0, 0, + _("Hue:"), + 0.01, 0.1, 2, + TRUE, 0.0, 1.0); + gimp_prop_scale_entry_new (config, "color-jitter-sat-amount", + GTK_TABLE (table), 0, 1, + _("Saturation:"), + 0.01, 0.1, 2, + TRUE, 0.0, 1.0); + gimp_prop_scale_entry_new (config, "color-jitter-val-amount", + GTK_TABLE (table), 0, 2, + _("Value:"), + 0.01, 0.1, 2, + TRUE, 0.0, 1.0); + + } + return frame; + + } static GtkWidget *