gimp r25758 - in trunk: . app/core app/display app/paint app/tools



Author: mitch
Date: Thu May 22 16:38:57 2008
New Revision: 25758
URL: http://svn.gnome.org/viewvc/gimp?rev=25758&view=rev

Log:
2008-05-22  Michael Natterer  <mitch gimp org>

	Applied slightly modified and fixed patch from Alexia Death which
	adds a "random" axis to the paint dynamics and fixes some issues
	in the previous paint dynamics commits. Fixes bug #529431.

	* app/core/core-types.h: add a "random" axis to GimpCoords.

	* app/display/gimpdisplayshell-coords.c: set it to a random value.

	* app/display/gimpdisplayshell-callbacks.c: on button_press,
	use the dynamics from the last motion event to avoid blotches
	at the beginning of paint strokes.

	* app/paint/gimppaintoptions.[ch]: add random properties the same
	way we do pressure and velocity. Add get_dynamic_size(),
	get_dynamic_color() and get_dynamic_hardness() functions which
	look at all dynamic parameters of the passed coords.

	* app/tools/gimppaintoptions-gui.c: add gui for the random options.

	* app/paint/gimpbrushcore.[ch]: remove calc_brush_scale() and use
	gimp_paint_options_get_dynamic_size_instead().
	Add "dynamic_hardness" parameters to paste_canvas(),
	replace_canvas() and get_brush_mask().

	* app/paint/gimpairbrushoptions.c
	* app/paint/gimpclone.c
	* app/paint/gimpconvolve.c
	* app/paint/gimpdodgeburn.c
	* app/paint/gimperaser.c
	* app/paint/gimpheal.c
	* app/paint/gimppaintbrush.c
	* app/paint/gimpsmudge.c: calculate the dynamic hardness and pass
	it to above brush core functions. Use the get_dynamic_color() to
	calculate the gradient color.



Modified:
   trunk/ChangeLog
   trunk/app/core/core-types.h
   trunk/app/display/gimpdisplayshell-callbacks.c
   trunk/app/display/gimpdisplayshell-coords.c
   trunk/app/paint/gimpairbrushoptions.c
   trunk/app/paint/gimpbrushcore.c
   trunk/app/paint/gimpbrushcore.h
   trunk/app/paint/gimpclone.c
   trunk/app/paint/gimpconvolve.c
   trunk/app/paint/gimpdodgeburn.c
   trunk/app/paint/gimperaser.c
   trunk/app/paint/gimpheal.c
   trunk/app/paint/gimppaintbrush.c
   trunk/app/paint/gimppaintoptions.c
   trunk/app/paint/gimppaintoptions.h
   trunk/app/paint/gimpsmudge.c
   trunk/app/tools/gimppaintoptions-gui.c

Modified: trunk/app/core/core-types.h
==============================================================================
--- trunk/app/core/core-types.h	(original)
+++ trunk/app/core/core-types.h	Thu May 22 16:38:57 2008
@@ -204,6 +204,7 @@
   gdouble delta_y;
   gdouble distance;
   gdouble velocity;
+  gdouble random;
 };
 
 

Modified: trunk/app/display/gimpdisplayshell-callbacks.c
==============================================================================
--- trunk/app/display/gimpdisplayshell-callbacks.c	(original)
+++ trunk/app/display/gimpdisplayshell-callbacks.c	Thu May 22 16:38:57 2008
@@ -810,6 +810,23 @@
 
                 if (initialized)
                   {
+                    /* Use the last evaluated dynamic axes instead of
+                     * the button_press event's ones because the click
+                     * is usually at the same spot as the last motion
+                     * event which would give us bogus dynamics.
+                     */
+                    GimpCoords tmp_coords;
+
+                    tmp_coords = shell->last_coords;
+
+                    tmp_coords.x        = image_coords.x;
+                    tmp_coords.y        = image_coords.y;
+                    tmp_coords.pressure = image_coords.pressure;
+                    tmp_coords.xtilt    = image_coords.xtilt;
+                    tmp_coords.ytilt    = image_coords.ytilt;
+
+                    image_coords = tmp_coords;
+
                     tool_manager_button_press_active (gimp,
                                                       &image_coords,
                                                       time, state, display);

Modified: trunk/app/display/gimpdisplayshell-coords.c
==============================================================================
--- trunk/app/display/gimpdisplayshell-coords.c	(original)
+++ trunk/app/display/gimpdisplayshell-coords.c	Thu May 22 16:38:57 2008
@@ -226,7 +226,7 @@
       /* First pair is invalid to do any velocity calculation,
        * so we apply constant values.
        */
-      coords->velocity   = 100;
+      coords->velocity   = 1.0;
       coords->delta_time = 0.001;
       coords->distance   = 1;
     }
@@ -252,6 +252,8 @@
                             + coords->delta_time * SMOOTH_FACTOR);
       coords->distance = dist = sqrt (SQR (dx) + SQR (dy));
 
+      coords->random = g_random_double_range (0.0, 1.0);
+
       /* If even smoothed time resolution does not allow to guess for speed,
        * use last velocity.
        */

Modified: trunk/app/paint/gimpairbrushoptions.c
==============================================================================
--- trunk/app/paint/gimpairbrushoptions.c	(original)
+++ trunk/app/paint/gimpairbrushoptions.c	Thu May 22 16:38:57 2008
@@ -36,7 +36,8 @@
   PROP_0,
   PROP_RATE,
   PROP_PRESSURE,
-  PROP_VELOCITY_SIZE
+  PROP_VELOCITY_SIZE,
+  PROP_VELOCITY_HARDNESS
 };
 
 
@@ -71,11 +72,17 @@
                                    0.0, 100.0, AIRBRUSH_DEFAULT_PRESSURE,
                                    GIMP_PARAM_STATIC_STRINGS);
 
-  /* override velocity size because its unavaliable to the airbrush */
+  /* override velocity size because its unnatural as a default for airbrush */
   GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_VELOCITY_SIZE,
                                     "velocity-size", NULL,
                                     FALSE,
                                     GIMP_PARAM_STATIC_STRINGS);
