[gimp] Adds dynamic aspect ratio for brushes.



commit 6aafd3438070ee52e914b31e990a1982851de4a9
Author: Alexia Death <alexiadeath gmail com>
Date:   Sat Apr 25 20:53:09 2009 +0300

    Adds dynamic aspect ratio for brushes.
---
 app/actions/tools-actions.c      |   41 ++++++++++
 app/actions/tools-commands.c     |   21 +++++
 app/actions/tools-commands.h     |    4 +
 app/core/gimpbrush-transform.c   |   28 +++++--
 app/core/gimpbrush-transform.h   |   12 ++--
 app/core/gimpbrush.c             |   40 +++++-----
 app/core/gimpbrushgenerated.c    |   44 ++++++++---
 app/paint/gimpbrushcore.c        |   75 +++++++++++--------
 app/paint/gimpbrushcore.h        |    2 +
 app/paint/gimppaintoptions.c     |  154 +++++++++++++++++++++++++++++++++++++-
 app/paint/gimppaintoptions.h     |    6 ++
 app/paint/gimpsmudge.c           |    3 +-
 app/tools/gimpbrushtool.c        |    4 +
 app/tools/gimppaintoptions-gui.c |   79 ++++++++++++++++++--
 14 files changed, 426 insertions(+), 87 deletions(-)

diff --git a/app/actions/tools-actions.c b/app/actions/tools-actions.c
index 4af966c..223af5e 100644
--- a/app/actions/tools-actions.c
+++ b/app/actions/tools-actions.c
@@ -217,6 +217,42 @@ static const GimpEnumActionEntry tools_paint_brush_angle_actions[] =
     NULL },
 };
 
