[gimp] app: Make brush boundaries dynamic aswell



commit 44a5a34d7e083453fb0aa9093f3a99f19d476569
Author: Alexia Death <alexiadeath gmail com>
Date:   Mon Mar 15 02:20:13 2010 +0200

    app: Make brush boundaries dynamic aswell

 app/base/boundary.c       |   43 ++++++++++
 app/base/boundary.h       |    3 +
 app/paint/gimpbrushcore.c |  200 ++++++++++++++++++++++++++++++--------------
 app/paint/gimpbrushcore.h |   10 ++
 app/tools/gimpbrushtool.c |   23 +++++-
 5 files changed, 212 insertions(+), 67 deletions(-)
---
diff --git a/app/base/boundary.c b/app/base/boundary.c
index bb864f3..c8ca075 100644
--- a/app/base/boundary.c
+++ b/app/base/boundary.c
@@ -361,6 +361,49 @@ boundary_simplify (BoundSeg *sorted_segs,
   return (BoundSeg *) g_array_free (new_bounds, FALSE);
 }
 
+/*Transform boundary based on a matrix*/
+
+BoundSeg * boundary_transform (const BoundSeg *segs,
+                               gint           *num_segs,
+                               GimpMatrix3    *matrix)
+{
+
+  Boundary *boundary = boundary_new(NULL);
+  gint i;
+
+      for (i = 0; i < *num_segs; i++)
+        {
+
+
+          /*dont transform sorting sentinels*/
+          if (!(segs[i].x1 == -1 &&
+                segs[i].y1 == -1 &&
+                segs[i].x2 == -1 &&
+                segs[i].y2 == -1))
+            {
+              gdouble x1, y1, x2, y2;
+
+              gimp_matrix3_transform_point (matrix, segs[i].x1, segs[i].y1, &x1, &y1);
+              gimp_matrix3_transform_point (matrix, segs[i].x2, segs[i].y2, &x2, &y2);
+
+              boundary_add_seg (boundary,
+                                (gint) ceil(x1), (gint) ceil(y1),
+                                (gint) ceil(x2), (gint) ceil(y2),
+                                segs[i].open);
+            }
+          else
+            {
+              /*Keep the sorting sentinel*/
+              boundary_add_seg (boundary,
+                                -1, -1,
+                                -1, -1,
+                                segs[i].open);
+            }
+        }
+      *num_segs = boundary->num_segs;
+      return boundary_free(boundary, FALSE);
+}
+
 
 /*  private functions  */
 
diff --git a/app/base/boundary.h b/app/base/boundary.h
index 9577d9c..7192b78 100644
--- a/app/base/boundary.h
+++ b/app/base/boundary.h
@@ -56,6 +56,9 @@ BoundSeg * boundary_simplify  (BoundSeg       *sorted_segs,
                                gint            num_groups,
                                gint           *num_segs);
 
+BoundSeg * boundary_transform (const BoundSeg *segs,
+                               gint           *num_segs,
+                               GimpMatrix3    *matrix);
 
 
 #endif  /*  __BOUNDARY_H__  */
diff --git a/app/paint/gimpbrushcore.c b/app/paint/gimpbrushcore.c
index 846a407..3bbb770 100644
--- a/app/paint/gimpbrushcore.c
+++ b/app/paint/gimpbrushcore.c
@@ -213,6 +213,7 @@ gimp_brush_core_init (GimpBrushCore *core)
   core->rand                         = g_rand_new ();
 
   core->brush_bound_segs             = NULL;
+  core->transformed_brush_bound_segs = NULL;
   core->n_brush_bound_segs           = 0;
   core->brush_bound_width            = 0;
   core->brush_bound_height           = 0;
@@ -315,6 +316,12 @@ gimp_brush_core_finalize (GObject *object)
       core->brush_bound_height = 0;
     }
 