+  
+  /* override velocity hardness to default to a true, because that is natural for airbrush */
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_VELOCITY_HARDNESS,
+                                    "velocity-hardness", NULL,
+                                    TRUE,
+                                    GIMP_PARAM_STATIC_STRINGS);
 }
 
 static void
@@ -102,6 +109,9 @@
     case PROP_VELOCITY_SIZE:
       GIMP_PAINT_OPTIONS (options)->velocity_options->size = g_value_get_boolean (value);
       break;
+    case PROP_VELOCITY_HARDNESS:
+      GIMP_PAINT_OPTIONS (options)->velocity_options->hardness = g_value_get_boolean (value);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -128,6 +138,9 @@
     case PROP_VELOCITY_SIZE:
       g_value_set_boolean (value, GIMP_PAINT_OPTIONS (options)->velocity_options->size);
       break;
+    case PROP_VELOCITY_HARDNESS:
+      g_value_set_boolean (value, GIMP_PAINT_OPTIONS (options)->velocity_options->hardness);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);

Modified: trunk/app/paint/gimpbrushcore.c
==============================================================================
--- trunk/app/paint/gimpbrushcore.c	(original)
+++ trunk/app/paint/gimpbrushcore.c	Thu May 22 16:38:57 2008
@@ -85,11 +85,6 @@
 static void     gimp_brush_core_real_set_brush    (GimpBrushCore    *core,
                                                    GimpBrush        *brush);
 
-static gdouble  gimp_brush_core_calc_brush_scale  (GimpBrushCore    *core,
-                                                   GimpPaintOptions *paint_options,
-                                                   gdouble           pressure,
-                                                   gdouble           velocity);
-
 static inline void rotate_pointers                (gulong          **p,
                                                    guint32           n);
 static TempBuf * gimp_brush_core_subsample_mask   (GimpBrushCore    *core,
@@ -358,9 +353,10 @@
       return FALSE;
     }
 
-  core->scale = gimp_brush_core_calc_brush_scale (core, paint_options,
-                                                  coords->pressure,
-                                                  coords->velocity);
+  core->scale = gimp_paint_options_get_dynamic_size (paint_options,
+                                                     coords,
+                                                     paint_core->use_pressure,
+                                                     GIMP_BRUSH_CORE_GET_CLASS (core)->handles_scaling_brush);
 
   core->spacing = (gdouble) gimp_brush_get_spacing (core->main_brush) / 100.0;
 
@@ -673,6 +669,7 @@
   paint_core->cur_coords.ytilt    = paint_core->last_coords.ytilt    + delta_ytilt;
   paint_core->cur_coords.wheel    = paint_core->last_coords.wheel    + delta_wheel;
   paint_core->cur_coords.velocity = paint_core->last_coords.velocity + delta_velocity;
+  paint_core->cur_coords.random   = g_random_double_range (0.0, 1.0);
 
   paint_core->distance   = total;
   paint_core->pixel_dist = pixel_initial + pixel_dist;
@@ -693,9 +690,10 @@
 
   if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_scaling_brush)
     {
-      core->scale = gimp_brush_core_calc_brush_scale (core, paint_options,
-                                                      paint_core->cur_coords.pressure,
-                                                      paint_core->cur_coords.velocity);
+      core->scale = gimp_paint_options_get_dynamic_size (paint_options,
+                                                         &paint_core->cur_coords,
+                                                         paint_core->use_pressure,
+                                                         TRUE);
     }
   /* else use scale from start(), we don't support on-the-fly scaling */
 
@@ -833,10 +831,12 @@
                               gdouble                   image_opacity,
                               GimpLayerModeEffects      paint_mode,
                               GimpBrushApplicationMode  brush_hardness,
+                              gdouble                   dynamic_hardness,
                               GimpPaintApplicationMode  mode)
 {
   TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core,
-                                                        brush_hardness);
+                                                        brush_hardness,
+                                                        dynamic_hardness);
 
   if (brush_mask)
     {
@@ -875,10 +875,12 @@
                                 gdouble                   brush_opacity,
                                 gdouble                   image_opacity,
                                 GimpBrushApplicationMode  brush_hardness,
+                                gdouble                   dynamic_hardness,
                                 GimpPaintApplicationMode  mode)
 {
   TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core,
-                                                        brush_hardness);
+                                                        brush_hardness,
+                                                        dynamic_hardness);
 
   if (brush_mask)
     {
@@ -927,53 +929,6 @@
  *             LOCAL FUNCTION DEFINITIONS                   *
  ************************************************************/
 
-static gdouble
-gimp_brush_core_calc_brush_scale (GimpBrushCore    *core,
-                                  GimpPaintOptions *paint_options,
-                                  gdouble           pressure,
-                                  gdouble           velocity)
-{
-  gdouble scale = 1.0;
-
-  if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_scaling_brush)
-    {
-      if (! (GIMP_PAINT_CORE (core)->use_pressure           &&
-             (paint_options->pressure_options->inverse_size ||
-              paint_options->pressure_options->size)))
-        {
-          pressure = -1;
-        }
-      else if (paint_options->pressure_options->inverse_size)
-        {
-          pressure = 1.0 - 0.9 * pressure;
-        }
-
-      if (paint_options->velocity_options->size)
-        {
-          velocity = 1.0 - sqrt (velocity);
-        }
-      else if (paint_options->velocity_options->inverse_size)
-        {
-          velocity = sqrt (velocity);
-        }
-      else
-        {
-          velocity = -1;
-        }
-
-      scale = gimp_paint_options_get_dynamics_mix (pressure, velocity);
-
-      if (scale < 1 / 64.0)
-        scale = 1 / 8.0;
-      else
-        scale = sqrt (scale);
-    }
-
-  scale *= paint_options->brush_scale;
-
-  return scale;
-}
-
 static inline void
 rotate_pointers (gulong  **p,
                  guint32   n)