+static const GimpEnumActionEntry tools_paint_brush_aspect_ratio_actions[] =
+{
+  { "tools-paint-brush-aspect-ratio-set", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Set Brush Aspect Ratio", NULL, NULL,
+    GIMP_ACTION_SELECT_SET, TRUE,
+    NULL },
+  { "tools-paint-brush-aspect-ratio-set-to-default", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Set Brush Aspect Ratio To Default Value", NULL, NULL,
+    GIMP_ACTION_SELECT_SET_TO_DEFAULT, FALSE,
+    NULL },
+  { "tools-paint-brush-aspect-ratio-minimum", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Minimize Brush Aspect Ratio", NULL, NULL,
+    GIMP_ACTION_SELECT_FIRST, FALSE,
+    NULL },
+  { "tools-paint-brush-aspect-ratio-maximum", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Maximize Brush Aspect Ratio", NULL, NULL,
+    GIMP_ACTION_SELECT_LAST, FALSE,
+    NULL },
+  { "tools-paint-brush-aspect-ratio-decrease", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Decrease Brush Aspect Ratio", NULL, NULL,
+    GIMP_ACTION_SELECT_PREVIOUS, FALSE,
+    NULL },
+  { "tools-paint-brush-aspect-ratio-increase", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Increase Brush Aspect Ratio", NULL, NULL,
+    GIMP_ACTION_SELECT_NEXT, FALSE,
+    NULL },
+  { "tools-paint-brush-aspect-ratio-decrease-skip", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Decrease Brush Aspect Ratio More", NULL, NULL,
+    GIMP_ACTION_SELECT_SKIP_PREVIOUS, FALSE,
+    NULL },
+  { "tools-paint-brush-aspect-ratio-increase-skip", GIMP_STOCK_TOOL_PAINTBRUSH,
+    "Increase Brush Aspect Ratio More", NULL, NULL,
+    GIMP_ACTION_SELECT_SKIP_NEXT, FALSE,
+    NULL },
+};
+
 static const GimpEnumActionEntry tools_ink_blob_size_actions[] =
 {
   { "tools-ink-blob-size-set", GIMP_STOCK_TOOL_INK,
@@ -631,6 +667,11 @@ tools_actions_setup (GimpActionGroup *group)
                                       G_CALLBACK (tools_paint_brush_angle_cmd_callback));
 
   gimp_action_group_add_enum_actions (group, NULL,
+                                      tools_paint_brush_aspect_ratio_actions,
+                                      G_N_ELEMENTS (tools_paint_brush_aspect_ratio_actions),
+                                      G_CALLBACK (tools_paint_brush_aspect_ratio_cmd_callback));
+
+  gimp_action_group_add_enum_actions (group, NULL,
                                       tools_ink_blob_size_actions,
                                       G_N_ELEMENTS (tools_ink_blob_size_actions),
                                       G_CALLBACK (tools_ink_blob_size_cmd_callback));
diff --git a/app/actions/tools-commands.c b/app/actions/tools-commands.c
index bc8fd71..7ca3687 100644
--- a/app/actions/tools-commands.c
+++ b/app/actions/tools-commands.c
@@ -318,6 +318,27 @@ tools_paint_brush_angle_cmd_callback (GtkAction *action,
 }
 
 void
+tools_paint_brush_aspect_ratio_cmd_callback (GtkAction *action,
+                                             gint       value,
+                                             gpointer   data)
+{
+  GimpContext  *context;
+  GimpToolInfo *tool_info;
+  return_if_no_context (context, data);
+
+  tool_info = gimp_context_get_tool (context);
+
+  if (tool_info && GIMP_IS_PAINT_OPTIONS (tool_info->tool_options))
+    {
+      action_select_property ((GimpActionSelectType) value,
+                              action_data_get_display (data),
+                              G_OBJECT (tool_info->tool_options),
+                              "brush-aspect-ratio",
+                              0.01, 0.1, 1.0, TRUE);
+    }
+}
+
+void
 tools_ink_blob_size_cmd_callback (GtkAction *action,
                                   gint       value,
                                   gpointer   data)
diff --git a/app/actions/tools-commands.h b/app/actions/tools-commands.h
index b22e204..fd3b38f 100644
--- a/app/actions/tools-commands.h
+++ b/app/actions/tools-commands.h
@@ -49,6 +49,10 @@ void   tools_paint_brush_angle_cmd_callback         (GtkAction   *action,
                                                      gint         value,
                                                      gpointer     data);
 
+void   tools_paint_brush_aspect_ratio_cmd_callback  (GtkAction   *action,
+                                                     gint         value,
+                                                     gpointer     data);
+
 void   tools_ink_blob_size_cmd_callback             (GtkAction   *action,
                                                      gint         value,
                                                      gpointer     data);
diff --git a/app/core/gimpbrush-transform.c b/app/core/gimpbrush-transform.c
index 570d77d..8d7b36e 100644
--- a/app/core/gimpbrush-transform.c
+++ b/app/core/gimpbrush-transform.c
@@ -50,8 +50,8 @@ static void  gimp_brush_transform_bounding_box (GimpBrush         *brush,
 
 void
 gimp_brush_real_transform_size (GimpBrush *brush,
-                                gdouble    scale_x,
-                                gdouble    scale_y,
+                                gdouble    scale,
+                                gdouble    aspect_ratio,
                                 gdouble    angle,
                                 gint      *width,
                                 gint      *height)
@@ -59,7 +59,11 @@ gimp_brush_real_transform_size (GimpBrush *brush,
   GimpMatrix3 matrix;
   gint        x, y;
 
-  gimp_brush_transform_matrix (brush, scale_x, scale_y, angle, &matrix);
+  if (aspect_ratio < 1.0)
+    gimp_brush_transform_matrix (brush, scale * aspect_ratio, scale, angle, &matrix);
+  else
+    gimp_brush_transform_matrix (brush, scale, scale / aspect_ratio, angle, &matrix);
+
   gimp_brush_transform_bounding_box (brush, &matrix, &x, &y, width, height);
 }
 
@@ -88,8 +92,8 @@ gimp_brush_real_transform_size (GimpBrush *brush,
  */
 TempBuf *
 gimp_brush_real_transform_mask (GimpBrush *brush,
-                                gdouble    scale_x,
-                                gdouble    scale_y,
+                                gdouble    scale,
+                                gdouble    aspect_ratio,
                                 gdouble    angle)
 {
   TempBuf      *result;
@@ -157,7 +161,10 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
   const guint fraction_bitmask = pow(2, fraction_bits) - 1 ;
 
 
-  gimp_brush_transform_matrix (brush, scale_x, scale_y, angle, &matrix);
+   if (aspect_ratio < 1.0)
+    gimp_brush_transform_matrix (brush, scale * aspect_ratio, scale, angle, &matrix);
+  else
+    gimp_brush_transform_matrix (brush, scale, scale / aspect_ratio, angle, &matrix);
 
   if (gimp_matrix3_is_identity (&matrix))
     return temp_buf_copy (brush->mask, NULL);
@@ -335,8 +342,8 @@ gimp_brush_real_transform_mask (GimpBrush *brush,
  */
 TempBuf *
 gimp_brush_real_transform_pixmap (GimpBrush *brush,
-                                  gdouble    scale_x,
-                                  gdouble    scale_y,
+                                  gdouble    scale,
+                                  gdouble    aspect_ratio,
                                   gdouble    angle)
 {
   TempBuf      *result;
@@ -404,7 +411,10 @@ gimp_brush_real_transform_pixmap (GimpBrush *brush,
   const guint fraction_bitmask = pow(2, fraction_bits)- 1 ;
 
 
-  gimp_brush_transform_matrix (brush, scale_x, scale_y, angle, &matrix);
+  if (aspect_ratio < 1.0)
+    gimp_brush_transform_matrix (brush, scale * aspect_ratio, scale, angle, &matrix);
+  else
+    gimp_brush_transform_matrix (brush, scale, scale / aspect_ratio, angle, &matrix);
 
   if (gimp_matrix3_is_identity (&matrix))
     return temp_buf_copy (brush->pixmap, NULL);
diff --git a/app/core/gimpbrush-transform.h b/app/core/gimpbrush-transform.h
index fb65491..db7fe76 100644
--- a/app/core/gimpbrush-transform.h
+++ b/app/core/gimpbrush-transform.h
@@ -24,18 +24,18 @@
 /*  virtual functions of GimpBrush, don't call directly  */
 
 void      gimp_brush_real_transform_size   (GimpBrush *brush,
-                                            gdouble    scale_x,
-                                            gdouble    scale_y,
+                                            gdouble    scale,
+                                            gdouble    aspect_ratio,
                                             gdouble    angle,
                                             gint      *scaled_width,
                                             gint      *scaled_height);
 TempBuf * gimp_brush_real_transform_mask   (GimpBrush *brush,
-                                            gdouble    scale_x,
-                                            gdouble    scale_y,
+                                            gdouble    scale,
+                                            gdouble    aspect_ratio,
                                             gdouble    angle);
 TempBuf * gimp_brush_real_transform_pixmap (GimpBrush *brush,
-                                            gdouble    scale_x,
-                                            gdouble    scale_y,
+                                            gdouble    scale,
+                                            gdouble    aspect_ratio,
                                             gdouble    angle);
 
 
diff --git a/app/core/gimpbrush.c b/app/core/gimpbrush.c
index 51f5e61..417162b 100644
--- a/app/core/gimpbrush.c
+++ b/app/core/gimpbrush.c
@@ -276,13 +276,13 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
 
       if (scale != 1.0)
         {
-          mask_buf = gimp_brush_transform_mask (brush, scale, scale, 0.0);
+          mask_buf = gimp_brush_transform_mask (brush, scale, 1.0, 0.0);
 
           if (! mask_buf)
             mask_buf = temp_buf_new (1, 1, 1, 0, 0, transp);
 
           if (pixmap_buf)
-            pixmap_buf = gimp_brush_transform_pixmap (brush, scale, scale, 0.0);
+            pixmap_buf = gimp_brush_transform_pixmap (brush, scale, 1.0, 0.0);
 
           mask_width  = mask_buf->width;
           mask_height = mask_buf->height;
@@ -457,19 +457,19 @@ gimp_brush_want_null_motion (GimpBrush  *brush,
 
 void
 gimp_brush_transform_size (GimpBrush     *brush,
-                           gdouble        scale_x,
-                           gdouble        scale_y,
+                           gdouble        scale,
+                           gdouble        aspect_ratio,
                            gdouble        angle,
                            gint          *width,
                            gint          *height)
 {
   g_return_if_fail (GIMP_IS_BRUSH (brush));
-  g_return_if_fail (scale_x > 0.0);
-  g_return_if_fail (scale_y > 0.0);
+  g_return_if_fail (scale > 0.0);
+  g_return_if_fail (aspect_ratio > 0.0);
   g_return_if_fail (width != NULL);
   g_return_if_fail (height != NULL);
 
-  if ((scale_x == 1.0) && (scale_y == 1.0) && ((angle == 0.0) || (angle == 0.5) || (angle == 1.0)))
+  if ((scale == 1.0) && ( aspect_ratio == 1.0) && ((angle == 0.0) || (angle == 0.5) || (angle == 1.0)))
     {
       *width  = brush->mask->width;
       *height = brush->mask->height;
@@ -477,41 +477,41 @@ gimp_brush_transform_size (GimpBrush     *brush,
       return;
     }
 
-  GIMP_BRUSH_GET_CLASS (brush)->transform_size (brush, scale_x, scale_y, angle, width, height);
+  GIMP_BRUSH_GET_CLASS (brush)->transform_size (brush, scale, aspect_ratio, angle, width, height);
 }
 
 TempBuf *
 gimp_brush_transform_mask (GimpBrush *brush,
-                           gdouble    scale_x,
-                           gdouble    scale_y,
+                           gdouble    scale,
+                           gdouble    aspect_ratio,
                            gdouble    angle)
 {
   g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
-  g_return_val_if_fail (scale_x > 0.0, NULL);
-  g_return_val_if_fail (scale_y > 0.0, NULL);
+  g_return_val_if_fail (scale > 0.0, NULL);
+  g_return_val_if_fail (aspect_ratio > 0.0, NULL);
 
-  if ((scale_x == 1.0) && (scale_y == 1.0) && (angle == 0.0))
+  if ((scale == 1.0) && (aspect_ratio == 1.0) && (angle == 0.0))
     return temp_buf_copy (brush->mask, NULL);
 
-  return GIMP_BRUSH_GET_CLASS (brush)->transform_mask (brush, scale_x, scale_y, angle);
+  return GIMP_BRUSH_GET_CLASS (brush)->transform_mask (brush, scale, aspect_ratio, angle);
 }
 
 TempBuf *
 gimp_brush_transform_pixmap (GimpBrush *brush,
-                             gdouble    scale_x,
-                             gdouble    scale_y,
+                             gdouble    scale,
+                             gdouble    aspect_ratio,
                              gdouble    angle)
 {
   g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
   g_return_val_if_fail (brush->pixmap != NULL, NULL);
-  g_return_val_if_fail (scale_x > 0.0, NULL);
-  g_return_val_if_fail (scale_y > 0.0, NULL);
+  g_return_val_if_fail (scale > 0.0, NULL);
+  g_return_val_if_fail (aspect_ratio > 0.0, NULL);
 
 
-  if ((scale_x == 1.0) && (scale_y == 1.0) && (angle == 0.0))
+  if ((scale == 1.0) && (aspect_ratio == 1.0) && (angle == 0.0))
     return temp_buf_copy (brush->pixmap, NULL);
 
-  return GIMP_BRUSH_GET_CLASS (brush)->transform_pixmap (brush, scale_x, scale_y, angle);
+  return GIMP_BRUSH_GET_CLASS (brush)->transform_pixmap (brush, scale, aspect_ratio, angle);
 }
 
 TempBuf *
diff --git a/app/core/gimpbrushgenerated.c b/app/core/gimpbrushgenerated.c
index 0bd79a8..d2157ff 100644
--- a/app/core/gimpbrushgenerated.c
+++ b/app/core/gimpbrushgenerated.c
@@ -66,14 +66,14 @@ static const gchar * gimp_brush_generated_get_extension (GimpData     *data);
 static GimpData    * gimp_brush_generated_duplicate     (GimpData     *data);
 
 static void          gimp_brush_generated_transform_size(GimpBrush    *gbrush,
-                                                         gdouble       scale_x,
-                                                         gdouble       scale_y,
+                                                         gdouble       scale,
+                                                         gdouble       aspect_ratio,
                                                          gdouble       angle,
                                                          gint         *width,
                                                          gint         *height);
 static TempBuf     * gimp_brush_generated_transform_mask(GimpBrush    *gbrush,
-                                                         gdouble       scale_x,
-                                                         gdouble       scale_y,
+                                                         gdouble       scale,
+                                                         gdouble       aspect_ratio,
                                                          gdouble       angle);
 
 static TempBuf     * gimp_brush_generated_calc          (GimpBrushGenerated      *brush,
@@ -290,8 +290,8 @@ gimp_brush_generated_duplicate (GimpData *data)
 
 static void
 gimp_brush_generated_transform_size (GimpBrush *gbrush,
-                                     gdouble    scale_x,
-                                     gdouble    scale_y,
+                                     gdouble    scale,
+                                     gdouble    aspect_ratio,
                                      gdouble    angle,
                                      gint      *width,
                                      gint      *height)
@@ -300,12 +300,22 @@ gimp_brush_generated_transform_size (GimpBrush *gbrush,
   gint                half_width;
   gint                half_height;
 
+  /* Since generated brushes are symmetric the dont have intput
+   * for aspect ratios  < 1.0. its same as rotate by 90 degrees and
+   * 1 / ratio. So we fix the input up for this case.   */
+
+  if (aspect_ratio < 1.0)
+    {
+      aspect_ratio = 1.0 / aspect_ratio;
+      angle = angle + 0.25;
+    }
+
   gimp_brush_generated_get_half_size (brush,
                                       brush->shape,
-                                      brush->radius * (scale_x + scale_y) / 2,
+                                      brush->radius * scale,
                                       brush->spikes,
                                       brush->hardness,
-                                      brush->aspect_ratio * scale_x / scale_y,
+                                      brush->aspect_ratio / aspect_ratio,
                                       (brush->angle + 360 * angle),
                                       &half_width, &half_height,
                                       NULL, NULL, NULL, NULL);
@@ -316,18 +326,28 @@ gimp_brush_generated_transform_size (GimpBrush *gbrush,
 
 static TempBuf *
 gimp_brush_generated_transform_mask (GimpBrush *gbrush,
-                                     gdouble    scale_x,
-                                     gdouble    scale_y,
+                                     gdouble    scale,
+                                     gdouble    aspect_ratio,
                                      gdouble    angle)
 {
   GimpBrushGenerated *brush  = GIMP_BRUSH_GENERATED (gbrush);
 
+  /* Since generated brushes are symmetric the dont have intput
+   * for aspect ratios  < 1.0. its same as rotate by 90 degrees and
+   * 1 / ratio. So we fix the input up for this case.   */
+
+  if (aspect_ratio < 1.0)
+    {
+      aspect_ratio = 1.0 / aspect_ratio;
+      angle = angle + 0.25;
+    }
+
   return gimp_brush_generated_calc (brush,
                                     brush->shape,
-                                    brush->radius * (scale_x + scale_y) / 2,
+                                    brush->radius * scale ,
                                     brush->spikes,
                                     brush->hardness,
-                                    brush->aspect_ratio * scale_x / scale_y,
+                                    brush->aspect_ratio / aspect_ratio,
                                     (brush->angle + 360 * angle),
                                     NULL, NULL);
 }
diff --git a/app/paint/gimpbrushcore.c b/app/paint/gimpbrushcore.c
index fe7f063..0b7f210 100644
--- a/app/paint/gimpbrushcore.c
+++ b/app/paint/gimpbrushcore.c
@@ -366,11 +366,14 @@ gimp_brush_core_start (GimpPaintCore     *paint_core,
 
   if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
     {
-      core->scale = gimp_paint_options_get_dynamic_size (paint_options,
-                                                         coords,
-                                                         TRUE);
-      core->angle = gimp_paint_options_get_dynamic_angle (paint_options,
-                                                          coords);
+      core->scale        = gimp_paint_options_get_dynamic_size (paint_options,
+                                                                coords,
+                                                                TRUE);
+      core->angle        = gimp_paint_options_get_dynamic_angle (paint_options,
+                                                                 coords);
+      core->aspect_ratio =
+                    gimp_paint_options_get_dynamic_aspect_ratio (paint_options,
+                                                                 coords);
     }
   core->spacing = (gdouble) gimp_brush_get_spacing (core->main_brush) / 100.0;
 
@@ -706,17 +709,21 @@ gimp_brush_core_get_paint_area (GimpPaintCore    *paint_core,
 
   if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
     {
-      core->scale = gimp_paint_options_get_dynamic_size (paint_options,
-                                                         &paint_core->cur_coords,
-                                                         TRUE);
+      core->scale = gimp_paint_options_get_dynamic_size       (paint_options,
+                                                               &paint_core->cur_coords,
+                                                               TRUE);
 
-      core->angle = gimp_paint_options_get_dynamic_angle (paint_options,
-                                                          &paint_core->cur_coords);
+      core->angle = gimp_paint_options_get_dynamic_angle       (paint_options,
+                                                                &paint_core->cur_coords);
+
+      core->aspect_ratio =
+                   gimp_paint_options_get_dynamic_aspect_ratio (paint_options,
+                                                                &paint_core->cur_coords);
     }
 
   core->scale = gimp_brush_core_clamp_brush_scale (core, core->scale);
 
-  gimp_brush_transform_size (core->brush, core->scale, core->scale, core->angle, &brush_width, &brush_height);
+  gimp_brush_transform_size (core->brush, core->scale, core->aspect_ratio, core->angle, &brush_width, &brush_height);
 
   /*  adjust the x and y coordinates to the upper left corner of the brush  */
   x = (gint) floor (paint_core->cur_coords.x) - (brush_width  / 2);
@@ -797,6 +804,7 @@ gimp_brush_core_create_bound_segs (GimpBrushCore    *core,
   TempBuf *mask  = NULL;
   gdouble  scale;
   gdouble  angle;
+  gdouble  aspect_ratio;
 
   g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
   g_return_if_fail (core->main_brush != NULL);
@@ -804,12 +812,13 @@ gimp_brush_core_create_bound_segs (GimpBrushCore    *core,
 
   scale = paint_options->brush_scale;
   angle = paint_options->brush_angle;
+  aspect_ratio = paint_options->brush_aspect_ratio;
 
   if (scale > 0.0)
     {
       scale = gimp_brush_core_clamp_brush_scale (core, scale);
 
-      mask = gimp_brush_transform_mask (core->main_brush, scale, scale, angle);
+      mask = gimp_brush_transform_mask (core->main_brush, scale, aspect_ratio, angle);
     }
 
   if (mask)
@@ -1311,18 +1320,19 @@ gimp_brush_core_transform_mask (GimpBrushCore *core,
   if (core->scale <= 0.0)
     return NULL; /* Should never happen now, with scale clamping. */
 
-  if ((core->scale == 1.0) && (core->angle == 0.0))
+  if ((core->scale == 1.0) && (core->angle == 0.0) && (core->aspect_ratio == 1.0))
     return brush->mask;
 
-  gimp_brush_transform_size (brush, core->scale, core->scale, core->angle, &width, &height);
+  gimp_brush_transform_size (brush, core->scale, core->aspect_ratio, core->angle, &width, &height);
 
-    if (! core->cache_invalid                      &&
-      core->transform_brush                      &&
-      brush->mask == core->last_transform_brush  &&
-      width       == core->last_transform_width  &&
-      height      == core->last_transform_height &&
-      core->scale == core->last_scale            &&
-      core->angle == core->last_angle)
+  if (! core->cache_invalid                             &&
+      core->transform_brush                             &&
+      brush->mask        == core->last_transform_brush  &&
+      width              == core->last_transform_width  &&
+      height             == core->last_transform_height &&
+      core->scale        == core->last_scale            &&
+      core->angle        == core->last_angle            &&
+      core->aspect_ratio == core->last_aspect_ratio)
     {
       return core->transform_brush;
     }
@@ -1332,12 +1342,13 @@ gimp_brush_core_transform_mask (GimpBrushCore *core,
   core->last_transform_height = height;
   core->last_scale        = core->scale;
   core->last_angle        = core->angle;
+  core->last_aspect_ratio = core->aspect_ratio;
 
 
   if (core->transform_brush)
     temp_buf_free (core->transform_brush);
 
-  core->transform_brush = gimp_brush_transform_mask (brush, core->scale, core->scale, core->angle);
+  core->transform_brush = gimp_brush_transform_mask (brush, core->scale, core->aspect_ratio, core->angle);
 
   core->cache_invalid       = TRUE;
   core->solid_cache_invalid = TRUE;
@@ -1355,18 +1366,19 @@ gimp_brush_core_transform_pixmap (GimpBrushCore *core,
   if (core->scale <= 0.0)
     return NULL;
 
-  if ((core->scale == 1.0) && (core->angle == 0.0))
+  if ((core->scale == 1.0) && (core->angle == 0.0) && (core->aspect_ratio == 1.0))
     return brush->pixmap;
 
-  gimp_brush_transform_size (brush, core->scale, core->scale, core->angle, &width, &height);
+  gimp_brush_transform_size (brush, core->scale, core->aspect_ratio, core->angle, &width, &height);
 
 
-  if (! core->cache_invalid                              &&
-      core->transform_pixmap                             &&
-      brush->pixmap == core->last_transform_pixmap       &&
-      width         == core->last_transform_pixmap_width &&
-      height        == core->last_transform_pixmap_height&&
-      core->angle   == core->last_angle)
+  if (! core->cache_invalid                                    &&
+      core->transform_pixmap                                   &&
+      brush->pixmap      == core->last_transform_pixmap        &&
+      width              == core->last_transform_pixmap_width  &&
+      height             == core->last_transform_pixmap_height &&
+      core->angle        == core->last_angle                   &&
+      core->aspect_ratio == core->last_aspect_ratio)
     {
       return core->transform_pixmap;
     }
@@ -1375,12 +1387,13 @@ gimp_brush_core_transform_pixmap (GimpBrushCore *core,
   core->last_transform_pixmap_width  = width;
   core->last_transform_pixmap_height = height;
   core->last_angle = core->angle;
+  core->last_aspect_ratio = core->aspect_ratio;
 
   if (core->transform_pixmap)
     temp_buf_free (core->transform_pixmap);
 
 
-  core->transform_pixmap = gimp_brush_transform_pixmap (brush, core->scale, core->scale, core->angle);
+  core->transform_pixmap = gimp_brush_transform_pixmap (brush, core->scale, core->aspect_ratio, core->angle);
 
   core->cache_invalid = TRUE;
 
diff --git a/app/paint/gimpbrushcore.h b/app/paint/gimpbrushcore.h
index 947b48c..2f119c9 100644
--- a/app/paint/gimpbrushcore.h
+++ b/app/paint/gimpbrushcore.h
@@ -46,6 +46,7 @@ struct _GimpBrushCore
   gdouble        spacing;
   gdouble        scale;
   gdouble        angle;
+  gdouble        aspect_ratio;
 
   /*  brush buffers  */
   TempBuf       *pressure_brush;
@@ -60,6 +61,7 @@ struct _GimpBrushCore
   gint           last_transform_height;
   gdouble        last_scale;
   gdouble        last_angle;
+  gdouble        last_aspect_ratio;
 
   TempBuf       *transform_pixmap;
   TempBuf       *last_transform_pixmap;
diff --git a/app/paint/gimppaintoptions.c b/app/paint/gimppaintoptions.c
index 7d12c96..091ffae 100644
--- a/app/paint/gimppaintoptions.c
+++ b/app/paint/gimppaintoptions.c
@@ -36,6 +36,7 @@
 
 
 #define DEFAULT_BRUSH_SCALE            1.0
+#define DEFAULT_BRUSH_ASPECT_RATIO     1.0
 #define DEFAULT_BRUSH_ANGLE            0.0
 
 #define DEFAULT_APPLICATION_MODE       GIMP_PAINT_CONSTANT
@@ -48,6 +49,7 @@
 #define DEFAULT_PRESSURE_RATE          FALSE
 #define DEFAULT_PRESSURE_SIZE          FALSE
 #define DEFAULT_PRESSURE_INVERSE_SIZE  FALSE
+#define DEFAULT_PRESSURE_ASPECT_RATIO  FALSE
 #define DEFAULT_PRESSURE_COLOR         FALSE
 #define DEFAULT_PRESSURE_ANGLE         FALSE
 #define DEFAULT_PRESSURE_PRESCALE      1.0
@@ -57,6 +59,7 @@
 #define DEFAULT_VELOCITY_RATE          FALSE
 #define DEFAULT_VELOCITY_SIZE          FALSE
 #define DEFAULT_VELOCITY_INVERSE_SIZE  FALSE
+#define DEFAULT_VELOCITY_ASPECT_RATIO  FALSE
 #define DEFAULT_VELOCITY_COLOR         FALSE
 #define DEFAULT_VELOCITY_ANGLE         FALSE
 #define DEFAULT_VELOCITY_PRESCALE      1.0
@@ -66,6 +69,7 @@
 #define DEFAULT_DIRECTION_RATE         FALSE
 #define DEFAULT_DIRECTION_SIZE         FALSE
 #define DEFAULT_DIRECTION_INVERSE_SIZE FALSE
+#define DEFAULT_DIRECTION_ASPECT_RATIO FALSE
 #define DEFAULT_DIRECTION_COLOR        FALSE
 #define DEFAULT_DIRECTION_ANGLE        FALSE
 #define DEFAULT_DIRECTION_PRESCALE     1.0
@@ -75,6 +79,7 @@
 #define DEFAULT_TILT_RATE              FALSE
 #define DEFAULT_TILT_SIZE              FALSE
 #define DEFAULT_TILT_INVERSE_SIZE      FALSE
+#define DEFAULT_TILT_ASPECT_RATIO      FALSE
 #define DEFAULT_TILT_COLOR             FALSE
 #define DEFAULT_TILT_ANGLE             FALSE
 #define DEFAULT_TILT_PRESCALE          1.0
@@ -84,6 +89,7 @@
 #define DEFAULT_RANDOM_RATE            FALSE
 #define DEFAULT_RANDOM_SIZE            FALSE
 #define DEFAULT_RANDOM_INVERSE_SIZE    FALSE
+#define DEFAULT_RANDOM_ASPECT_RATIO    FALSE
 #define DEFAULT_RANDOM_COLOR           FALSE
 #define DEFAULT_RANDOM_ANGLE           FALSE
 #define DEFAULT_RANDOM_PRESCALE        1.0
@@ -109,6 +115,7 @@ enum
   PROP_PAINT_INFO,
 
   PROP_BRUSH_SCALE,
+  PROP_BRUSH_ASPECT_RATIO,
   PROP_BRUSH_ANGLE,
 
   PROP_APPLICATION_MODE,
@@ -121,6 +128,7 @@ enum
   PROP_PRESSURE_RATE,
   PROP_PRESSURE_SIZE,
   PROP_PRESSURE_INVERSE_SIZE,
+  PROP_PRESSURE_ASPECT_RATIO,
   PROP_PRESSURE_COLOR,
   PROP_PRESSURE_ANGLE,
   PROP_PRESSURE_PRESCALE,
@@ -130,6 +138,7 @@ enum
   PROP_VELOCITY_RATE,
   PROP_VELOCITY_SIZE,
   PROP_VELOCITY_INVERSE_SIZE,
+  PROP_VELOCITY_ASPECT_RATIO,
   PROP_VELOCITY_COLOR,
   PROP_VELOCITY_ANGLE,
   PROP_VELOCITY_PRESCALE,
@@ -139,6 +148,7 @@ enum
   PROP_DIRECTION_RATE,
   PROP_DIRECTION_SIZE,
   PROP_DIRECTION_INVERSE_SIZE,
+  PROP_DIRECTION_ASPECT_RATIO,
   PROP_DIRECTION_COLOR,
   PROP_DIRECTION_ANGLE,
   PROP_DIRECTION_PRESCALE,
@@ -148,6 +158,7 @@ enum
   PROP_TILT_RATE,
   PROP_TILT_SIZE,
   PROP_TILT_INVERSE_SIZE,
+  PROP_TILT_ASPECT_RATIO,
   PROP_TILT_COLOR,
   PROP_TILT_ANGLE,
   PROP_TILT_PRESCALE,
@@ -157,6 +168,7 @@ enum
   PROP_RANDOM_RATE,
   PROP_RANDOM_SIZE,
   PROP_RANDOM_INVERSE_SIZE,
+  PROP_RANDOM_ASPECT_RATIO,
   PROP_RANDOM_COLOR,
   PROP_RANDOM_ANGLE,
   PROP_RANDOM_PRESCALE,
@@ -233,6 +245,11 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
                                    "brush-scale", _("Brush Scale"),
                                    0.01, 10.0, DEFAULT_BRUSH_SCALE,
                                    GIMP_PARAM_STATIC_STRINGS);
+
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_BRUSH_ASPECT_RATIO,
+                                   "brush-aspect-ratio", NULL,
+                                   0.01, 10.0, DEFAULT_BRUSH_ASPECT_RATIO,
+                                   GIMP_PARAM_STATIC_STRINGS);
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_BRUSH_ANGLE,
                                    "brush-angle", _("Brush Angle"),
                                    -180.0, 180.0, DEFAULT_BRUSH_ANGLE,
@@ -281,6 +298,10 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
                                     "pressure-inverse-size", NULL,
                                     DEFAULT_PRESSURE_INVERSE_SIZE,
                                     GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_PRESSURE_ASPECT_RATIO,
+                                    "pressure-aspect-ratio", NULL,
+                                    DEFAULT_PRESSURE_ASPECT_RATIO,
+                                    GIMP_PARAM_STATIC_STRINGS);
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_PRESSURE_PRESCALE,
                                    "pressure-prescale", NULL,
                                    0.0, 1.0, DEFAULT_PRESSURE_PRESCALE,
@@ -314,6 +335,10 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
                                     "velocity-inverse-size", NULL,
                                     DEFAULT_VELOCITY_INVERSE_SIZE,
                                     GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_VELOCITY_ASPECT_RATIO,
+                                    "velocity-aspect-ratio", NULL,
+                                    DEFAULT_VELOCITY_ASPECT_RATIO,
+                                    GIMP_PARAM_STATIC_STRINGS);
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_VELOCITY_PRESCALE,
                                    "velocity-prescale", NULL,
                                    0.0, 1.0, DEFAULT_VELOCITY_PRESCALE,
@@ -347,6 +372,10 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
                                     "direction-inverse-size", NULL,
                                     DEFAULT_DIRECTION_INVERSE_SIZE,
                                     GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_DIRECTION_ASPECT_RATIO,
+                                    "direction-aspect-ratio", NULL,
+                                    DEFAULT_DIRECTION_ASPECT_RATIO,
+                                    GIMP_PARAM_STATIC_STRINGS);
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_DIRECTION_PRESCALE,
                                    "direction-prescale", NULL,
                                    0.0, 1.0, DEFAULT_DIRECTION_PRESCALE,
@@ -380,6 +409,10 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
                                     "tilt-inverse-size", NULL,
                                     DEFAULT_TILT_INVERSE_SIZE,
                                     GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_TILT_ASPECT_RATIO,
+                                    "tilt-aspect-ratio", NULL,
+                                    DEFAULT_TILT_ASPECT_RATIO,
+                                    GIMP_PARAM_STATIC_STRINGS);
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_TILT_PRESCALE,
                                    "tilt-prescale", NULL,
                                    0.0, 1.0, DEFAULT_TILT_PRESCALE,
@@ -439,7 +472,10 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
                                    "jitter-amount", NULL,
                                    0.0, 50.0, DEFAULT_JITTER_AMOUNT,
                                    GIMP_PARAM_STATIC_STRINGS);
-
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_RANDOM_ASPECT_RATIO,
+                                    "random-aspect-ratio", NULL,
+                                    DEFAULT_RANDOM_ASPECT_RATIO,
+                                    GIMP_PARAM_STATIC_STRINGS);
   GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_USE_GRADIENT,
                                     "use-gradient", NULL,
                                     DEFAULT_USE_GRADIENT,
@@ -560,6 +596,10 @@ gimp_paint_options_set_property (GObject      *object,
       options->brush_scale = g_value_get_double (value);
       break;
 
+    case PROP_BRUSH_ASPECT_RATIO:
+      options->brush_aspect_ratio = g_value_get_double (value);
+      break;
+
     case PROP_BRUSH_ANGLE:
       options->brush_angle = - 1.0 * g_value_get_double (value) / 360.0; /* let's make the angle mathematically correct */
       break;
@@ -596,6 +636,10 @@ gimp_paint_options_set_property (GObject      *object,
       pressure_options->inverse_size = g_value_get_boolean (value);
       break;
 
+    case PROP_PRESSURE_ASPECT_RATIO:
+      pressure_options->aspect_ratio = g_value_get_boolean (value);
+      break;
+
     case PROP_PRESSURE_COLOR:
       pressure_options->color = g_value_get_boolean (value);
       break;
@@ -628,6 +672,10 @@ gimp_paint_options_set_property (GObject      *object,
       velocity_options->inverse_size = g_value_get_boolean (value);
       break;
 
+    case PROP_VELOCITY_ASPECT_RATIO:
+      velocity_options->aspect_ratio = g_value_get_boolean (value);
+      break;
+
     case PROP_VELOCITY_COLOR:
       velocity_options->color = g_value_get_boolean (value);
       break;
@@ -660,6 +708,10 @@ gimp_paint_options_set_property (GObject      *object,
       direction_options->inverse_size = g_value_get_boolean (value);
       break;
 
+    case PROP_DIRECTION_ASPECT_RATIO:
+      direction_options->aspect_ratio = g_value_get_boolean (value);
+      break;
+
     case PROP_DIRECTION_COLOR:
       direction_options->color = g_value_get_boolean (value);
       break;
@@ -692,6 +744,10 @@ gimp_paint_options_set_property (GObject      *object,
       tilt_options->inverse_size = g_value_get_boolean (value);
       break;
 
+    case PROP_TILT_ASPECT_RATIO:
+      tilt_options->aspect_ratio = g_value_get_boolean (value);
+      break;
+
     case PROP_TILT_COLOR:
       tilt_options->color = g_value_get_boolean (value);
       break;
@@ -724,6 +780,10 @@ gimp_paint_options_set_property (GObject      *object,
       random_options->inverse_size = g_value_get_boolean (value);
       break;
 
+    case PROP_RANDOM_ASPECT_RATIO:
+      random_options->aspect_ratio = g_value_get_boolean (value);
+      break;
+
     case PROP_RANDOM_COLOR:
       random_options->color = g_value_get_boolean (value);
       break;
@@ -832,6 +892,10 @@ gimp_paint_options_get_property (GObject    *object,
       g_value_set_double (value, options->brush_scale);
       break;
 
+    case PROP_BRUSH_ASPECT_RATIO:
+      g_value_set_double (value, options->brush_aspect_ratio);
+      break;
+
     case PROP_BRUSH_ANGLE:
       g_value_set_double (value, - 1.0 * options->brush_angle * 360.0); /* mathematically correct -> intuitively correct */
       break;
@@ -868,6 +932,10 @@ gimp_paint_options_get_property (GObject    *object,
       g_value_set_boolean (value, pressure_options->inverse_size);
       break;
 
+    case PROP_PRESSURE_ASPECT_RATIO:
+      g_value_set_boolean (value, pressure_options->aspect_ratio);
+      break;
+
     case PROP_PRESSURE_COLOR:
       g_value_set_boolean (value, pressure_options->color);
       break;
@@ -900,6 +968,10 @@ gimp_paint_options_get_property (GObject    *object,
       g_value_set_boolean (value, velocity_options->inverse_size);
       break;
 
+    case PROP_VELOCITY_ASPECT_RATIO:
+      g_value_set_boolean (value, velocity_options->aspect_ratio);
+      break;
+
     case PROP_VELOCITY_COLOR:
       g_value_set_boolean (value, velocity_options->color);
       break;
@@ -932,6 +1004,10 @@ gimp_paint_options_get_property (GObject    *object,
       g_value_set_boolean (value, direction_options->inverse_size);
       break;
 
+    case PROP_DIRECTION_ASPECT_RATIO:
+      g_value_set_boolean (value, direction_options->aspect_ratio);
+      break;
+
     case PROP_DIRECTION_COLOR:
       g_value_set_boolean (value, direction_options->color);
       break;
@@ -965,6 +1041,10 @@ gimp_paint_options_get_property (GObject    *object,
       g_value_set_boolean (value, tilt_options->inverse_size);
       break;
 
+    case PROP_TILT_ASPECT_RATIO:
+      g_value_set_boolean (value, tilt_options->aspect_ratio);
+      break;
+
     case PROP_TILT_COLOR:
       g_value_set_boolean (value, tilt_options->color);
       break;
@@ -997,6 +1077,10 @@ gimp_paint_options_get_property (GObject    *object,
       g_value_set_boolean (value, random_options->inverse_size);
       break;
 
+    case PROP_RANDOM_ASPECT_RATIO:
+      g_value_set_boolean (value, random_options->aspect_ratio);
+      break;
+
     case PROP_RANDOM_COLOR:
       g_value_set_boolean (value, random_options->color);
       break;
@@ -1490,6 +1574,74 @@ gimp_paint_options_get_dynamic_size (GimpPaintOptions *paint_options,
   return scale;
 }
 
+gdouble
+gimp_paint_options_get_dynamic_aspect_ratio (GimpPaintOptions *paint_options,
+                                             const GimpCoords *coords)
+{
+  gdouble aspect_ratio = 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->aspect_ratio  ||
+      paint_options->velocity_options->aspect_ratio  ||
+      paint_options->direction_options->aspect_ratio ||
+      paint_options->tilt_options->aspect_ratio      ||
+      paint_options->random_options->aspect_ratio)
+    {
+      gdouble pressure  = -1.0;
+      gdouble velocity  = -1.0;
+      gdouble direction = -1.0;
+      gdouble tilt      = -1.0;
+      gdouble random    = -1.0;
+
+
+      if (paint_options->pressure_options->aspect_ratio)
+        pressure = 2 * coords->pressure;
+
+      if (paint_options->velocity_options->aspect_ratio)
+        velocity = 2 * coords->velocity;
+
+      if (paint_options->random_options->aspect_ratio)
+        {
+           random = g_random_double_range (0.0, 1.0);
+           if (random <= 0.5)
+             {
+                random = 1 / (random / 0.5 * (2.0 - 1.0) + 1.0);
+             }
+           else
+             {
+                random = (random - 0.5) / (1.0 - 0.5) * (2.0 - 1.0) + 1.0;
+             }
+        }
+
+     if (paint_options->tilt_options->aspect_ratio)
+       {
+          tilt = sqrt ((1 - fabs (coords->xtilt)) / (1 - fabs (coords->ytilt)));
+       }
+
+      if (paint_options->direction_options->aspect_ratio)
+        {
+           direction = fmod (1 + coords->direction, 0.5) / 0.25;
+
+           if ((coords->direction > 0.0) && (coords->direction < 0.5))
+             direction = 1 / direction;
+        }
+
+      aspect_ratio = gimp_paint_options_get_dynamics_mix (pressure,
+                                                          paint_options->pressure_options->prescale,
+                                                          velocity,
+                                                          paint_options->velocity_options->prescale,
+                                                          random,
+                                                          paint_options->random_options->prescale,
+                                                          tilt,
+                                                          paint_options->tilt_options->prescale,
+                                                          direction,
+                                                          paint_options->direction_options->prescale);
+    }
+
+  return paint_options->brush_aspect_ratio * aspect_ratio;
+}
 
 gdouble
 gimp_paint_options_get_dynamic_rate (GimpPaintOptions *paint_options,
diff --git a/app/paint/gimppaintoptions.h b/app/paint/gimppaintoptions.h
index 386f1cc..e72a632 100644
--- a/app/paint/gimppaintoptions.h
+++ b/app/paint/gimppaintoptions.h
@@ -41,6 +41,7 @@ struct _GimpDynamicOptions
   gboolean  rate;
   gboolean  size;
   gboolean  inverse_size;
+  gboolean  aspect_ratio;
   gboolean  color;
   gboolean  angle;
   gdouble   prescale;
@@ -89,6 +90,7 @@ struct _GimpPaintOptions
 
   gdouble                   brush_scale;
   gdouble                   brush_angle;
+  gdouble                   brush_aspect_ratio;
 
   GimpPaintApplicationMode  application_mode;
   GimpPaintApplicationMode  application_mode_save;
@@ -148,6 +150,10 @@ gdouble gimp_paint_options_get_dynamic_size    (GimpPaintOptions *paint_options,
                                                 const GimpCoords *coords,
                                                 gboolean          use_dynamics);
 
+gdouble gimp_paint_options_get_dynamic_aspect_ratio
+                                               (GimpPaintOptions *paint_options,
+                                                const GimpCoords *coords);
+
 gdouble gimp_paint_options_get_dynamic_rate    (GimpPaintOptions *paint_options,
                                                 const GimpCoords *coords);
 
diff --git a/app/paint/gimpsmudge.c b/app/paint/gimpsmudge.c
index 10265c9..956ba30 100644
--- a/app/paint/gimpsmudge.c
+++ b/app/paint/gimpsmudge.c
@@ -329,7 +329,8 @@ gimp_smudge_brush_coords (GimpPaintCore *paint_core,
   gint           height;
 
   gimp_brush_transform_size (brush_core->brush,
-                             brush_core->scale, brush_core->scale,
+                             brush_core->scale,
+                             brush_core->aspect_ratio,
                              brush_core->angle,
                              &width, &height);
 
diff --git a/app/tools/gimpbrushtool.c b/app/tools/gimpbrushtool.c
index d3bede8..6b77067 100644
--- a/app/tools/gimpbrushtool.c
+++ b/app/tools/gimpbrushtool.c
@@ -162,6 +162,10 @@ gimp_brush_tool_constructor (GType                  type,
                            G_CALLBACK (gimp_brush_tool_brush_transformed),
                            brush_tool, 0);
 
+  g_signal_connect_object (gimp_tool_get_options (tool), "notify::brush-aspect-ratio",
+                           G_CALLBACK (gimp_brush_tool_brush_transformed),
+                           brush_tool, 0);
+
   g_signal_connect (paint_tool->core, "set-brush",
                     G_CALLBACK (gimp_brush_tool_set_brush),
                     brush_tool);
diff --git a/app/tools/gimppaintoptions-gui.c b/app/tools/gimppaintoptions-gui.c
index 4ba155b..3dd34ca 100644
--- a/app/tools/gimppaintoptions-gui.c
+++ b/app/tools/gimppaintoptions-gui.c
@@ -47,12 +47,13 @@
 #include "gimp-intl.h"
 
 
-static gboolean    tool_has_opacity_dynamics  (GType       tool_type);
-static gboolean    tool_has_hardness_dynamics (GType       tool_type);
-static gboolean    tool_has_rate_dynamics     (GType       tool_type);
-static gboolean    tool_has_size_dynamics     (GType       tool_type);
-static gboolean    tool_has_color_dynamics    (GType       tool_type);
-static gboolean    tool_has_angle_dynamics    (GType       tool_type);
+static gboolean    tool_has_opacity_dynamics      (GType       tool_type);
+static gboolean    tool_has_hardness_dynamics     (GType       tool_type);
+static gboolean    tool_has_rate_dynamics         (GType       tool_type);
+static gboolean    tool_has_size_dynamics         (GType       tool_type);
+static gboolean    tool_has_color_dynamics        (GType       tool_type);
+static gboolean    tool_has_angle_dynamics        (GType       tool_type);
+static gboolean    tool_has_aspect_ratio_dynamics (GType       tool_type);
 
 static void        pressure_options_gui  (GimpPaintOptions *paint_options,
                                           GType             tool_type,
@@ -100,7 +101,7 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
   GtkWidget        *incremental_toggle = NULL;
   gint              table_row          = 0;
   gint              n_dynamics         = 0;
-  GtkWidget        *dynamics_labels[6];
+  GtkWidget        *dynamics_labels[7];
   GType             tool_type;
 
   tool_type = tool_options->tool_info->tool_type;
@@ -139,6 +140,8 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
     {
       GtkObject *adj_scale;
       GtkObject *adj_angle;
+      GtkObject *adj_aspect_ratio;
+
 
       button = gimp_prop_brush_box_new (NULL, GIMP_CONTEXT (tool_options), 2,
                                         "brush-view-type", "brush-view-size");
@@ -153,6 +156,13 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
                                              FALSE, 0.0, 0.0);
       gimp_scale_entry_set_logarithmic (adj_scale, TRUE);
 
+      adj_aspect_ratio = gimp_prop_scale_entry_new (config, "brush-aspect-ratio",
+                                                    GTK_TABLE (table), 0, table_row++,
+                                                    _("Aspect Ratio:"),
+                                                    0.01, 0.1, 2,
+                                                    FALSE, 0.0, 0.0);
+      gimp_scale_entry_set_logarithmic (adj_aspect_ratio, TRUE);
+
       adj_angle = gimp_prop_scale_entry_new (config, "brush-angle",
                                              GTK_TABLE (table), 0, table_row++,
                                              _("Angle:"),
@@ -184,6 +194,13 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
       n_dynamics++;
     }
 
+  if (tool_has_aspect_ratio_dynamics (tool_type))
+    {
+      dynamics_labels[n_dynamics] = gtk_label_new (_("Aspect ratio"));
+      n_dynamics++;
+    }
+
+
   if (tool_has_angle_dynamics (tool_type))
     {
       dynamics_labels[n_dynamics] = gtk_label_new (_("Angle"));
@@ -385,6 +402,18 @@ tool_has_size_dynamics (GType tool_type)
 }
 
 static gboolean
+tool_has_aspect_ratio_dynamics (GType tool_type)
+{
+  return (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_CONVOLVE_TOOL          ||
+          tool_type == GIMP_TYPE_DODGE_BURN_TOOL        ||
+          tool_type == GIMP_TYPE_ERASER_TOOL);
+}
+
+static gboolean
 tool_has_angle_dynamics (GType tool_type)
 {
   return (g_type_is_a (tool_type, GIMP_TYPE_PAINTBRUSH_TOOL));
@@ -490,6 +519,17 @@ pressure_options_gui (GimpPaintOptions *paint_options,
       column++;
     }
 
+  if (tool_has_aspect_ratio_dynamics (tool_type))
+    {
+      button = dynamics_check_button_new (config, "pressure-aspect_ratio",
+                                          table, column, row);
+
+      g_signal_connect (button, "size-allocate",
+                        G_CALLBACK (dynamics_check_button_size_allocate),
+                        labels[column - 1]);
+      column++;
+     }
+
   if (tool_has_angle_dynamics (tool_type))
     {
       button = dynamics_check_button_new (config, "pressure-angle",
@@ -550,6 +590,13 @@ velocity_options_gui (GimpPaintOptions *paint_options,
                                  table, column++, row);
     }
 
+  if (tool_has_aspect_ratio_dynamics (tool_type))
+    {
+      dynamics_check_button_new (config, "velocity-aspect-ratio",
+                                 table, column++, row);
+    }
+
+
   if (tool_has_angle_dynamics (tool_type))
     {
       dynamics_check_button_new (config, "velocity-angle",
@@ -602,6 +649,12 @@ direction_options_gui (GimpPaintOptions *paint_options,
                                  table, column++, row);
     }
 
+  if (tool_has_aspect_ratio_dynamics (tool_type))
+    {
+      dynamics_check_button_new (config, "direction-aspect-ratio",
+                                 table, column++, row);
+    }
+
   if (tool_has_angle_dynamics (tool_type))
     {
       dynamics_check_button_new (config, "direction-angle",
@@ -655,6 +708,12 @@ tilt_options_gui (GimpPaintOptions *paint_options,
                                  table, column++, row);
     }
 
+if (tool_has_aspect_ratio_dynamics (tool_type))
+    {
+      dynamics_check_button_new (config, "tilt-aspect-ratio",
+                                 table, column++, row);
+    }
+
   if (tool_has_angle_dynamics (tool_type))
     {
       dynamics_check_button_new (config, "tilt-angle",
@@ -707,6 +766,12 @@ random_options_gui (GimpPaintOptions *paint_options,
                                  table, column++, row);
     }
 
+  if (tool_has_aspect_ratio_dynamics (tool_type))
+    {
+      dynamics_check_button_new (config, "random-aspect-ratio",
+                                 table, column++, row);
+    }
+
   if (tool_has_angle_dynamics (tool_type))
     {
       dynamics_check_button_new (config, "random-angle",



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