[gimp/wip/alxsa/mypaint-brush-v2: 58/66] paint: Add support for MyPaint Brushes v2
- From: Alx Sa <sawyeralex src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/alxsa/mypaint-brush-v2: 58/66] paint: Add support for MyPaint Brushes v2
- Date: Sun, 16 Oct 2022 17:45:30 +0000 (UTC)
commit b8bb6bba2fad91368794211ad78bde5d68e7864e
Author: Alx Sa <cmyk student gmail com>
Date: Sat Oct 1 14:52:29 2022 +0000
paint: Add support for MyPaint Brushes v2
app/core/gimpmybrush-load.c | 14 +++-
app/core/gimpmybrush-private.h | 3 +
app/core/gimpmybrush.c | 35 +++++++-
app/core/gimpmybrush.h | 3 +
app/paint/gimpmybrushcore.c | 74 +++++++++--------
app/paint/gimpmybrushoptions.c | 53 ++++++++++++-
app/paint/gimpmybrushoptions.h | 3 +
app/paint/gimpmybrushsurface.c | 158 +++++++++++++++++++++++++++++++++++++
app/paint/gimpmybrushsurface.h | 23 ++++--
app/tools/gimpmybrushoptions-gui.c | 5 ++
10 files changed, 324 insertions(+), 47 deletions(-)
---
diff --git a/app/core/gimpmybrush-load.c b/app/core/gimpmybrush-load.c
index 1dbb9f5bd7..eeca69347d 100644
--- a/app/core/gimpmybrush-load.c
+++ b/app/core/gimpmybrush-load.c
@@ -84,7 +84,7 @@ gimp_mybrush_load (GimpContext *context,
return NULL;
}
- mypaint_brush = mypaint_brush_new ();
+ mypaint_brush = mypaint_brush_new_with_buckets (64);
mypaint_brush_from_defaults (mypaint_brush);
if (! mypaint_brush_from_string (mypaint_brush, (const gchar *) buffer))
@@ -139,6 +139,18 @@ gimp_mybrush_load (GimpContext *context,
mypaint_brush_get_base_value (mypaint_brush,
MYPAINT_BRUSH_SETTING_HARDNESS);
+ brush->priv->pigment =
+ mypaint_brush_get_base_value (mypaint_brush,
+ MYPAINT_BRUSH_SETTING_PAINT_MODE);
+
+ brush->priv->posterize =
+ mypaint_brush_get_base_value (mypaint_brush,
+ MYPAINT_BRUSH_SETTING_POSTERIZE);
+
+ brush->priv->posterize_num =
+ mypaint_brush_get_base_value (mypaint_brush,
+ MYPAINT_BRUSH_SETTING_POSTERIZE_NUM);
+
brush->priv->eraser =
mypaint_brush_get_base_value (mypaint_brush,
MYPAINT_BRUSH_SETTING_ERASER) > 0.5f;
diff --git a/app/core/gimpmybrush-private.h b/app/core/gimpmybrush-private.h
index 7966c0b20d..31e0fc6be7 100644
--- a/app/core/gimpmybrush-private.h
+++ b/app/core/gimpmybrush-private.h
@@ -27,6 +27,9 @@ struct _GimpMybrushPrivate
gdouble radius;
gdouble opaque;
gdouble hardness;
+ gdouble pigment;
+ gdouble posterize;
+ gdouble posterize_num;
gdouble offset_by_random;
gboolean eraser;
};
diff --git a/app/core/gimpmybrush.c b/app/core/gimpmybrush.c
index a26c86b227..71af5c9568 100644
--- a/app/core/gimpmybrush.c
+++ b/app/core/gimpmybrush.c
@@ -98,10 +98,13 @@ gimp_mybrush_init (GimpMybrush *brush)
{
brush->priv = gimp_mybrush_get_instance_private (brush);
- brush->priv->radius = 1.0;
- brush->priv->opaque = 1.0;
- brush->priv->hardness = 1.0;
- brush->priv->eraser = FALSE;
+ brush->priv->radius = 1.0;
+ brush->priv->opaque = 1.0;
+ brush->priv->hardness = 1.0;
+ brush->priv->pigment = 0.0;
+ brush->priv->posterize = 1.0;
+ brush->priv->posterize_num = 1.0;
+ brush->priv->eraser = FALSE;
}
static void
@@ -264,6 +267,30 @@ gimp_mybrush_get_hardness (GimpMybrush *brush)
return brush->priv->hardness;
}
+gdouble
+gimp_mybrush_get_pigment (GimpMybrush *brush)
+{
+ g_return_val_if_fail (GIMP_IS_MYBRUSH (brush), 0.0);
+
+ return brush->priv->pigment;
+}
+
+gdouble
+gimp_mybrush_get_posterize (GimpMybrush *brush)
+{
+ g_return_val_if_fail (GIMP_IS_MYBRUSH (brush), 1.0);
+
+ return brush->priv->posterize;
+}
+
+gdouble
+gimp_mybrush_get_posterize_num (GimpMybrush *brush)
+{
+ g_return_val_if_fail (GIMP_IS_MYBRUSH (brush), 1.0);
+
+ return brush->priv->posterize_num;
+}
+
gdouble
gimp_mybrush_get_offset_by_random (GimpMybrush *brush)
{
diff --git a/app/core/gimpmybrush.h b/app/core/gimpmybrush.h
index 2dad734fe1..4bf8be8912 100644
--- a/app/core/gimpmybrush.h
+++ b/app/core/gimpmybrush.h
@@ -59,6 +59,9 @@ const gchar * gimp_mybrush_get_brush_json (GimpMybrush *brush);
gdouble gimp_mybrush_get_radius (GimpMybrush *brush);
gdouble gimp_mybrush_get_opaque (GimpMybrush *brush);
gdouble gimp_mybrush_get_hardness (GimpMybrush *brush);
+gdouble gimp_mybrush_get_pigment (GimpMybrush *brush);
+gdouble gimp_mybrush_get_posterize (GimpMybrush *brush);
+gdouble gimp_mybrush_get_posterize_num (GimpMybrush *brush);
gdouble gimp_mybrush_get_offset_by_random (GimpMybrush *brush);
gboolean gimp_mybrush_get_is_eraser (GimpMybrush *brush);
diff --git a/app/paint/gimpmybrushcore.c b/app/paint/gimpmybrushcore.c
index 108997f1ca..c8d6c618ef 100644
--- a/app/paint/gimpmybrushcore.c
+++ b/app/paint/gimpmybrushcore.c
@@ -49,11 +49,11 @@
struct _GimpMybrushCorePrivate
{
- GimpMybrush *mybrush;
- GimpMybrushSurface *surface;
- GList *brushes;
- gboolean synthetic;
- gint64 last_time;
+ GimpMybrush *mybrush;
+ GimpMybrushSurface2 *surface;
+ GList *brushes;
+ gboolean synthetic;
+ gint64 last_time;
};
@@ -217,11 +217,11 @@ gimp_mybrush_core_paint (GimpPaintCore *paint_core,
gimp_item_get_offset (drawables->data, &offset_x, &offset_y);
mybrush->private->surface =
- gimp_mypaint_surface_new (gimp_drawable_get_buffer (drawables->data),
- gimp_drawable_get_active_mask (drawables->data),
- paint_core->mask_buffer,
- -offset_x, -offset_y,
- GIMP_MYBRUSH_OPTIONS (paint_options));
+ gimp_mypaint_surface2_new (gimp_drawable_get_buffer (drawables->data),
+ gimp_drawable_get_active_mask (drawables->data),
+ paint_core->mask_buffer,
+ -offset_x, -offset_y,
+ GIMP_MYBRUSH_OPTIONS (paint_options));
gimp_mybrush_core_create_brushes (mybrush, drawables->data, paint_options, sym);
@@ -236,7 +236,7 @@ gimp_mybrush_core_paint (GimpPaintCore *paint_core,
case GIMP_PAINT_STATE_FINISH:
gimp_symmetry_set_stateful (sym, FALSE);
- mypaint_surface_unref ((MyPaintSurface *) mybrush->private->surface);
+ /*mypaint_surface_unref ((MyPaintSurface *) mybrush->private->surface);*/
mybrush->private->surface = NULL;
g_list_free_full (mybrush->private->brushes,
@@ -272,7 +272,7 @@ gimp_mybrush_core_motion (GimpPaintCore *paint_core,
gimp_mybrush_core_create_brushes (mybrush, drawable, paint_options, sym);
}
- mypaint_surface_begin_atomic ((MyPaintSurface *) mybrush->private->surface);
+ /*mypaint_surface_begin_atomic ((MyPaintSurface2 *) mybrush->private->surface);*/
if (mybrush->private->last_time < 0)
{
@@ -284,14 +284,15 @@ gimp_mybrush_core_motion (GimpPaintCore *paint_core,
MyPaintBrush *brush = iter->data;
GimpCoords coords = *(gimp_symmetry_get_coords (sym, i));
- mypaint_brush_stroke_to (brush,
- (MyPaintSurface *) mybrush->private->surface,
- coords.x - off_x,
- coords.y - off_y,
- 0.0f,
- coords.xtilt,
- coords.ytilt,
- 1.0f /* Pretend the cursor hasn't moved in a while */);
+ mypaint_brush_stroke_to_2 (brush,
+ (MyPaintSurface2 *) mybrush->private->surface,
+ coords.x - off_x,
+ coords.y - off_y,
+ 0.0f,
+ coords.xtilt,
+ coords.ytilt,
+ 1.0f, /* Pretend the cursor hasn't moved in a while */
+ 1.0f, 1.0f, 1.0f);
}
dt = 0.015;
@@ -316,20 +317,21 @@ gimp_mybrush_core_motion (GimpPaintCore *paint_core,
GimpCoords coords = *(gimp_symmetry_get_coords (sym, i));
gdouble pressure = coords.pressure;
- mypaint_brush_stroke_to (brush,
- (MyPaintSurface *) mybrush->private->surface,
- coords.x - off_x,
- coords.y - off_y,
- pressure,
- coords.xtilt,
- coords.ytilt,
- dt);
+ mypaint_brush_stroke_to_2 (brush,
+ (MyPaintSurface2 *) mybrush->private->surface,
+ coords.x - off_x,
+ coords.y - off_y,
+ pressure,
+ coords.xtilt,
+ coords.ytilt,
+ dt,
+ 1.0f, 1.0f, 1.0f);
}
mybrush->private->last_time = time;
- mypaint_surface_end_atomic ((MyPaintSurface *) mybrush->private->surface,
- &rect);
+ /*mypaint_surface_end_atomic ((MyPaintSurface2 *) mybrush->private->surface,
+ &rect);*/
if (rect.width > 0 && rect.height > 0)
{
@@ -375,7 +377,7 @@ gimp_mybrush_core_create_brushes (GimpMybrushCore *mybrush,
for (i = 0; i < n_strokes; i++)
{
- MyPaintBrush *brush = mypaint_brush_new ();
+ MyPaintBrush *brush = mypaint_brush_new_with_buckets (64);
const gchar *brush_data;
mypaint_brush_from_defaults (brush);
@@ -413,6 +415,16 @@ gimp_mybrush_core_create_brushes (GimpMybrushCore *mybrush,
gimp_drawable_has_alpha (drawable)) ?
1.0f : 0.0f);
+ mypaint_brush_set_base_value (brush,
+ MYPAINT_BRUSH_SETTING_PAINT_MODE,
+ options->pigment);
+ mypaint_brush_set_base_value (brush,
+ MYPAINT_BRUSH_SETTING_POSTERIZE,
+ options->posterize);
+ mypaint_brush_set_base_value (brush,
+ MYPAINT_BRUSH_SETTING_POSTERIZE_NUM,
+ options->posterize_num);
+
mypaint_brush_new_stroke (brush);
mybrush->private->brushes = g_list_prepend (mybrush->private->brushes,
diff --git a/app/paint/gimpmybrushoptions.c b/app/paint/gimpmybrushoptions.c
index 4d515491a8..38dc73a76d 100644
--- a/app/paint/gimpmybrushoptions.c
+++ b/app/paint/gimpmybrushoptions.c
@@ -41,6 +41,9 @@ enum
PROP_RADIUS,
PROP_OPAQUE,
PROP_HARDNESS,
+ PROP_PIGMENT,
+ PROP_POSTERIZE,
+ PROP_POSTERIZE_NUM,
PROP_ERASER,
PROP_NO_ERASING
};
@@ -103,6 +106,27 @@ gimp_mybrush_options_class_init (GimpMybrushOptionsClass *klass)
0.0, 1.0, 1.0,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_PIGMENT,
+ "pigment",
+ _("Pigment"),
+ NULL,
+ -1.0, 1.0, 0.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_POSTERIZE,
+ "posterize",
+ _("Posterize"),
+ NULL,
+ -1.0, 1.0, 0.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_POSTERIZE_NUM,
+ "posterizenum",
+ _("Posterize Number"),
+ NULL,
+ -1.0, 1.0, 0.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ERASER,
"eraser",
_("Erase with this brush"),
@@ -150,6 +174,15 @@ gimp_mybrush_options_set_property (GObject *object,
case PROP_OPAQUE:
options->opaque = g_value_get_double (value);
break;
+ case PROP_PIGMENT:
+ options->pigment = g_value_get_double (value);
+ break;
+ case PROP_POSTERIZE:
+ options->posterize = g_value_get_double (value);
+ break;
+ case PROP_POSTERIZE_NUM:
+ options->posterize_num = g_value_get_double (value);
+ break;
case PROP_ERASER:
options->eraser = g_value_get_boolean (value);
break;
@@ -182,6 +215,15 @@ gimp_mybrush_options_get_property (GObject *object,
case PROP_HARDNESS:
g_value_set_double (value, options->hardness);
break;
+ case PROP_PIGMENT:
+ g_value_set_double (value, options->pigment);
+ break;
+ case PROP_POSTERIZE:
+ g_value_set_double (value, options->posterize);
+ break;
+ case PROP_POSTERIZE_NUM:
+ g_value_set_double (value, options->posterize_num);
+ break;
case PROP_ERASER:
g_value_set_boolean (value, options->eraser);
break;
@@ -201,10 +243,13 @@ gimp_mybrush_options_mybrush_changed (GimpContext *context,
{
if (brush)
g_object_set (context,
- "radius", gimp_mybrush_get_radius (brush),
- "opaque", gimp_mybrush_get_opaque (brush),
- "hardness", gimp_mybrush_get_hardness (brush),
- "eraser", gimp_mybrush_get_is_eraser (brush),
+ "radius", gimp_mybrush_get_radius (brush),
+ "opaque", gimp_mybrush_get_opaque (brush),
+ "hardness", gimp_mybrush_get_hardness (brush),
+ "pigment", gimp_mybrush_get_pigment (brush),
+ "posterize", gimp_mybrush_get_posterize (brush),
+ "posterizenum", gimp_mybrush_get_posterize_num (brush),
+ "eraser", gimp_mybrush_get_is_eraser (brush),
NULL);
}
diff --git a/app/paint/gimpmybrushoptions.h b/app/paint/gimpmybrushoptions.h
index b1b5cd55a3..166c5f9176 100644
--- a/app/paint/gimpmybrushoptions.h
+++ b/app/paint/gimpmybrushoptions.h
@@ -39,6 +39,9 @@ struct _GimpMybrushOptions
gdouble radius;
gdouble opaque;
gdouble hardness;
+ gdouble pigment;
+ gdouble posterize;
+ gdouble posterize_num;
gboolean eraser;
gboolean no_erasing;
};
diff --git a/app/paint/gimpmybrushsurface.c b/app/paint/gimpmybrushsurface.c
index 436c77ced2..5e4ae76195 100644
--- a/app/paint/gimpmybrushsurface.c
+++ b/app/paint/gimpmybrushsurface.c
@@ -44,6 +44,18 @@ struct _GimpMybrushSurface
GimpMybrushOptions *options;
};
+struct _GimpMybrushSurface2
+{
+ MyPaintSurface2 surface;
+ GeglBuffer *buffer;
+ GeglBuffer *paint_mask;
+ gint paint_mask_x;
+ gint paint_mask_y;
+ GeglRectangle dirty;
+ GimpComponentMask component_mask;
+ GimpMybrushOptions *options;
+};
+
/* --- Taken from mypaint-tiled-surface.c --- */
static inline float
calculate_rr (int xp,
@@ -559,3 +571,149 @@ gimp_mypaint_surface_new (GeglBuffer *buffer,
return surface;
}
+
+/* MyPaintSurface2 implementation */
+static int
+gimp_mypaint_surface_draw_dab_2 (MyPaintSurface2 *base_surface,
+ float x,
+ float y,
+ float radius,
+ float color_r,
+ float color_g,
+ float color_b,
+ float opaque,
+ float hardness,
+ float color_a,
+ float aspect_ratio,
+ float angle,
+ float lock_alpha,
+ float colorize,
+ float posterize,
+ float posterize_num,
+ float paint)
+{
+ /* Placeholder - eventually implement here */
+ return 1;
+}
+
+
+static int
+gimp_mypaint_surface_draw_dab_wrapper (MyPaintSurface *surface,
+ float x,
+ float y,
+ float radius,
+ float color_r,
+ float color_g,
+ float color_b,
+ float opaque,
+ float hardness,
+ float color_a,
+ float aspect_ratio,
+ float angle,
+ float lock_alpha,
+ float colorize)
+{
+ const gfloat posterize = 0.0;
+ const gfloat posterize_num = 1.0;
+ const gfloat pigment = 0.0;
+
+ return gimp_mypaint_surface_draw_dab_2 ((MyPaintSurface2 *) surface, x, y, radius,
+ color_r, color_g, color_b, opaque, hardness,
+ color_a, aspect_ratio, angle, lock_alpha,
+ colorize, posterize, posterize_num,
+ pigment);
+}
+
+static void
+gimp_mypaint_surface_get_color_2 (MyPaintSurface2 *base_surface,
+ float x,
+ float y,
+ float radius,
+ float *color_r,
+ float *color_g,
+ float *color_b,
+ float *color_a,
+ float paint)
+{
+ /* Placeholder - eventually implement here */
+
+}
+
+static void
+gimp_mypaint_surface_get_color_wrapper (MyPaintSurface *surface,
+ float x,
+ float y,
+ float radius,
+ float *color_r,
+ float *color_g,
+ float *color_b,
+ float *color_a)
+{
+ return gimp_mypaint_surface_get_color_2 ((MyPaintSurface2 *) surface, x, y, radius,
+ color_r, color_g, color_b, color_a,
+ -1.0);
+}
+
+
+static void
+gimp_mypaint_surface_end_atomic_2 (MyPaintSurface2 *base_surface,
+ MyPaintRectangles *roi)
+{
+ GimpMybrushSurface2 *surface = (GimpMybrushSurface2 *) base_surface;
+
+ if (roi)
+ {
+ const gint roi_rects = roi->num_rectangles;
+
+ for (gint i = 0; i < roi_rects; i++)
+ {
+ roi->rectangles[i].x = 0;
+ roi->rectangles[i].y = 0;
+ roi->rectangles[i].width = 0;
+ roi->rectangles[i].height = 0;
+ surface->dirty = *GEGL_RECTANGLE (0, 0, 0, 0);
+ }
+ }
+}
+
+static void
+gimp_mypaint_surface_end_atomic_wrapper (MyPaintSurface *surface,
+ MyPaintRectangle *roi)
+{
+ MyPaintRectangles rois = {1, roi};
+ gimp_mypaint_surface_end_atomic_2 ((MyPaintSurface2 *) surface, &rois);
+}
+
+GimpMybrushSurface2 *
+gimp_mypaint_surface2_new (GeglBuffer *buffer,
+ GimpComponentMask component_mask,
+ GeglBuffer *paint_mask,
+ gint paint_mask_x,
+ gint paint_mask_y,
+ GimpMybrushOptions *options)
+{
+ GimpMybrushSurface2 *surface = g_malloc0 (sizeof (GimpMybrushSurface2));
+
+ mypaint_surface_init (&surface->surface.parent);
+
+ surface->surface.get_color_pigment = gimp_mypaint_surface_get_color_2;
+ surface->surface.draw_dab_pigment = gimp_mypaint_surface_draw_dab_2;
+ surface->surface.parent.begin_atomic = gimp_mypaint_surface_begin_atomic;
+ surface->surface.end_atomic_multi = gimp_mypaint_surface_end_atomic_2;
+
+ surface->surface.parent.draw_dab = gimp_mypaint_surface_draw_dab_wrapper;
+ surface->surface.parent.get_color = gimp_mypaint_surface_get_color_wrapper;
+ surface->surface.parent.end_atomic = gimp_mypaint_surface_end_atomic_wrapper;
+
+ surface->component_mask = component_mask;
+ surface->options = options;
+ surface->buffer = g_object_ref (buffer);
+ if (paint_mask)
+ surface->paint_mask = g_object_ref (paint_mask);
+
+ surface->paint_mask_x = paint_mask_x;
+ surface->paint_mask_y = paint_mask_y;
+ surface->dirty = *GEGL_RECTANGLE (0, 0, 0, 0);
+
+ return surface;
+}
\ No newline at end of file
diff --git a/app/paint/gimpmybrushsurface.h b/app/paint/gimpmybrushsurface.h
index 71bc0baa22..287df2c20f 100644
--- a/app/paint/gimpmybrushsurface.h
+++ b/app/paint/gimpmybrushsurface.h
@@ -19,15 +19,24 @@
#define __GIMP_MYBRUSH_SURFACE_H__
-typedef struct _GimpMybrushSurface GimpMybrushSurface;
+typedef struct _GimpMybrushSurface GimpMybrushSurface;
+typedef struct _GimpMybrushSurface2 GimpMybrushSurface2;
GimpMybrushSurface *
-gimp_mypaint_surface_new (GeglBuffer *buffer,
- GimpComponentMask component_mask,
- GeglBuffer *paint_mask,
- gint paint_mask_x,
- gint paint_mask_y,
- GimpMybrushOptions *options);
+gimp_mypaint_surface_new (GeglBuffer *buffer,
+ GimpComponentMask component_mask,
+ GeglBuffer *paint_mask,
+ gint paint_mask_x,
+ gint paint_mask_y,
+ GimpMybrushOptions *options);
+
+GimpMybrushSurface2 *
+gimp_mypaint_surface2_new (GeglBuffer *buffer,
+ GimpComponentMask component_mask,
+ GeglBuffer *paint_mask,
+ gint paint_mask_x,
+ gint paint_mask_y,
+ GimpMybrushOptions *options);
#endif /* __GIMP_MYBRUSH_SURFACE_H__ */
diff --git a/app/tools/gimpmybrushoptions-gui.c b/app/tools/gimpmybrushoptions-gui.c
index a2f927f920..0bfc418e3c 100644
--- a/app/tools/gimpmybrushoptions-gui.c
+++ b/app/tools/gimpmybrushoptions-gui.c
@@ -78,5 +78,10 @@ gimp_mybrush_options_gui (GimpToolOptions *tool_options)
0.1, 1.0, 2);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
+ /* pigment */
+ scale = gimp_prop_spin_scale_new (config, "pigment",
+ 0.1, 0.0, 2);
+ gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
+
return vbox;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]