@@ -1393,12 +1348,11 @@
 
 TempBuf *
 gimp_brush_core_get_brush_mask (GimpBrushCore            *core,
-                                GimpBrushApplicationMode  brush_hardness)
+                                GimpBrushApplicationMode  brush_hardness,
+                                gdouble                   dynamic_hardness)
 {
   GimpPaintCore *paint_core = GIMP_PAINT_CORE (core);
   TempBuf       *mask;
-  gdouble        pressure;
-  gdouble        velocity;
 
   mask = gimp_brush_core_scale_mask (core, core->brush);
 
@@ -1420,17 +1374,10 @@
       break;
 
     case GIMP_BRUSH_PRESSURE:
-      if (! paint_core->use_pressure)
-        pressure = -1.0;
-      else
-        pressure = GIMP_PAINT_PRESSURE_SCALE * paint_core->cur_coords.pressure;
-
-      velocity = GIMP_PAINT_VELOCITY_SCALE * paint_core->cur_coords.velocity;
-
       mask = gimp_brush_core_pressurize_mask (core, mask,
                                               paint_core->cur_coords.x,
                                               paint_core->cur_coords.y,
-                                              gimp_paint_options_get_dynamics_mix (pressure, velocity));
+                                              dynamic_hardness);
       break;
 
     default:

Modified: trunk/app/paint/gimpbrushcore.h
==============================================================================
--- trunk/app/paint/gimpbrushcore.h	(original)
+++ trunk/app/paint/gimpbrushcore.h	Thu May 22 16:38:57 2008
@@ -111,12 +111,14 @@
                                         gdouble                   image_opacity,
                                         GimpLayerModeEffects      paint_mode,
                                         GimpBrushApplicationMode  brush_hardness,
+                                        gdouble                   dynamic_hardness,
                                         GimpPaintApplicationMode  mode);
 void    gimp_brush_core_replace_canvas (GimpBrushCore            *core,
                                         GimpDrawable             *drawable,
                                         gdouble                   brush_opacity,
                                         gdouble                   image_opacity,
                                         GimpBrushApplicationMode  brush_hardness,
+                                        gdouble                   dynamic_hardness,
                                         GimpPaintApplicationMode  mode);
 
 void    gimp_brush_core_color_area_with_pixmap
@@ -126,7 +128,8 @@
                                           GimpBrushApplicationMode  mode);
 
 TempBuf * gimp_brush_core_get_brush_mask (GimpBrushCore            *core,
-                                          GimpBrushApplicationMode  brush_hardness);
+                                          GimpBrushApplicationMode  brush_hardness,
+                                          gdouble                   dynamic_hardness);
 
 
 #endif  /*  __GIMP_BRUSH_CORE_H__  */

Modified: trunk/app/paint/gimpclone.c
==============================================================================
--- trunk/app/paint/gimpclone.c	(original)
+++ trunk/app/paint/gimpclone.c	Thu May 22 16:38:57 2008
@@ -172,6 +172,7 @@
   gint               y;
   PixelRegion        destPR;
   GimpPattern       *pattern = NULL;
+  gdouble            hardness;
 
   image = gimp_item_get_image (GIMP_ITEM (drawable));
 
@@ -239,11 +240,16 @@
                                                      &paint_core->cur_coords,
                                                      paint_core->use_pressure);
 
+  hardness = gimp_paint_options_get_dynamic_hardness (paint_options,
+                                                      &paint_core->cur_coords,
+                                                      paint_core->use_pressure);
+
   gimp_brush_core_paste_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
                                 MIN (opacity, GIMP_OPACITY_OPAQUE),
                                 gimp_context_get_opacity (context),
                                 gimp_context_get_paint_mode (context),
                                 gimp_paint_options_get_brush_mode (paint_options),
+                                hardness,
 
                                 /* In fixed mode, paint incremental so the
                                  * individual brushes are properly applied

Modified: trunk/app/paint/gimpconvolve.c
==============================================================================
--- trunk/app/paint/gimpconvolve.c	(original)
+++ trunk/app/paint/gimpconvolve.c	Thu May 22 16:38:57 2008
@@ -211,6 +211,7 @@
                                   MIN (opacity, GIMP_OPACITY_OPAQUE),
                                   gimp_context_get_opacity (context),
                                   gimp_paint_options_get_brush_mode (paint_options),
+                                  1.0,
                                   GIMP_PAINT_INCREMENTAL);
 }
 

Modified: trunk/app/paint/gimpdodgeburn.c
==============================================================================
--- trunk/app/paint/gimpdodgeburn.c	(original)
+++ trunk/app/paint/gimpdodgeburn.c	Thu May 22 16:38:57 2008
@@ -170,6 +170,7 @@
   PixelRegion    srcPR, destPR, tempPR;
   guchar        *temp_data;
   gdouble        opacity;
+  gdouble        hardness;
 
   image = gimp_item_get_image (GIMP_ITEM (drawable));
 
@@ -239,11 +240,16 @@
                                                      &paint_core->cur_coords,
                                                      paint_core->use_pressure);
 
+  hardness = gimp_paint_options_get_dynamic_hardness (paint_options,
+                                                      &paint_core->cur_coords,
+                                                      paint_core->use_pressure);
+
   /* Replace the newly dodgedburned area (canvas_buf) to the image */
   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),
+                                  hardness,
                                   GIMP_PAINT_CONSTANT);
 }
 

Modified: trunk/app/paint/gimperaser.c
==============================================================================
--- trunk/app/paint/gimperaser.c	(original)
+++ trunk/app/paint/gimperaser.c	Thu May 22 16:38:57 2008
@@ -108,6 +108,7 @@
   gdouble            opacity;
   TempBuf           *area;
   guchar             col[MAX_CHANNELS];
+  gdouble            hardness;
 
   image = gimp_item_get_image (GIMP_ITEM (drawable));
 
@@ -134,11 +135,16 @@
                                                      &paint_core->cur_coords,
                                                      paint_core->use_pressure);
 
+  hardness = gimp_paint_options_get_dynamic_hardness (paint_options,
+                                                      &paint_core->cur_coords,
+                                                      paint_core->use_pressure);
+
   gimp_brush_core_paste_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
                                 MIN (opacity, GIMP_OPACITY_OPAQUE),
                                 gimp_context_get_opacity (context),
                                 (options->anti_erase ?
                                  GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE),
                                 gimp_paint_options_get_brush_mode (paint_options),
+                                hardness,
                                 paint_options->application_mode);
 }

Modified: trunk/app/paint/gimpheal.c
==============================================================================
--- trunk/app/paint/gimpheal.c	(original)
+++ trunk/app/paint/gimpheal.c	Thu May 22 16:38:57 2008
@@ -435,9 +435,15 @@
   PixelRegion    destPR;
   GimpImageType  src_type;
   TempBuf       *mask_buf;
