mirror of https://github.com/GNOME/gimp.git
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.
This commit is contained in:
parent
3b56bd7a9a
commit
aba4eef916
|
@ -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;
|
||||
GimpEraserOptions *options = GIMP_ERASER_OPTIONS (paint_options);
|
||||
GimpContext *context = GIMP_CONTEXT (paint_options);
|
||||
|
||||
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);
|
||||
gimp_context_get_background (context, paint_color);
|
||||
gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (drawable),
|
||||
&background, &background);
|
||||
color = gimp_gegl_color_new (&background, gimp_drawable_get_space (drawable));
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
gimp_drawable_get_space (drawable));
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue