[gimp/gimp-2-10] app: derive GimpEraser from GimpPaintbrush



commit b2dac69b7ea12d19358f390fbd70708b4b3bef36
Author: Ell <ell_se yahoo com>
Date:   Sun May 26 14:38:24 2019 -0400

    app: derive GimpEraser from GimpPaintbrush
    
    In GimpPaintbrush, factor out the code responsible for determining
    the current dab's paint parameters and content to a new
    GimpPaintbrush::get_paint_params() virtual function.
    
    Derive GimpEraser from GimpPaintbrush, instead of directly from
    GimpBrushCore, implementing get_paint_params() appropriately.
    This allows GimpEraser to reuse the paint-buffer content across
    dabs, improving performance.
    
    (cherry picked from commit aba4eef916172460dde062ac76c86cf6e1f71a52)

 app/paint/gimperaser.c     | 148 +++++++++++---------------------------
 app/paint/gimperaser.h     |   6 +-
 app/paint/gimppaintbrush.c | 176 ++++++++++++++++++++++++++++-----------------
 app/paint/gimppaintbrush.h |  10 +++
 4 files changed, 164 insertions(+), 176 deletions(-)
---
diff --git a/app/paint/gimperaser.c b/app/paint/gimperaser.c
index 541b622ba5..b360f18ca9 100644
--- a/app/paint/gimperaser.c
+++ b/app/paint/gimperaser.c
@@ -38,19 +38,26 @@
 #include "gimp-intl.h"
 
 
-static void   gimp_eraser_paint  (GimpPaintCore    *paint_core,
-                                  GimpDrawable     *drawable,
-                                  GimpPaintOptions *paint_options,
-                                  GimpSymmetry     *sym,
-                                  GimpPaintState    paint_state,
-                                  guint32           time);
-static void   gimp_eraser_motion (GimpPaintCore    *paint_core,
-                                  GimpDrawable     *drawable,
-                                  GimpPaintOptions *paint_options,
-                                  GimpSymmetry     *sym);
+static void   gimp_eraser_paint            (GimpPaintCore             *paint_core,
+                                            GimpDrawable              *drawable,
+                                            GimpPaintOptions          *paint_options,
+                                            GimpSymmetry              *sym,
+                                            GimpPaintState             paint_state,
+                                            guint32                    time);
 
+static void   gimp_eraser_get_paint_params (GimpPaintbrush            *paintbrush,
+                                            GimpDrawable              *drawable,
+                                            GimpPaintOptions          *paint_options,
+                                            GimpSymmetry              *sym,
+                                            GimpLayerMode             *paint_mode,
+                                            GimpPaintApplicationMode  *paint_appl_mode,
+                                            const GimpTempBuf        **paint_pixmap,
+                                            GimpRGB                   *paint_color);
 
-G_DEFINE_TYPE (GimpEraser, gimp_eraser, GIMP_TYPE_BRUSH_CORE)
+
+G_DEFINE_TYPE (GimpEraser, gimp_eraser, GIMP_TYPE_PAINTBRUSH)
+
+#define parent_class gimp_eraser_parent_class
 
 
 void
@@ -68,12 +75,12 @@ gimp_eraser_register (Gimp                      *gimp,
 static void
 gimp_eraser_class_init (GimpEraserClass *klass)
 {
-  GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
-  GimpBrushCoreClass *brush_core_class = GIMP_BRUSH_CORE_CLASS (klass);
+  GimpPaintCoreClass  *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
+  GimpPaintbrushClass *paintbrush_class = GIMP_PAINTBRUSH_CLASS (klass);
 
-  paint_core_class->paint = gimp_eraser_paint;
+  paint_core_class->paint            = gimp_eraser_paint;
 
-  brush_core_class->handles_changing_brush = TRUE;
+  paintbrush_class->get_paint_params = gimp_eraser_get_paint_params;
 }
 
 static void
@@ -108,108 +115,37 @@ gimp_eraser_paint (GimpPaintCore    *paint_core,
             }
         }
       break;
-    case GIMP_PAINT_STATE_MOTION:
-      gimp_eraser_motion (paint_core, drawable, paint_options, sym);
-      break;
 
     default:
       break;
     }