+  gdouble        hardness;
+
+  hardness = gimp_paint_options_get_dynamic_hardness (paint_options,
+                                                      &paint_core->cur_coords,
+                                                      paint_core->use_pressure);
 
   mask_buf = gimp_brush_core_get_brush_mask (GIMP_BRUSH_CORE (source_core),
-                                             GIMP_BRUSH_HARD);
+                                             GIMP_BRUSH_HARD,
+                                             hardness);
 
   src_type = gimp_pickable_get_image_type (src_pickable);
 
@@ -550,5 +556,6 @@
                                   MIN (opacity, GIMP_OPACITY_OPAQUE),
                                   gimp_context_get_opacity (context),
                                   gimp_paint_options_get_brush_mode (paint_options),
+                                  hardness,
                                   GIMP_PAINT_INCREMENTAL);
 }

Modified: trunk/app/paint/gimppaintbrush.c
==============================================================================
--- trunk/app/paint/gimppaintbrush.c	(original)
+++ trunk/app/paint/gimppaintbrush.c	Thu May 22 16:38:57 2008
@@ -114,7 +114,8 @@
   TempBuf                  *area;
   guchar                    col[MAX_CHANNELS];
   GimpPaintApplicationMode  paint_appl_mode;
-  gdouble                   colmix = 0.0;
+  gdouble                   grad_point;
+  gdouble                   hardness;
 
   image = gimp_item_get_image (GIMP_ITEM (drawable));
 
@@ -127,28 +128,15 @@
   if (! area)
     return;
 
-  if (paint_core->use_pressure &&
-      pressure_options->color  &&
-      velocity_options->color)
-    {
-      colmix = (paint_core->cur_coords.pressure * 0.5 +
-                paint_core->cur_coords.velocity * 0.5);
-    }
-  else if (paint_core->use_pressure &&
-           pressure_options->color)
-    {
-      colmix = paint_core->cur_coords.pressure;
-    }
-  else if (velocity_options->color)
-    {
-      colmix = paint_core->cur_coords.velocity;
-    }
-
   paint_appl_mode = paint_options->application_mode;
 
+  grad_point = gimp_paint_options_get_dynamic_color (paint_options,
+                                                     &paint_core->cur_coords,
+                                                     paint_core->use_pressure);
+
   /* optionally take the color from the current gradient */
   if (gimp_paint_options_get_gradient_color (paint_options, image,
-                                             colmix,
+                                             grad_point,
                                              paint_core->pixel_dist,
                                              &gradient_color))
     {
@@ -192,11 +180,16 @@
                                                      &paint_core->cur_coords,
                                                      paint_core->use_pressure);
 
+  hardness = gimp_paint_options_get_dynamic_hardness (paint_options,
+                                                      &paint_core->cur_coords,
+                                                      paint_core->use_pressure);
+
   /* finally, let the brush core paste the colored area on the canvas */
   gimp_brush_core_paste_canvas (brush_core, drawable,
                                 MIN (opacity, GIMP_OPACITY_OPAQUE),
                                 gimp_context_get_opacity (context),
                                 gimp_context_get_paint_mode (context),
                                 gimp_paint_options_get_brush_mode (paint_options),
+                                hardness,
                                 paint_appl_mode);
 }

Modified: trunk/app/paint/gimppaintoptions.c
==============================================================================
--- trunk/app/paint/gimppaintoptions.c	(original)
+++ trunk/app/paint/gimppaintoptions.c	Thu May 22 16:38:57 2008
@@ -54,6 +54,14 @@
 #define DEFAULT_VELOCITY_INVERSE_SIZE FALSE
 #define DEFAULT_VELOCITY_COLOR        FALSE
 
+#define DEFAULT_RANDOM_EXPANDED       FALSE
+#define DEFAULT_RANDOM_OPACITY        FALSE
+#define DEFAULT_RANDOM_HARDNESS       FALSE
+#define DEFAULT_RANDOM_RATE           FALSE
+#define DEFAULT_RANDOM_SIZE           FALSE
+#define DEFAULT_RANDOM_INVERSE_SIZE   FALSE
+#define DEFAULT_RANDOM_COLOR          FALSE
+
 #define DEFAULT_USE_FADE              FALSE
 #define DEFAULT_FADE_LENGTH           100.0
 #define DEFAULT_FADE_UNIT             GIMP_UNIT_PIXEL
@@ -93,6 +101,14 @@
   PROP_VELOCITY_INVERSE_SIZE,
   PROP_VELOCITY_COLOR,
 
+  PROP_RANDOM_EXPANDED,
+  PROP_RANDOM_OPACITY,
+  PROP_RANDOM_HARDNESS,
+  PROP_RANDOM_RATE,
+  PROP_RANDOM_SIZE,
+  PROP_RANDOM_INVERSE_SIZE,
+  PROP_RANDOM_COLOR,
+
   PROP_USE_FADE,
   PROP_FADE_LENGTH,
   PROP_FADE_UNIT,
@@ -115,17 +131,21 @@
 };
 
 
-static void   gimp_paint_options_finalize     (GObject      *object);
-static void   gimp_paint_options_set_property (GObject      *object,
-                                               guint         property_id,
-                                               const GValue *value,
-                                               GParamSpec   *pspec);
-static void   gimp_paint_options_get_property (GObject      *object,
-                                               guint         property_id,
-                                               GValue       *value,
-                                               GParamSpec   *pspec);
-static void   gimp_paint_options_notify       (GObject      *object,
-                                               GParamSpec   *pspec);
+static void    gimp_paint_options_finalize         (GObject      *object);
+static void    gimp_paint_options_set_property     (GObject      *object,
+                                                    guint         property_id,
+                                                    const GValue *value,
+                                                    GParamSpec   *pspec);
+static void    gimp_paint_options_get_property     (GObject      *object,
+                                                    guint         property_id,
+                                                    GValue       *value,
+                                                    GParamSpec   *pspec);
+static void    gimp_paint_options_notify           (GObject      *object,
+                                                    GParamSpec   *pspec);
+
+static gdouble gimp_paint_options_get_dynamics_mix (gdouble       mix1,
+                                                    gdouble       mix2,
+                                                    gdouble       mix3);
 
 
 G_DEFINE_TYPE (GimpPaintOptions, gimp_paint_options, GIMP_TYPE_TOOL_OPTIONS)