+  if (core->transformed_brush_bound_segs)
+    {
+      g_free (core->transformed_brush_bound_segs);
+      core->transformed_brush_bound_segs   = NULL;
+    }
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -432,33 +439,10 @@ gimp_brush_core_start (GimpPaintCore     *paint_core,
 
   if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
     {
-      GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
-      gdouble    fade_point;
-
-      core->scale        = paint_options->brush_scale;
-      core->angle        = paint_options->brush_angle;
-      core->aspect_ratio = paint_options->brush_aspect_ratio;
-
-      if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
-        {
-          fade_point = gimp_paint_options_get_fade (paint_options, image,
-                                                    paint_core->pixel_dist);
-
-          core->scale *= gimp_dynamics_output_get_linear_value (core->dynamics->size_output,
-                                                                coords,
-                                                                paint_options,
-                                                                fade_point);
-
-          core->angle += gimp_dynamics_output_get_angular_value (core->dynamics->angle_output,
-                                                                 coords,
-                                                                 paint_options,
-                                                                 fade_point);
-
-          core->aspect_ratio *= gimp_dynamics_output_get_aspect_value (core->dynamics->aspect_ratio_output,
-                                                                       coords,
-                                                                       paint_options,
-                                                                       fade_point);
-        }
+      gimp_brush_core_eval_transform_dynamics (paint_core,
+                                               drawable,
+                                               paint_options,
+                                               coords);
     }
 
   core->spacing = (gdouble) gimp_brush_get_spacing (core->main_brush) / 100.0;
@@ -845,42 +829,10 @@ gimp_brush_core_get_paint_area (GimpPaintCore    *paint_core,
 
   if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_transforming_brush)
     {
-      GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
-      gdouble    fade_point;
-
-      core->scale = paint_options->brush_scale;
-      core->angle = paint_options->brush_angle;
-      core->aspect_ratio = paint_options->brush_aspect_ratio;
-
-      if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
-        {
-          fade_point = gimp_paint_options_get_fade (paint_options, image,
-                                                    paint_core->pixel_dist);
-
-          core->scale *=
-            gimp_dynamics_output_get_linear_value (core->dynamics->size_output,
-                                                   coords,
-                                                   paint_options,
-                                                   fade_point);
-
-          core->angle +=
-            gimp_dynamics_output_get_angular_value (core->dynamics->angle_output,
-                                                    coords,
-                                                    paint_options,
-                                                    fade_point);
-
-          core->hardness =
-            gimp_dynamics_output_get_linear_value (core->dynamics->hardness_output,
-                                                   coords,
-                                                   paint_options,
-                                                   fade_point);
-
-          core->aspect_ratio *=
-            gimp_dynamics_output_get_aspect_value (core->dynamics->aspect_ratio_output,
-                                                   coords,
-                                                   paint_options,
-                                                   fade_point);
-        }
+      gimp_brush_core_eval_transform_dynamics (paint_core,
+                                               drawable,
+                                               paint_options,
+                                               coords);
     }
 
   core->scale = gimp_brush_core_clamp_brush_scale (core, core->scale);
@@ -1006,7 +958,7 @@ gimp_brush_core_create_bound_segs (GimpBrushCore    *core,
       scale = gimp_brush_core_clamp_brush_scale (core, scale);
 
       mask = gimp_brush_transform_mask (core->main_brush,
-                                        scale, aspect_ratio, angle, 1.0);
+                                        1.0, 1.0, 0.0, 1.0);
     }
 
   if (mask)
@@ -1046,6 +998,74 @@ gimp_brush_core_create_bound_segs (GimpBrushCore    *core,
 }
 
 void