+
+  GIMP_PAINT_CORE_CLASS (parent_class)->paint (paint_core, drawable,
+                                               paint_options, sym,
+                                               paint_state, time);
 }
 
 static void
-gimp_eraser_motion (GimpPaintCore    *paint_core,
-                    GimpDrawable     *drawable,
-                    GimpPaintOptions *paint_options,
-                    GimpSymmetry     *sym)
+gimp_eraser_get_paint_params (GimpPaintbrush            *paintbrush,
+                              GimpDrawable              *drawable,
+                              GimpPaintOptions          *paint_options,
+                              GimpSymmetry              *sym,
+                              GimpLayerMode             *paint_mode,
+                              GimpPaintApplicationMode  *paint_appl_mode,
+                              const GimpTempBuf        **paint_pixmap,
+                              GimpRGB                   *paint_color)
 {
-  GimpBrushCore     *brush_core = GIMP_BRUSH_CORE (paint_core);
-  GimpEraserOptions *options    = GIMP_ERASER_OPTIONS (paint_options);
-  GimpContext       *context    = GIMP_CONTEXT (paint_options);
-  GimpDynamics      *dynamics   = GIMP_BRUSH_CORE (paint_core)->dynamics;
-  GimpImage         *image      = gimp_item_get_image (GIMP_ITEM (drawable));
-  gdouble            fade_point;
-  gdouble            opacity;
-  GimpLayerMode      paint_mode;
-  GeglBuffer        *paint_buffer;
-  gint               paint_buffer_x;
-  gint               paint_buffer_y;
-  GimpRGB            background;
-  GeglColor         *color;
-  gdouble            force;
-  const GimpCoords  *coords;
-  gint               n_strokes;
-  gint               paint_width, paint_height;
-  gint               i;
-
-  fade_point = gimp_paint_options_get_fade (paint_options, image,
-                                            paint_core->pixel_dist);
-
-  coords = gimp_symmetry_get_origin (sym);
-  opacity = gimp_dynamics_get_linear_value (dynamics,
-                                            GIMP_DYNAMICS_OUTPUT_OPACITY,
-                                            coords,
-                                            paint_options,
-                                            fade_point);
-  if (opacity == 0.0)
-    return;
-
-  gimp_context_get_background (context, &background);
+  GimpEraserOptions *options = GIMP_ERASER_OPTIONS (paint_options);
+  GimpContext       *context = GIMP_CONTEXT (paint_options);
+
+  gimp_context_get_background (context, paint_color);
   gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (drawable),
-                                     &background, &background);
-  color = gimp_gegl_color_new (&background);
+                                     paint_color, paint_color);
 
   if (options->anti_erase)
-    paint_mode = GIMP_LAYER_MODE_ANTI_ERASE;
+    *paint_mode = GIMP_LAYER_MODE_ANTI_ERASE;
   else if (gimp_drawable_has_alpha (drawable))
-    paint_mode = GIMP_LAYER_MODE_ERASE;
+    *paint_mode = GIMP_LAYER_MODE_ERASE;
   else
-    paint_mode = GIMP_LAYER_MODE_NORMAL_LEGACY;
-
-  gimp_brush_core_eval_transform_dynamics (brush_core,
-                                           drawable,
-                                           paint_options,
-                                           coords);
-
-  n_strokes = gimp_symmetry_get_size (sym);
-  for (i = 0; i < n_strokes; i++)
-    {
-      coords = gimp_symmetry_get_coords (sym, i);
-
-      gimp_brush_core_eval_transform_symmetry (brush_core, sym, i);
-
-      if (gimp_dynamics_is_output_enabled (dynamics, GIMP_DYNAMICS_OUTPUT_FORCE))
-        force = gimp_dynamics_get_linear_value (dynamics,
-                                                GIMP_DYNAMICS_OUTPUT_FORCE,
-                                                coords,
-                                                paint_options,
-                                                fade_point);
-      else
-        force = paint_options->brush_force;
-
-
-      paint_buffer = gimp_paint_core_get_paint_buffer (paint_core, drawable,
-                                                       paint_options,
-                                                       paint_mode,
-                                                       coords,
-                                                       &paint_buffer_x,
-                                                       &paint_buffer_y,
-                                                       &paint_width,
-                                                       &paint_height);
-      if (! paint_buffer)
-        continue;
-
-      gegl_buffer_set_color (paint_buffer, NULL, color);
-
-      gimp_brush_core_paste_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
-                                    coords,
-                                    MIN (opacity, GIMP_OPACITY_OPAQUE),
-                                    gimp_context_get_opacity (context),
-                                    paint_mode,
-                                    gimp_paint_options_get_brush_mode (paint_options),
-                                    force,
-                                    paint_options->application_mode);
-    }
-
-  g_object_unref (color);
+    *paint_mode = GIMP_LAYER_MODE_NORMAL_LEGACY;
 }