@@ -222,6 +242,35 @@
                                     DEFAULT_VELOCITY_INVERSE_SIZE,
                                     GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_EXPANDED,
+                                    "random-expanded", NULL,
+                                    DEFAULT_RANDOM_EXPANDED,
+                                    GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_OPACITY,
+                                    "random-opacity", NULL,
+                                    DEFAULT_RANDOM_OPACITY,
+                                    GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_HARDNESS,
+                                    "random-hardness", NULL,
+                                    DEFAULT_RANDOM_HARDNESS,
+                                    GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_RATE,
+                                    "random-rate", NULL,
+                                    DEFAULT_RANDOM_RATE,
+                                    GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_SIZE,
+                                    "random-size", NULL,
+                                    DEFAULT_RANDOM_SIZE,
+                                    GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_COLOR,
+                                    "random-color", NULL,
+                                    DEFAULT_RANDOM_COLOR,
+                                    GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_INVERSE_SIZE,
+                                    "random-inverse-size", NULL,
+                                    DEFAULT_RANDOM_INVERSE_SIZE,
+                                    GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_USE_FADE,
                                     "use-fade", NULL,
                                     DEFAULT_USE_FADE,
@@ -310,6 +359,7 @@
 
   options->pressure_options = g_slice_new0 (GimpPressureOptions);
   options->velocity_options = g_slice_new0 (GimpVelocityOptions);
+  options->random_options   = g_slice_new0 (GimpRandomOptions);
   options->fade_options     = g_slice_new0 (GimpFadeOptions);
   options->jitter_options   = g_slice_new0 (GimpJitterOptions);
   options->gradient_options = g_slice_new0 (GimpGradientOptions);
@@ -325,6 +375,7 @@
 
   g_slice_free (GimpPressureOptions, options->pressure_options);
   g_slice_free (GimpVelocityOptions, options->velocity_options);
+  g_slice_free (GimpRandomOptions,   options->random_options);
   g_slice_free (GimpFadeOptions,     options->fade_options);
   g_slice_free (GimpJitterOptions,   options->jitter_options);
   g_slice_free (GimpGradientOptions, options->gradient_options);
@@ -341,6 +392,7 @@
   GimpPaintOptions    *options          = GIMP_PAINT_OPTIONS (object);
   GimpPressureOptions *pressure_options = options->pressure_options;
   GimpVelocityOptions *velocity_options = options->velocity_options;
+  GimpRandomOptions   *random_options   = options->random_options;
   GimpFadeOptions     *fade_options     = options->fade_options;
   GimpJitterOptions   *jitter_options   = options->jitter_options;
   GimpGradientOptions *gradient_options = options->gradient_options;
@@ -405,6 +457,28 @@
       velocity_options->color = g_value_get_boolean (value);
       break;
 
+    case PROP_RANDOM_EXPANDED:
+      random_options->expanded = g_value_get_boolean (value);
+      break;
+    case PROP_RANDOM_OPACITY:
+      random_options->opacity = g_value_get_boolean (value);
+      break;
+    case PROP_RANDOM_HARDNESS:
+      random_options->hardness = g_value_get_boolean (value);
+      break;
+    case PROP_RANDOM_RATE:
+      random_options->rate = g_value_get_boolean (value);
+      break;
+    case PROP_RANDOM_SIZE:
+      random_options->size = g_value_get_boolean (value);
+      break;
+    case PROP_RANDOM_INVERSE_SIZE:
+      random_options->inverse_size = g_value_get_boolean (value);
+      break;
+    case PROP_RANDOM_COLOR:
+      random_options->color = g_value_get_boolean (value);
+      break;
+
     case PROP_USE_FADE:
       fade_options->use_fade = g_value_get_boolean (value);
       break;
@@ -474,6 +548,7 @@
   GimpPaintOptions    *options          = GIMP_PAINT_OPTIONS (object);
   GimpPressureOptions *pressure_options = options->pressure_options;
   GimpVelocityOptions *velocity_options = options->velocity_options;
+  GimpRandomOptions   *random_options   = options->random_options;
   GimpFadeOptions     *fade_options     = options->fade_options;
   GimpJitterOptions   *jitter_options   = options->jitter_options;
   GimpGradientOptions *gradient_options = options->gradient_options;
@@ -538,6 +613,28 @@
       g_value_set_boolean (value, velocity_options->color);
       break;
 
+    case PROP_RANDOM_EXPANDED:
+      g_value_set_boolean (value, random_options->expanded);
+      break;
+    case PROP_RANDOM_OPACITY:
+      g_value_set_boolean (value, random_options->opacity);
+      break;
+    case PROP_RANDOM_HARDNESS:
+      g_value_set_boolean (value, random_options->hardness);
+      break;
+    case PROP_RANDOM_RATE:
+      g_value_set_boolean (value, random_options->rate);
+      break;
+    case PROP_RANDOM_SIZE:
+      g_value_set_boolean (value, random_options->size);
+      break;
+    case PROP_RANDOM_INVERSE_SIZE:
+      g_value_set_boolean (value, random_options->inverse_size);
+      break;
+    case PROP_RANDOM_COLOR:
+      g_value_set_boolean (value, random_options->color);
+      break;
+
     case PROP_USE_FADE:
       g_value_set_boolean (value, fade_options->use_fade);
       break;