+gimp_brush_core_transform_bound_segs (GimpBrushCore    *core,
+                                      GimpPaintOptions *paint_options)
+{
+  gdouble      scale;
+  gdouble      angle;
+  gdouble      aspect_ratio;
+  gdouble      height;
+  gdouble      width;
+  GimpMatrix3  matrix;
+  gdouble      scale_x;
+  gdouble      scale_y;
+
+
+  g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
+  g_return_if_fail (core->main_brush != NULL);
+  g_return_if_fail (core->brush_bound_segs != NULL);
+
+  scale = core->scale;
+  angle = core->angle;
+  aspect_ratio = core->aspect_ratio;
+
+  height = core->main_brush->mask->height;
+  width  = core->main_brush->mask->width;
+
+  if (aspect_ratio < 1.0)
+    {
+        scale_x = scale * aspect_ratio;
+        scale_y = scale;
+    }
+  else
+    {
+      scale_x = scale;
+      scale_y = scale / aspect_ratio;
+    }
+
+  if (core->transformed_brush_bound_segs)
+    {
+      g_free (core->transformed_brush_bound_segs);
+      core->transformed_brush_bound_segs   = NULL;
+    }
+
+
+  if ((scale > 0.0) && (aspect_ratio > 0.0))
+    {
+
+      const gdouble center_x = width  / 2;
+      const gdouble center_y = height / 2;
+
+      scale = gimp_brush_core_clamp_brush_scale (core, scale);
+
+      gimp_matrix3_identity (&matrix);
+      gimp_matrix3_translate (&matrix, - center_x, - center_y);
+      gimp_matrix3_rotate (&matrix, -2 * G_PI * angle);
+      gimp_matrix3_translate (&matrix, center_x, center_y);
+      gimp_matrix3_scale (&matrix, scale_x, scale_y);
+
+      core->transformed_brush_bound_segs
+                      = boundary_transform (core->brush_bound_segs,
+                                            &core->n_brush_bound_segs,
+                                            &matrix);
+
+      core->transformed_brush_bound_width = core->brush_bound_width * scale_x;
+      core->transformed_brush_bound_height = core->brush_bound_height * scale_y;
+    }
+
+}
+
+void
 gimp_brush_core_paste_canvas (GimpBrushCore            *core,
                               GimpDrawable             *drawable,
                               const GimpCoords         *coords,
@@ -1653,6 +1673,58 @@ gimp_brush_core_get_brush_mask (GimpBrushCore            *core,
   return mask;
 }
 
+void
+gimp_brush_core_eval_transform_dynamics (GimpPaintCore     *paint_core,
+                                         GimpDrawable      *drawable,
+                                         GimpPaintOptions  *paint_options,
+                                         const GimpCoords  *coords)
+{
+  GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
+  GimpImage *image;
+  gdouble    fade_point = 1.0;
+
+  core->scale = paint_options->brush_scale;
+  core->angle = paint_options->brush_angle;
+  core->aspect_ratio = paint_options->brush_aspect_ratio;
+
+  g_return_if_fail (GIMP_IS_DYNAMICS (core->dynamics));
+
+  if (GIMP_BRUSH_CORE_GET_CLASS (core)->handles_dynamic_transforming_brush)
+    {
+      if (drawable)
+        {
+          image = gimp_item_get_image (GIMP_ITEM (drawable));
+          fade_point = gimp_paint_options_get_fade (paint_options, image,
+                                                    paint_core->pixel_dist);
+        }
+
+      core->scale *=
+            gimp_dynamics_output_get_linear_value (core->dynamics->size_output,
+                                                   coords,
+                                                   paint_options,
+                                                   fade_point);
+
+      core->angle +=
+            gimp_dynamics_output_get_angular_value (core->dynamics->angle_output,
+                                                    coords,
+                                                    paint_options,
+                                                    fade_point);
+
+      core->hardness =
+            gimp_dynamics_output_get_linear_value (core->dynamics->hardness_output,
+                                                   coords,
+                                                   paint_options,
+                                                   fade_point);
+
+      core->aspect_ratio *=
+            gimp_dynamics_output_get_aspect_value (core->dynamics->aspect_ratio_output,
+                                                   coords,
+                                                   paint_options,
+                                                   fade_point);
+    }
+
+}
+
 
 /**************************************************/
 /*  Brush pipe utility functions                  */
diff --git a/app/paint/gimpbrushcore.h b/app/paint/gimpbrushcore.h
index 05fb34a..16c055b 100644
--- a/app/paint/gimpbrushcore.h
+++ b/app/paint/gimpbrushcore.h
@@ -84,9 +84,12 @@ struct _GimpBrushCore
 
   /*  don't use these...  */
   BoundSeg      *brush_bound_segs;
+  BoundSeg      *transformed_brush_bound_segs;
   gint           n_brush_bound_segs;
   gint           brush_bound_width;
   gint           brush_bound_height;
+  gint           transformed_brush_bound_width;
+  gint           transformed_brush_bound_height;
 };
 
 struct _GimpBrushCoreClass