diff --git a/app/paint/gimperaser.h b/app/paint/gimperaser.h
index 748cf253e4..5b04a3292f 100644
--- a/app/paint/gimperaser.h
+++ b/app/paint/gimperaser.h
@@ -19,7 +19,7 @@
 #define __GIMP_ERASER_H__
 
 
-#include "gimpbrushcore.h"
+#include "gimppaintbrush.h"
 
 
 #define GIMP_TYPE_ERASER            (gimp_eraser_get_type ())
@@ -34,12 +34,12 @@ typedef struct _GimpEraserClass GimpEraserClass;
 
 struct _GimpEraser
 {
-  GimpBrushCore  parent_instance;
+  GimpPaintbrush  parent_instance;
 };
 
 struct _GimpEraserClass
 {
-  GimpBrushCoreClass  parent_class;
+  GimpPaintbrushClass  parent_class;
 };
 
 
diff --git a/app/paint/gimppaintbrush.c b/app/paint/gimppaintbrush.c
index 8f39944285..1db8fea250 100644
--- a/app/paint/gimppaintbrush.c
+++ b/app/paint/gimppaintbrush.c
@@ -46,12 +46,21 @@
 #include "gimp-intl.h"
 
 
-static void   gimp_paintbrush_paint (GimpPaintCore    *paint_core,
-                                     GimpDrawable     *drawable,
-                                     GimpPaintOptions *paint_options,
-                                     GimpSymmetry     *sym,
-                                     GimpPaintState    paint_state,
-                                     guint32           time);
+static void   gimp_paintbrush_paint                 (GimpPaintCore             *paint_core,
+                                                     GimpDrawable              *drawable,
+                                                     GimpPaintOptions          *paint_options,
+                                                     GimpSymmetry              *sym,
+                                                     GimpPaintState             paint_state,
+                                                     guint32                    time);
+
+static void   gimp_paintbrush_real_get_paint_params (GimpPaintbrush            *paintbrush,
+                                                     GimpDrawable              *drawable,
+                                                     GimpPaintOptions          *paint_options,
+                                                     GimpSymmetry              *sym,
+                                                     GimpLayerMode             *paint_mode,
+                                                     GimpPaintApplicationMode  *paint_appl_mode,
+                                                     const GimpTempBuf        **paint_pixmap,
+                                                     GimpRGB                   *paint_color);
 
 
 G_DEFINE_TYPE (GimpPaintbrush, gimp_paintbrush, GIMP_TYPE_BRUSH_CORE)
@@ -78,6 +87,8 @@ gimp_paintbrush_class_init (GimpPaintbrushClass *klass)
   paint_core_class->paint                  = gimp_paintbrush_paint;
 
   brush_core_class->handles_changing_brush = TRUE;
+
+  klass->get_paint_params                  = gimp_paintbrush_real_get_paint_params;
 }
 
 static void
@@ -139,6 +150,66 @@ gimp_paintbrush_paint (GimpPaintCore    *paint_core,
     }
 }
 