@@ -721,8 +818,6 @@
                                        gdouble           pixel_dist,
                                        GimpRGB          *color)
 {
-  GimpPressureOptions *pressure_options;
-  GimpVelocityOptions *velocity_options;
   GimpGradientOptions *gradient_options;
   GimpGradient        *gradient;
 
@@ -730,13 +825,13 @@
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (color != NULL, FALSE);
 
-  pressure_options = paint_options->pressure_options;
-  velocity_options = paint_options->velocity_options;
   gradient_options = paint_options->gradient_options;
 
   gradient = gimp_context_get_gradient (GIMP_CONTEXT (paint_options));
 
-  if (pressure_options->color || velocity_options->color)
+  if (paint_options->pressure_options->color ||
+      paint_options->velocity_options->color ||
+      paint_options->random_options->color)
     {
       gimp_gradient_get_color_at (gradient, GIMP_CONTEXT (paint_options),
                                   NULL, grad_point,
@@ -810,7 +905,8 @@
     return GIMP_BRUSH_HARD;
 
   if (paint_options->pressure_options->hardness ||
-      paint_options->velocity_options->hardness)
+      paint_options->velocity_options->hardness ||
+      paint_options->random_options->hardness)
     return GIMP_BRUSH_PRESSURE;
 
   return GIMP_BRUSH_SOFT;
@@ -818,28 +914,38 @@
 
 
 /* Calculates dynamics mix to be used for same parameter
- * (velocity/pressure) mix Needed in may places and tools.
+ * (velocity/pressure/random) mix Needed in may places and tools.
  */
-gdouble
+static gdouble
 gimp_paint_options_get_dynamics_mix (gdouble mix1,
-                                     gdouble mix2)
+                                     gdouble mix2,
+                                     gdouble mix3)
 {
-  gdouble mixpv = 1.0;
+  gdouble mixpv = 0.0;
+  gint    dyn   = 0;
 
-  if ((mix1 >= 0) && (mix2 >= 0))
+  if (mix1 >= 0)
     {
-      mixpv = (mix1 + mix2) * 0.5;
+      mixpv += mix1;
+      dyn++;
     }
-  else if (mix1 >= 0)
+
+  if (mix2 >= 0)
     {
-      mixpv = mix1;
+      mixpv += mix2;
+      dyn++;
     }
-  else if (mix2 >= 0)
+
+  if (mix3 >= 0)
     {
-      mixpv = mix2;
+      mixpv += mix3;
+      dyn++;
     }
 
-  return mixpv;
+  if (dyn == 0)
+    return 1.0;
+  else
+    return mixpv / (gdouble) dyn;
 }
 
 gdouble
@@ -853,24 +959,79 @@
   g_return_val_if_fail (coords != NULL, 1.0);
 
   if (paint_options->pressure_options->opacity ||
-      paint_options->velocity_options->opacity)
+      paint_options->velocity_options->opacity ||
+      paint_options->random_options->opacity)
     {
       gdouble pressure = -1.0;
       gdouble velocity = -1.0;
+      gdouble random   = -1.0;
 
       if (paint_options->pressure_options->opacity && use_pressure)
         pressure = GIMP_PAINT_PRESSURE_SCALE * coords->pressure;
 
       if (paint_options->velocity_options->opacity)
         velocity = GIMP_PAINT_VELOCITY_SCALE * (1 - coords->velocity);
+      if (paint_options->random_options->opacity)
+        random = coords->random;
 
-      opacity = gimp_paint_options_get_dynamics_mix (pressure, velocity);
+      opacity = gimp_paint_options_get_dynamics_mix (pressure, velocity, random);
     }
 
   return opacity;
 }
 
 gdouble
+gimp_paint_options_get_dynamic_size (GimpPaintOptions *paint_options,
+                                     const GimpCoords *coords,
+                                     gboolean          use_pressure,
+                                     gboolean          use_dynamics)
+{
+  gdouble scale =  1.0;
+
+  if (use_dynamics)
+    {
+      gdouble pressure = -1.0;
+      gdouble velocity = -1.0;
+      gdouble random   = -1.0;
+
+      if (paint_options->pressure_options->inverse_size)
+        {
+          pressure = 1.0 - 0.9 * coords->pressure;
+        }
+
+      if (paint_options->velocity_options->size)
+        {
+          velocity = 1.0 - sqrt (coords->velocity);
+        }
+      else if (paint_options->velocity_options->inverse_size)
+        {
+          velocity = sqrt (coords->velocity);
+        }
+
+      if (paint_options->random_options->size)
+        {
+          random = 1.0 - coords->random;
+        }
+      else if (paint_options->random_options->inverse_size)
+        {
+          random = coords->random;
+        }
+
+      scale = gimp_paint_options_get_dynamics_mix (pressure, velocity, random);
+
+      if (scale < 1 / 64.0)
+        scale = 1 / 8.0;
+      else
+        scale = sqrt (scale);
+    }
+
+  scale *= paint_options->brush_scale;
+
+  return scale;
+}
+
+
+gdouble
 gimp_paint_options_get_dynamic_rate (GimpPaintOptions *paint_options,
                                      const GimpCoords *coords,
                                      gboolean          use_pressure)
@@ -881,10 +1042,12 @@
   g_return_val_if_fail (coords != NULL, 1.0);
 
   if (paint_options->pressure_options->rate ||
-      paint_options->velocity_options->rate)
+      paint_options->velocity_options->rate ||
+      paint_options->random_options->rate)
     {
       gdouble pressure = -1.0;
       gdouble velocity = -1.0;
+      gdouble random   = -1.0;
 
       if (paint_options->pressure_options->rate && use_pressure)
         pressure = GIMP_PAINT_PRESSURE_SCALE * coords->pressure;
@@ -892,8 +1055,78 @@
       if (paint_options->velocity_options->rate)
         velocity = GIMP_PAINT_VELOCITY_SCALE * (1 - coords->velocity);
 
-      rate = gimp_paint_options_get_dynamics_mix (pressure, velocity);
+      if (paint_options->random_options->rate)
+        random = coords->random;
+
+      rate = gimp_paint_options_get_dynamics_mix (pressure, velocity, random);
     }
 
   return rate;
 }