@@ -118,6 +121,8 @@ void    gimp_brush_core_set_dynamics   (GimpBrushCore            *core,
 
 void    gimp_brush_core_create_bound_segs (GimpBrushCore         *core,
                                            GimpPaintOptions      *options);
+void gimp_brush_core_transform_bound_segs (GimpBrushCore    *core,
+                                           GimpPaintOptions *paint_options);
 
 void    gimp_brush_core_paste_canvas   (GimpBrushCore            *core,
                                         GimpDrawable             *drawable,
@@ -150,4 +155,9 @@ TempBuf * gimp_brush_core_get_brush_mask (GimpBrushCore            *core,
                                           gdouble                   dynamic_hardness);
 
 
+void gimp_brush_core_eval_transform_dynamics (GimpPaintCore     *paint_core,
+                                              GimpDrawable      *drawable,
+                                              GimpPaintOptions  *paint_options,
+                                              const GimpCoords  *coords);
+
 #endif  /*  __GIMP_BRUSH_CORE_H__  */
diff --git a/app/tools/gimpbrushtool.c b/app/tools/gimpbrushtool.c
index 74c28ac..03ace86 100644
--- a/app/tools/gimpbrushtool.c
+++ b/app/tools/gimpbrushtool.c
@@ -220,6 +220,7 @@ gimp_brush_tool_oper_update (GimpTool         *tool,
       GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
       GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
       GimpBrush     *brush;
+      GimpDynamics  *dynamics;
 
       brush_tool->brush_x = coords->x;
       brush_tool->brush_y = coords->y;
@@ -228,6 +229,19 @@ gimp_brush_tool_oper_update (GimpTool         *tool,
 
       if (brush_core->main_brush != brush)
         gimp_brush_core_set_brush (brush_core, brush);
+
+      dynamics = gimp_context_get_dynamics (GIMP_CONTEXT (paint_options));
+
+      if (brush_core->dynamics != dynamics)
+        gimp_brush_core_set_dynamics (brush_core, dynamics);
+
+      if (GIMP_BRUSH_CORE_GET_CLASS (brush_core)->handles_transforming_brush)
+        {
+          gimp_brush_core_eval_transform_dynamics (paint_tool->core,
+                                                   NULL,
+                                                   paint_options,
+                                                   coords);
+        }
     }
 
   gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
@@ -302,10 +316,13 @@ gimp_brush_tool_draw_brush (GimpBrushTool *brush_tool,
     }
 
   if (brush_core->brush_bound_segs)
+      gimp_brush_core_transform_bound_segs (brush_core, options);
+
+  if (brush_core->transformed_brush_bound_segs)
     {
       GimpDisplayShell *shell  = gimp_display_get_shell (draw_tool->display);
-      gdouble           width  = brush_core->brush_bound_width;
-      gdouble           height = brush_core->brush_bound_height;
+      gdouble           width  = brush_core->transformed_brush_bound_width;
+      gdouble           height = brush_core->transformed_brush_bound_height;
 
       /*  don't draw the boundary if it becomes too small  */
       if (SCALEX (shell, width) > 4 && SCALEY (shell, height) > 4)
@@ -326,7 +343,7 @@ gimp_brush_tool_draw_brush (GimpBrushTool *brush_tool,
             }
 
           gimp_draw_tool_draw_boundary (draw_tool,
-                                        brush_core->brush_bound_segs,
+                                        brush_core->transformed_brush_bound_segs,
                                         brush_core->n_brush_bound_segs,
                                         x, y,
                                         FALSE);



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