+static void
+gimp_paintbrush_real_get_paint_params (GimpPaintbrush            *paintbrush,
+                                       GimpDrawable              *drawable,
+                                       GimpPaintOptions          *paint_options,
+                                       GimpSymmetry              *sym,
+                                       GimpLayerMode             *paint_mode,
+                                       GimpPaintApplicationMode  *paint_appl_mode,
+                                       const GimpTempBuf        **paint_pixmap,
+                                       GimpRGB                   *paint_color)
+{
+  GimpPaintCore    *paint_core = GIMP_PAINT_CORE (paintbrush);
+  GimpBrushCore    *brush_core = GIMP_BRUSH_CORE (paintbrush);
+  GimpContext      *context    = GIMP_CONTEXT (paint_options);
+  GimpDynamics     *dynamics   = brush_core->dynamics;
+  GimpImage        *image      = gimp_item_get_image (GIMP_ITEM (drawable));
+  const GimpCoords *coords     = gimp_symmetry_get_origin (sym);
+  gdouble           fade_point;
+  gdouble           grad_point;
+
+  fade_point = gimp_paint_options_get_fade (paint_options, image,
+                                            paint_core->pixel_dist);
+
+  grad_point = gimp_dynamics_get_linear_value (dynamics,
+                                               GIMP_DYNAMICS_OUTPUT_COLOR,
+                                               coords,
+                                               paint_options,
+                                               fade_point);
+
+  *paint_mode = gimp_context_get_paint_mode (context);
+
+  if (gimp_paint_options_get_gradient_color (paint_options, image,
+                                             grad_point,
+                                             paint_core->pixel_dist,
+                                             paint_color))
+    {
+      /* optionally take the color from the current gradient */
+      gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (drawable),
+                                         paint_color, paint_color);
+
+      *paint_appl_mode = GIMP_PAINT_INCREMENTAL;
+    }
+  else if (brush_core->brush && gimp_brush_get_pixmap (brush_core->brush))
+    {
+      /* otherwise check if the brush has a pixmap and use that to
+       * color the area
+       */
+      *paint_pixmap = gimp_brush_core_get_brush_pixmap (brush_core);
+
+      *paint_appl_mode = GIMP_PAINT_INCREMENTAL;
+    }
+  else
+    {
+      /* otherwise fill the area with the foreground color */
+      gimp_context_get_foreground (context, paint_color);
+
+      gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (drawable),
+                                         paint_color, paint_color);
+    }
+}
+
 void
 _gimp_paintbrush_motion (GimpPaintCore    *paint_core,
                          GimpDrawable     *drawable,
@@ -146,24 +217,16 @@ _gimp_paintbrush_motion (GimpPaintCore    *paint_core,
                          GimpSymmetry     *sym,
                          gdouble           opacity)
 {
-  GimpBrushCore            *brush_core = GIMP_BRUSH_CORE (paint_core);
-  GimpPaintbrush           *paintbrush = GIMP_PAINTBRUSH (paint_core);
-  GimpContext              *context    = GIMP_CONTEXT (paint_options);
-  GimpDynamics             *dynamics   = brush_core->dynamics;
-  GimpImage                *image;
-  GimpLayerMode             paint_mode;
-  GeglBuffer               *paint_buffer;
-  gint                      paint_buffer_x;
-  gint                      paint_buffer_y;
-  GimpPaintApplicationMode  paint_appl_mode;
-  gdouble                   fade_point;
-  gdouble                   grad_point;
-  gdouble                   force;
-  const GimpCoords         *coords;
-  gint                      n_strokes;
-  gint                      i;
-
-  image = gimp_item_get_image (GIMP_ITEM (drawable));
+  GimpBrushCore    *brush_core = GIMP_BRUSH_CORE (paint_core);
+  GimpPaintbrush   *paintbrush = GIMP_PAINTBRUSH (paint_core);
+  GimpContext      *context    = GIMP_CONTEXT (paint_options);
+  GimpDynamics     *dynamics   = brush_core->dynamics;
+  GimpImage        *image      = gimp_item_get_image (GIMP_ITEM (drawable));
+  gdouble           fade_point;
+  gdouble           force;
+  const GimpCoords *coords;
+  gint              n_strokes;
+  gint              i;
 
   fade_point = gimp_paint_options_get_fade (paint_options, image,
                                             paint_core->pixel_dist);
@@ -178,15 +241,6 @@ _gimp_paintbrush_motion (GimpPaintCore    *paint_core,
   if (opacity == 0.0)
     return;
 
-  paint_appl_mode = paint_options->application_mode;
-
-  grad_point = gimp_dynamics_get_linear_value (dynamics,
-                                               GIMP_DYNAMICS_OUTPUT_COLOR,
-                                               coords,
-                                               paint_options,
-                                               fade_point);
-
-
   if (GIMP_BRUSH_CORE_GET_CLASS (brush_core)->handles_transforming_brush)
     {
       gimp_brush_core_eval_transform_dynamics (brush_core,
@@ -195,14 +249,28 @@ _gimp_paintbrush_motion (GimpPaintCore    *paint_core,
                                                coords);
     }
 
-  paint_mode = gimp_context_get_paint_mode (context);
-
   n_strokes = gimp_symmetry_get_size (sym);
   for (i = 0; i < n_strokes; i++)
     {
-      const GimpTempBuf *paint_pixmap = NULL;
-      GimpRGB            paint_color;
-      gint               paint_width, paint_height;
+      GimpLayerMode             paint_mode;
+      GimpPaintApplicationMode  paint_appl_mode;
+      GeglBuffer               *paint_buffer;
+      gint                      paint_buffer_x;
+      gint                      paint_buffer_y;
+      const GimpTempBuf        *paint_pixmap = NULL;
+      GimpRGB                   paint_color;
+      gint                      paint_width, paint_height;
+
+      paint_appl_mode = paint_options->application_mode;
+
+      GIMP_PAINTBRUSH_GET_CLASS (paintbrush)->get_paint_params (paintbrush,
+                                                                drawable,
+                                                                paint_options,
+                                                                sym,
+                                                                &paint_mode,
+                                                                &paint_appl_mode,
+                                                                &paint_pixmap,
+                                                                &paint_color);
 
       coords = gimp_symmetry_get_coords (sym, i);
 
@@ -220,33 +288,10 @@ _gimp_paintbrush_motion (GimpPaintCore    *paint_core,
       if (! paint_buffer)
         continue;
 
-      if (gimp_paint_options_get_gradient_color (paint_options, image,
-                                                 grad_point,
-                                                 paint_core->pixel_dist,
-                                                 &paint_color))
+      if (! paint_pixmap)
         {
-          /* optionally take the color from the current gradient */
-          gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (drawable),
-                                             &paint_color, &paint_color);
-
-          paint_appl_mode = GIMP_PAINT_INCREMENTAL;
-        }
-      else if (brush_core->brush && gimp_brush_get_pixmap (brush_core->brush))
-        {
-          /* otherwise check if the brush has a pixmap and use that to
-           * color the area
-           */
-          paint_pixmap = gimp_brush_core_get_brush_pixmap (brush_core);
-
-          paint_appl_mode = GIMP_PAINT_INCREMENTAL;
-        }
-      else
-        {
-          /* otherwise fill the area with the foreground color */
-          gimp_context_get_foreground (context, &paint_color);
-
-          gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (drawable),
-                                             &paint_color, &paint_color);
+          opacity *= paint_color.a;
+          gimp_rgb_set_alpha (&paint_color, GIMP_OPACITY_OPAQUE);
         }
 
       /* fill the paint buffer.  we can skip this step when reusing the
@@ -299,9 +344,6 @@ _gimp_paintbrush_motion (GimpPaintCore    *paint_core,
             {
               GeglColor *color;
 
-              opacity *= paint_color.a;
-              gimp_rgb_set_alpha (&paint_color, GIMP_OPACITY_OPAQUE);
-
               color = gimp_gegl_color_new (&paint_color);
 
               gegl_buffer_set_color (paint_buffer, NULL, color);
diff --git a/app/paint/gimppaintbrush.h b/app/paint/gimppaintbrush.h
index 1e94b8e1ab..0631439826 100644
--- a/app/paint/gimppaintbrush.h
+++ b/app/paint/gimppaintbrush.h
@@ -44,6 +44,16 @@ struct _GimpPaintbrush
 struct _GimpPaintbrushClass
 {
   GimpBrushCoreClass  parent_class;
+
+  /*  virtual functions  */
+  void   (* get_paint_params) (GimpPaintbrush            *paintbrush,
+                               GimpDrawable              *drawable,
+                               GimpPaintOptions          *paint_options,
+                               GimpSymmetry              *sym,
+                               GimpLayerMode             *paint_mode,
+                               GimpPaintApplicationMode  *paint_appl_mode,
+                               const GimpTempBuf        **paint_pixmap,
+                               GimpRGB                   *paint_color);
 };
 
 


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