+
+
+gdouble
+gimp_paint_options_get_dynamic_color (GimpPaintOptions *paint_options,
+                                      const GimpCoords *coords,
+                                      gboolean          use_pressure)
+{
+  gdouble color = 1.0;
+
+  g_return_val_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options), 1.0);
+  g_return_val_if_fail (coords != NULL, 1.0);
+
+  if (paint_options->pressure_options->color ||
+      paint_options->velocity_options->color ||
+      paint_options->random_options->color)
+    {
+      gdouble pressure = -1.0;
+      gdouble velocity = -1.0;
+      gdouble random   = -1.0;
+
+      if (paint_options->pressure_options->color && use_pressure)
+        pressure = GIMP_PAINT_PRESSURE_SCALE * coords->pressure;
+
+      if (paint_options->velocity_options->color)
+        velocity = GIMP_PAINT_VELOCITY_SCALE * coords->velocity;
+
+      if (paint_options->random_options->color)
+        random = coords->random;
+
+      color = gimp_paint_options_get_dynamics_mix (pressure, velocity, random);
+    }
+
+  return color;
+}
+
+gdouble
+gimp_paint_options_get_dynamic_hardness (GimpPaintOptions *paint_options,
+                                         const GimpCoords *coords,
+                                         gboolean          use_pressure)
+{
+  gdouble hardness = 1.0;
+
+  g_return_val_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options), 1.0);
+  g_return_val_if_fail (coords != NULL, 1.0);
+
+  if (paint_options->pressure_options->rate ||
+      paint_options->velocity_options->rate ||
+      paint_options->random_options->rate)
+    {
+      gdouble pressure = -1.0;
+      gdouble velocity = -1.0;
+      gdouble random   = -1.0;
+
+      if (paint_options->pressure_options->hardness && use_pressure)
+        pressure = GIMP_PAINT_PRESSURE_SCALE * coords->pressure;
+
+      if (paint_options->velocity_options->hardness)
+        velocity = GIMP_PAINT_VELOCITY_SCALE * (1 - coords->velocity);
+
+      if (paint_options->random_options->hardness)
+        random = coords->random;
+
+      hardness = gimp_paint_options_get_dynamics_mix (pressure, velocity, random);
+    }
+
+  return hardness;
+}

Modified: trunk/app/paint/gimppaintoptions.h
==============================================================================
--- trunk/app/paint/gimppaintoptions.h	(original)
+++ trunk/app/paint/gimppaintoptions.h	Thu May 22 16:38:57 2008
@@ -32,6 +32,7 @@
 
 typedef struct _GimpPressureOptions GimpPressureOptions;
 typedef struct _GimpVelocityOptions GimpVelocityOptions;
+typedef struct _GimpRandomOptions   GimpRandomOptions;
 typedef struct _GimpFadeOptions     GimpFadeOptions;
 typedef struct _GimpJitterOptions   GimpJitterOptions;
 typedef struct _GimpGradientOptions GimpGradientOptions;
@@ -58,6 +59,17 @@
   gboolean  color;
 };
 
+struct _GimpRandomOptions
+{
+  gboolean  expanded;
+  gboolean  opacity;
+  gboolean  hardness;
+  gboolean  rate;
+  gboolean  size;
+  gboolean  inverse_size;
+  gboolean  color;
+};
+
 struct _GimpFadeOptions
 {
   gboolean  use_fade;
@@ -108,6 +120,7 @@
 
   GimpPressureOptions      *pressure_options;
   GimpVelocityOptions      *velocity_options;
+  GimpRandomOptions        *random_options;
   GimpFadeOptions          *fade_options;
   GimpJitterOptions        *jitter_options;
   GimpGradientOptions      *gradient_options;
@@ -146,14 +159,25 @@
 GimpBrushApplicationMode
              gimp_paint_options_get_brush_mode (GimpPaintOptions *paint_options);
 
-gdouble    gimp_paint_options_get_dynamics_mix (gdouble          mix1,
-                                                gdouble          mix2);
 
 gdouble gimp_paint_options_get_dynamic_opacity (GimpPaintOptions *paint_options,
                                                 const GimpCoords *coords,
                                                 gboolean          use_pressure);
 
-gdouble    gimp_paint_options_get_dynamic_rate (GimpPaintOptions *paint_options,
+gdouble gimp_paint_options_get_dynamic_size    (GimpPaintOptions *paint_options,
+                                                const GimpCoords *coords,
+                                                gboolean          use_pressure,
+                                                gboolean          use_dynamics);
+
+gdouble gimp_paint_options_get_dynamic_rate    (GimpPaintOptions *paint_options,
+                                                const GimpCoords *coords,
+                                                gboolean          use_pressure);
+
+gdouble gimp_paint_options_get_dynamic_color   (GimpPaintOptions *paint_options,
+                                                const GimpCoords *coords,
+                                                gboolean          use_pressure);
+
+gdouble gimp_paint_options_get_dynamic_hardness(GimpPaintOptions *paint_options,
                                                 const GimpCoords *coords,
                                                 gboolean          use_pressure);
 

Modified: trunk/app/paint/gimpsmudge.c
==============================================================================
--- trunk/app/paint/gimpsmudge.c	(original)
+++ trunk/app/paint/gimpsmudge.c	Thu May 22 16:38:57 2008
@@ -238,6 +238,7 @@
   gdouble            opacity;
   gdouble            dynamic_rate;
   gint               x, y, w, h;
+  gdouble            hardness;
 
   image = gimp_item_get_image (GIMP_ITEM (drawable));
 
@@ -308,10 +309,15 @@
                                                      &paint_core->cur_coords,
                                                      paint_core->use_pressure);
 
+  hardness = gimp_paint_options_get_dynamic_hardness (paint_options,
+                                                      &paint_core->cur_coords,
+                                                      paint_core->use_pressure);
+
   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),
+                                  hardness,
                                   GIMP_PAINT_INCREMENTAL);
 }
 

Modified: trunk/app/tools/gimppaintoptions-gui.c
==============================================================================
--- trunk/app/tools/gimppaintoptions-gui.c	(original)
+++ trunk/app/tools/gimppaintoptions-gui.c	Thu May 22 16:38:57 2008
@@ -54,7 +54,10 @@
 static GtkWidget * pressure_options_gui (GimpPressureOptions *pressure,
                                          GimpPaintOptions    *paint_options,
                                          GType                tool_type);
-static GtkWidget * velocity_options_gui (GimpVelocityOptions *pressure,
+static GtkWidget * velocity_options_gui (GimpVelocityOptions *velocity,
+                                         GimpPaintOptions    *paint_options,
+                                         GType                tool_type);
+static GtkWidget * random_options_gui   (GimpRandomOptions   *random,
                                          GimpPaintOptions    *paint_options,
                                          GType                tool_type);
 static GtkWidget * fade_options_gui     (GimpFadeOptions     *fade,
@@ -164,6 +167,14 @@
       gtk_widget_show (frame);
     }
 
+  frame = random_options_gui (options->random_options,
+                              options, tool_type);
+  if (frame)
+    {
+      gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+      gtk_widget_show (frame);
+    }
+
   frame = fade_options_gui (options->fade_options,
                             options, tool_type);
   if (frame)
@@ -359,8 +370,7 @@
     }
 
   /*  the opacity toggle  */
-  if ((g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL) &&
-      (tool_type != GIMP_TYPE_AIRBRUSH_TOOL))            ||
+  if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL)||
       tool_type == GIMP_TYPE_CLONE_TOOL                  ||
       tool_type == GIMP_TYPE_HEAL_TOOL                   ||
       tool_type == GIMP_TYPE_PERSPECTIVE_CLONE_TOOL      ||
@@ -408,6 +418,7 @@
       tool_type == GIMP_TYPE_DODGE_BURN_TOOL        ||
       tool_type == GIMP_TYPE_ERASER_TOOL            ||
       tool_type == GIMP_TYPE_PAINTBRUSH_TOOL        ||
+      tool_type == GIMP_TYPE_AIRBRUSH_TOOL          ||
       tool_type == GIMP_TYPE_PENCIL_TOOL)
     {
       button = gimp_prop_check_button_new (config, "velocity-size",
@@ -416,19 +427,108 @@
       gtk_widget_show (button);
     }
 
-  /* the inverse size toggle */
-  if (tool_type == GIMP_TYPE_AIRBRUSH_TOOL)
+  /*  the color toggle  */
+  if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL))
     {
-      button = gimp_prop_check_button_new (config, "velocity-inverse-size",
-                                           _("Size"));
+      button = gimp_prop_check_button_new (config, "velocity-color",
+                                           _("Color"));
       gtk_container_add (GTK_CONTAINER (wbox), button);
       gtk_widget_show (button);
     }
 
+  return frame;
+}
+
+
+static GtkWidget *
+random_options_gui (GimpRandomOptions *random,
+                    GimpPaintOptions  *paint_options,
+                    GType              tool_type)
+{
+  GObject   *config = G_OBJECT (paint_options);
+  GtkWidget *frame  = NULL;
+  GtkWidget *wbox   = NULL;
+  GtkWidget *button;
+
+  if (g_type_is_a (tool_type, GIMP_TYPE_BRUSH_TOOL))
+    {
+      GtkWidget *inner_frame;
+
+      frame = gimp_prop_expander_new (G_OBJECT (paint_options),
+                                      "random-expanded",
+                                      _("Random sensitivity"));
+
+      inner_frame = gimp_frame_new ("<expander>");
+      gtk_container_add (GTK_CONTAINER (frame), inner_frame);
+      gtk_widget_show (inner_frame);
+
+      wbox = gtk_hwrap_box_new (FALSE);
+      gtk_wrap_box_set_aspect_ratio (GTK_WRAP_BOX (wbox), 4);
+      gtk_container_add (GTK_CONTAINER (inner_frame), wbox);
+      gtk_widget_show (wbox);
+    }
+
+  /*  the opacity toggle  */
+  if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL)||
+      tool_type == GIMP_TYPE_CLONE_TOOL                  ||
+      tool_type == GIMP_TYPE_HEAL_TOOL                   ||
+      tool_type == GIMP_TYPE_PERSPECTIVE_CLONE_TOOL      ||
+      tool_type == GIMP_TYPE_DODGE_BURN_TOOL             ||
+      tool_type == GIMP_TYPE_ERASER_TOOL)
+    {
+      button = gimp_prop_check_button_new (config, "random-opacity",
+                                           _("Opacity"));
+      gtk_container_add (GTK_CONTAINER (wbox), button);
+      gtk_widget_show (button);
+    }
+
+  /*  the pressure toggle  */
+  if (tool_type == GIMP_TYPE_AIRBRUSH_TOOL          ||
+      tool_type == GIMP_TYPE_CLONE_TOOL             ||
+      tool_type == GIMP_TYPE_HEAL_TOOL              ||
+      tool_type == GIMP_TYPE_PERSPECTIVE_CLONE_TOOL ||
+      tool_type == GIMP_TYPE_CONVOLVE_TOOL          ||
+      tool_type == GIMP_TYPE_DODGE_BURN_TOOL        ||
+      tool_type == GIMP_TYPE_PAINTBRUSH_TOOL        ||
+      tool_type == GIMP_TYPE_SMUDGE_TOOL)
+    {
+      button = gimp_prop_check_button_new (config, "random-hardness",
+                                           _("Hardness"));
+      gtk_container_add (GTK_CONTAINER (wbox), button);
+      gtk_widget_show (button);
+    }
+
+  /*  the rate toggle */
+  if (tool_type == GIMP_TYPE_AIRBRUSH_TOOL ||
+      tool_type == GIMP_TYPE_CONVOLVE_TOOL ||
+      tool_type == GIMP_TYPE_SMUDGE_TOOL)
+    {
+      button = gimp_prop_check_button_new (config, "random-rate",
+                                           _("Rate"));
+      gtk_container_add (GTK_CONTAINER (wbox), button);
+      gtk_widget_show (button);
+    }
+
+  /*  the size toggle  */
+  if (tool_type == GIMP_TYPE_CLONE_TOOL             ||
+      tool_type == GIMP_TYPE_HEAL_TOOL              ||
+      tool_type == GIMP_TYPE_PERSPECTIVE_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_PAINTBRUSH_TOOL        ||
+      tool_type == GIMP_TYPE_AIRBRUSH_TOOL          ||
+      tool_type == GIMP_TYPE_PENCIL_TOOL)
+    {
+      button = gimp_prop_check_button_new (config, "random-size",
+                                         _("Size"));
+        gtk_container_add (GTK_CONTAINER (wbox), button);
+        gtk_widget_show (button);
+      }
   /*  the color toggle  */
   if (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL))
     {
-      button = gimp_prop_check_button_new (config, "velocity-color",
+      button = gimp_prop_check_button_new (config, "random-color",
                                            _("Color"));
       gtk_container_add (GTK_CONTAINER (wbox), button);
       gtk_widget_show (button);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]