1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-05 21:02:42 +02:00

core, paint, tools: Port to MyPaint Brushes2

This patch ports our MyPaint code to use the
MyPaintSurface2 API, allowing us to support
version 2 MyPaint Brushes correctly.
The API update lets us take into account
the zoom factor and rotation of the canvas
when drawing. It also adds a "Gain" option
to the GUI in order to control the strength
of the input's pressure (tablet or mouse).
As a caveat, this patch does not yet
implement spectral/pigment blending.
This commit is contained in:
Alx Sa
2025-07-09 22:14:42 +00:00
parent 4dd729ba42
commit ea8b9dc13c
17 changed files with 422 additions and 111 deletions

View File

@@ -311,7 +311,7 @@ gimp_core_config_class_init (GimpCoreConfigClass *klass)
#ifdef ENABLE_RELOCATABLE_RESOURCES
mypaint_brushes = g_build_filename ("${gimp_installation_dir}",
"share", "mypaint-data",
"1.0", "brushes", NULL);
"2.0", "brushes", NULL);
#else
mypaint_brushes = g_strdup (MYPAINT_BRUSHES_DIR);
#endif

View File

@@ -69,7 +69,7 @@ gimp_mybrush_load (GimpContext *context,
G_FILE_ATTRIBUTE_STANDARD_SIZE);
g_object_unref (info);
if (size > 32768)
if (size > G_MAXSHORT)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("MyPaint brush file is unreasonably large, skipping."));
@@ -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))
@@ -147,6 +147,23 @@ gimp_mybrush_load (GimpContext *context,
mypaint_brush_get_base_value (mypaint_brush,
MYPAINT_BRUSH_SETTING_OFFSET_BY_RANDOM);
brush->priv->gain =
mypaint_brush_get_base_value (mypaint_brush,
MYPAINT_BRUSH_SETTING_PRESSURE_GAIN_LOG);
/* Version 2 MyPaint Brush options */
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);
mypaint_brush_unref (mypaint_brush);
return g_list_prepend (NULL, brush);

View File

@@ -27,6 +27,10 @@ struct _GimpMybrushPrivate
gdouble radius;
gdouble opaque;
gdouble hardness;
gdouble gain;
gdouble pigment;
gdouble posterize;
gdouble posterize_num;
gdouble offset_by_random;
gboolean eraser;
};

View File

@@ -98,10 +98,14 @@ 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->gain = 0.0;
brush->priv->pigment = 0.0;
brush->priv->posterize = 0.0;
brush->priv->posterize_num = 1.0;
brush->priv->eraser = FALSE;
}
static void
@@ -262,6 +266,39 @@ gimp_mybrush_get_hardness (GimpMybrush *brush)
return brush->priv->hardness;
}
gdouble
gimp_mybrush_get_gain (GimpMybrush *brush)
{
g_return_val_if_fail (GIMP_IS_MYBRUSH (brush), 0.0);
return brush->priv->gain;
}
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), 0.0);
return brush->priv->posterize;
}
gdouble
gimp_mybrush_get_posterize_num (GimpMybrush *brush)
{
g_return_val_if_fail (GIMP_IS_MYBRUSH (brush), 0.05);
return brush->priv->posterize_num;
}
gdouble
gimp_mybrush_get_offset_by_random (GimpMybrush *brush)
{

View File

@@ -59,6 +59,10 @@ 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_gain (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);

View File

@@ -80,7 +80,10 @@ static void gimp_mybrush_core_motion (GimpPaintCore *paint_core
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpSymmetry *sym,
guint32 time);
guint32 time,
gfloat view_zoom,
gfloat view_rotation,
gfloat barrel_rotation);
static void gimp_mybrush_core_create_brushes (GimpMybrushCore *mybrush,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
@@ -200,10 +203,11 @@ gimp_mybrush_core_paint (GimpPaintCore *paint_core,
GimpPaintState paint_state,
guint32 time)
{
GimpMybrushCore *mybrush = GIMP_MYBRUSH_CORE (paint_core);
GimpContext *context = GIMP_CONTEXT (paint_options);
gint offset_x;
gint offset_y;
GimpMybrushCore *mybrush = GIMP_MYBRUSH_CORE (paint_core);
GimpMybrushOptions *mybrush_options = GIMP_MYBRUSH_OPTIONS (paint_options);
GimpContext *context = GIMP_CONTEXT (paint_options);
gint offset_x;
gint offset_y;
g_return_if_fail (g_list_length (drawables) == 1);
@@ -229,7 +233,8 @@ gimp_mybrush_core_paint (GimpPaintCore *paint_core,
case GIMP_PAINT_STATE_MOTION:
gimp_mybrush_core_motion (paint_core, drawables->data, paint_options,
sym, time);
sym, time, mybrush_options->view_zoom,
mybrush_options->view_rotation, 1.0f);
break;
case GIMP_PAINT_STATE_FINISH:
@@ -249,10 +254,14 @@ gimp_mybrush_core_motion (GimpPaintCore *paint_core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpSymmetry *sym,
guint32 time)
guint32 time,
gfloat view_zoom,
gfloat view_rotation,
gfloat barrel_rotation)
{
GimpMybrushCore *mybrush = GIMP_MYBRUSH_CORE (paint_core);
MyPaintRectangle rect;
MyPaintRectangles rects = {1, &rect};
GimpCoords origin;
GList *iter;
gdouble dt = 0.0;
@@ -288,14 +297,17 @@ 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,
coords.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,
coords.y,
0.0f,
coords.xtilt,
coords.ytilt,
1.0f, /* Pretend the cursor hasn't moved in a while */
view_zoom,
view_rotation,
barrel_rotation);
}
dt = 0.015;
@@ -356,29 +368,36 @@ gimp_mybrush_core_motion (GimpPaintCore *paint_core,
gimp_symmetry_set_origin (sym, drawable, &origin);
}
mypaint_brush_stroke_to (brush,
(MyPaintSurface *) mybrush->private->surface,
coords.x,
coords.y,
pressure,
coords.xtilt,
coords.ytilt,
dt);
mypaint_brush_stroke_to_2 (brush,
(MyPaintSurface2 *) mybrush->private->surface,
coords.x,
coords.y,
pressure,
coords.xtilt,
coords.ytilt,
dt,
view_zoom,
view_rotation,
barrel_rotation);
}
mybrush->private->last_time = time;
mypaint_surface_end_atomic ((MyPaintSurface *) mybrush->private->surface,
&rect);
mypaint_surface2_end_atomic ((MyPaintSurface2 *) mybrush->private->surface,
&rects);
if (rect.width > 0 && rect.height > 0)
if (rects.rectangles[0].width > 0 && rects.rectangles[0].height > 0)
{
paint_core->x1 = MIN (paint_core->x1, rect.x);
paint_core->y1 = MIN (paint_core->y1, rect.y);
paint_core->x2 = MAX (paint_core->x2, rect.x + rect.width);
paint_core->y2 = MAX (paint_core->y2, rect.y + rect.height);
paint_core->x1 = MIN (paint_core->x1, rects.rectangles[0].x);
paint_core->y1 = MIN (paint_core->y1, rects.rectangles[0].y);
paint_core->x2 = MAX (paint_core->x2,
rects.rectangles[0].x + rects.rectangles[0].width);
paint_core->y2 = MAX (paint_core->y2,
rects.rectangles[0].y + rects.rectangles[0].height);
gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height);
gimp_drawable_update (drawable, rects.rectangles[0].x,
rects.rectangles[0].y, rects.rectangles[0].width,
rects.rectangles[0].height);
}
}
@@ -413,7 +432,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);
@@ -445,6 +464,18 @@ gimp_mybrush_core_create_brushes (GimpMybrushCore *mybrush,
mypaint_brush_set_base_value (brush,
MYPAINT_BRUSH_SETTING_HARDNESS,
options->hardness);
mypaint_brush_set_base_value (brush,
MYPAINT_BRUSH_SETTING_PRESSURE_GAIN_LOG,
options->gain);
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_set_base_value (brush,
MYPAINT_BRUSH_SETTING_ERASER,
(options->eraser &&

View File

@@ -38,9 +38,15 @@
enum
{
PROP_0,
PROP_VIEW_ZOOM,
PROP_VIEW_ROTATION,
PROP_RADIUS,
PROP_OPAQUE,
PROP_HARDNESS,
PROP_GAIN,
PROP_PIGMENT,
PROP_POSTERIZE,
PROP_POSTERIZE_NUM,
PROP_ERASER,
PROP_NO_ERASING
};
@@ -82,6 +88,20 @@ gimp_mybrush_options_class_init (GimpMybrushOptionsClass *klass)
context_class->mybrush_changed = gimp_mybrush_options_mybrush_changed;
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_RADIUS,
"viewzoom",
_("View Zoom"),
NULL,
0.0001, G_MAXFLOAT, 1.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_RADIUS,
"viewrotation",
_("View Rotation"),
NULL,
-360.0, 360.0, 0.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_RADIUS,
"radius",
_("Radius"),
@@ -103,6 +123,31 @@ gimp_mybrush_options_class_init (GimpMybrushOptionsClass *klass)
0.0, 1.0, 1.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_GAIN,
"gain",
_("Gain"),
_("Adjust strength of input pressue"),
-1.8, 1.8, 0.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_PIGMENT,
"pigment",
NULL, NULL,
0.0, 1.0, 0.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_POSTERIZE,
"posterize",
NULL, NULL,
0.0, 1.0, 0.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_POSTERIZE_NUM,
"posterizenum",
NULL, NULL,
0.0, 1.28, 1.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ERASER,
"eraser",
_("Erase with this brush"),
@@ -141,14 +186,33 @@ gimp_mybrush_options_set_property (GObject *object,
switch (property_id)
{
case PROP_VIEW_ZOOM:
options->view_zoom = g_value_get_double (value) > 0.0f ?
g_value_get_double (value) : 0.0001f;
break;
case PROP_VIEW_ROTATION:
options->view_rotation = CLAMP (g_value_get_double (value), 0.0f, 360.0f);
break;
case PROP_RADIUS:
options->radius = g_value_get_double (value);
break;
case PROP_OPAQUE:
options->opaque = g_value_get_double (value);
break;
case PROP_HARDNESS:
options->hardness = g_value_get_double (value);
break;
case PROP_OPAQUE:
options->opaque = g_value_get_double (value);
case PROP_GAIN:
options->gain = 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);
@@ -173,6 +237,12 @@ gimp_mybrush_options_get_property (GObject *object,
switch (property_id)
{
case PROP_VIEW_ZOOM:
g_value_set_double (value, options->view_zoom);
break;
case PROP_VIEW_ROTATION:
g_value_set_double (value, options->view_rotation);
break;
case PROP_RADIUS:
g_value_set_double (value, options->radius);
break;
@@ -182,6 +252,18 @@ gimp_mybrush_options_get_property (GObject *object,
case PROP_HARDNESS:
g_value_set_double (value, options->hardness);
break;
case PROP_GAIN:
g_value_set_double (value, options->gain);
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 +283,16 @@ 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),
"viewzoom", 1.0f,
"viewrotation", 0.0f,
"radius", gimp_mybrush_get_radius (brush),
"opaque", gimp_mybrush_get_opaque (brush),
"hardness", gimp_mybrush_get_hardness (brush),
"gain", gimp_mybrush_get_gain (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);
}

View File

@@ -36,9 +36,16 @@ struct _GimpMybrushOptions
{
GimpPaintOptions parent_instance;
gdouble view_zoom;
gdouble view_rotation;
gdouble radius;
gdouble opaque;
gdouble hardness;
gdouble gain;
gdouble pigment;
gdouble posterize;
gdouble posterize_num;
gboolean eraser;
gboolean no_erasing;
};

View File

@@ -34,7 +34,7 @@
struct _GimpMybrushSurface
{
MyPaintSurface surface;
MyPaintSurface2 surface;
GeglBuffer *buffer;
GeglBuffer *paint_mask;
gint paint_mask_x;
@@ -232,17 +232,18 @@ calculate_dab_roi (float x,
}
static void
gimp_mypaint_surface_get_color (MyPaintSurface *base_surface,
float x,
float y,
float radius,
float *color_r,
float *color_g,
float *color_b,
float *color_a)
gimp_mypaint_surface_get_color_2 (MyPaintSurface2 *base_surface,
gfloat x,
gfloat y,
gfloat radius,
gfloat *color_r,
gfloat *color_g,
gfloat *color_b,
gfloat *color_a,
gfloat paint)
{
GimpMybrushSurface *surface = (GimpMybrushSurface *)base_surface;
GeglRectangle dabRect;
GeglRectangle dabRect;
if (radius < 1.0f)
radius = 1.0f;
@@ -334,24 +335,41 @@ gimp_mypaint_surface_get_color (MyPaintSurface *base_surface,
*color_a = CLAMP(sum_a, 0.0f, 1.0f);
}
}
}
static int
gimp_mypaint_surface_draw_dab (MyPaintSurface *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)
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 gint
gimp_mypaint_surface_draw_dab_2 (MyPaintSurface2 *base_surface,
gfloat x,
gfloat y,
gfloat radius,
gfloat color_r,
gfloat color_g,
gfloat color_b,
gfloat opaque,
gfloat hardness,
gfloat color_a,
gfloat aspect_ratio,
gfloat angle,
gfloat lock_alpha,
gfloat colorize,
gfloat posterize,
gfloat posterize_num,
gfloat paint)
{
GimpMybrushSurface *surface = (GimpMybrushSurface *)base_surface;
GeglBufferIterator *iter;
@@ -370,6 +388,10 @@ gimp_mypaint_surface_draw_dab (MyPaintSurface *base_surface,
float segment2_slope;
float r_aa_start;
posterize = CLAMP (posterize, 0.0f, 1.0f);
posterize_num = CLAMP (ROUND (posterize_num * 100.0), 1, 128);
paint = CLAMP (paint, 0.0f, 1.0f);
hardness = CLAMP (hardness, 0.0f, 1.0f);
segment1_slope = -(1.0f / hardness - 1.0f);
segment2_slope = -hardness / (1.0f - hardness);
@@ -379,7 +401,7 @@ gimp_mypaint_surface_draw_dab (MyPaintSurface *base_surface,
r_aa_start = MAX (r_aa_start, 0);
r_aa_start = (r_aa_start * r_aa_start) / aspect_ratio;
normal_mode = opaque * (1.0f - colorize);
normal_mode = opaque * (1.0f - colorize) * (1.0f - posterize);
colorize = opaque * colorize;
/* FIXME: This should use the real matrix values to trim aspect_ratio dabs */
@@ -481,6 +503,26 @@ gimp_mypaint_surface_draw_dab (MyPaintSurface *base_surface,
}
}
if (posterize > 0.0f && base_alpha > 0.0f)
{
alpha = base_alpha * posterize;
a = alpha + dst_alpha - alpha * dst_alpha;
if (a > 0.0f)
{
gfloat post_pixel[3];
gfloat src_term = alpha / a;
gfloat dst_term = 1.0f - src_term;
post_pixel[0] = ROUND (r * posterize_num) / posterize_num;
post_pixel[1] = ROUND (g * posterize_num) / posterize_num;
post_pixel[2] = ROUND (b * posterize_num) / posterize_num;
r = post_pixel[0] * src_term + r * dst_term;
g = post_pixel[1] * src_term + g * dst_term;
b = post_pixel[2] * src_term + b * dst_term;
}
}
if (surface->options->no_erasing)
a = MAX (a, pixel[ALPHA]);
@@ -513,6 +555,33 @@ gimp_mypaint_surface_draw_dab (MyPaintSurface *base_surface,
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_begin_atomic (MyPaintSurface *base_surface)
{
@@ -520,22 +589,39 @@ gimp_mypaint_surface_begin_atomic (MyPaintSurface *base_surface)
}
static void
gimp_mypaint_surface_end_atomic (MyPaintSurface *base_surface,
MyPaintRectangle *roi)
gimp_mypaint_surface_end_atomic_2 (MyPaintSurface2 *base_surface,
MyPaintRectangles *rois)
{
GimpMybrushSurface *surface = (GimpMybrushSurface *)base_surface;
roi->x = surface->dirty.x;
roi->y = surface->dirty.y;
roi->width = surface->dirty.width;
roi->height = surface->dirty.height;
surface->dirty = *GEGL_RECTANGLE (0, 0, 0, 0);
if (rois)
{
const gint roi_rects = rois->num_rectangles;
for (gint i = 0; i < roi_rects; i++)
{
rois->rectangles[i].x = surface->dirty.x;
rois->rectangles[i].y = surface->dirty.y;
rois->rectangles[i].width = surface->dirty.width;
rois->rectangles[i].height = surface->dirty.height;
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);
}
static void
gimp_mypaint_surface_destroy (MyPaintSurface *base_surface)
{
GimpMybrushSurface *surface = (GimpMybrushSurface *)base_surface;
GimpMybrushSurface *surface = (GimpMybrushSurface *) base_surface;
g_clear_object (&surface->buffer);
g_clear_object (&surface->paint_mask);
@@ -551,26 +637,34 @@ gimp_mypaint_surface_new (GeglBuffer *buffer,
GimpMybrushOptions *options)
{
GimpMybrushSurface *surface = g_malloc0 (sizeof (GimpMybrushSurface));
MyPaintSurface2 *s;
mypaint_surface_init ((MyPaintSurface *)surface);
mypaint_surface_init (&surface->surface.parent);
s = &surface->surface;
surface->surface.get_color = gimp_mypaint_surface_get_color;
surface->surface.draw_dab = gimp_mypaint_surface_draw_dab;
surface->surface.begin_atomic = gimp_mypaint_surface_begin_atomic;
surface->surface.end_atomic = gimp_mypaint_surface_end_atomic;
surface->surface.destroy = gimp_mypaint_surface_destroy;
surface->component_mask = component_mask;
surface->options = options;
surface->buffer = g_object_ref (buffer);
s->get_color_pigment = gimp_mypaint_surface_get_color_2;
s->draw_dab_pigment = gimp_mypaint_surface_draw_dab_2;
s->parent.begin_atomic = gimp_mypaint_surface_begin_atomic;
s->end_atomic_multi = gimp_mypaint_surface_end_atomic_2;
s->parent.draw_dab = gimp_mypaint_surface_draw_dab_wrapper;
s->parent.get_color = gimp_mypaint_surface_get_color_wrapper;
s->parent.end_atomic = gimp_mypaint_surface_end_atomic_wrapper;
s->parent.destroy = gimp_mypaint_surface_destroy;
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 = 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);
surface->paint_mask_x = paint_mask_x;
surface->paint_mask_y = paint_mask_y;
surface->dirty = *GEGL_RECTANGLE (0, 0, 0, 0);
surface->off_x = 0;
surface->off_y = 0;
surface->off_x = 0;
surface->off_y = 0;
return surface;
}

View File

@@ -80,6 +80,11 @@ gimp_mybrush_options_gui (GimpToolOptions *tool_options)
0.1, 1.0, 2);
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
/* pressure gain */
scale = gimp_prop_spin_scale_new (config, "gain",
0.1, 0.0, 2);
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
/* erase mode */
scale = gimp_prop_check_button_new (config, "eraser", NULL);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);

View File

@@ -46,7 +46,10 @@ G_DEFINE_TYPE (GimpMybrushTool, gimp_mybrush_tool, GIMP_TYPE_PAINT_TOOL)
#define parent_class gimp_mybrush_tool_parent_class
static void gimp_mybrush_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display);
static void gimp_mybrush_tool_options_notify (GimpTool *tool,
GimpToolOptions *options,
const GParamSpec *pspec);
@@ -86,6 +89,7 @@ gimp_mybrush_tool_class_init (GimpMybrushToolClass *klass)
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
GimpPaintToolClass *paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
tool_class->cursor_update = gimp_mybrush_tool_cursor_update;
tool_class->options_notify = gimp_mybrush_tool_options_notify;
paint_tool_class->get_outline = gimp_mybrush_tool_get_outline;
@@ -108,6 +112,23 @@ gimp_mybrush_tool_init (GimpMybrushTool *mybrush_tool)
GIMP_COLOR_PICK_TARGET_FOREGROUND);
}
static void gimp_mybrush_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display)
{
GimpDisplayShell *shell;
GimpMybrushOptions *options = GIMP_MYBRUSH_TOOL_GET_OPTIONS (tool);
g_return_if_fail (GIMP_IS_DISPLAY (display));
shell = gimp_display_get_shell (display);
options->view_zoom = (gimp_zoom_model_get_factor (shell->zoom) >= 0.0f) ?
gimp_zoom_model_get_factor (shell->zoom) : 0.0001f;
options->view_rotation = shell->rotate_angle;
}
static void
gimp_mybrush_tool_options_notify (GimpTool *tool,
GimpToolOptions *options,

View File

@@ -324,7 +324,7 @@ bund_usr "$GIMP_PREFIX" "etc/gimp"
## Other features and plug-ins
### mypaint brushes
bund_usr "$UNIX_PREFIX" "share/mypaint-data/1.0"
bund_usr "$UNIX_PREFIX" "share/mypaint-data/2.0"
### Needed for 'th' word breaking in Text tool etc
bund_usr "$UNIX_PREFIX" "share/libthai"
conf_app LIBTHAI_DICTDIR "share/libthai"

View File

@@ -482,16 +482,12 @@
"sources": [
{
"type": "archive",
"url": "https://github.com/mypaint/mypaint-brushes/releases/download/v1.3.1/mypaint-brushes-1.3.1.tar.xz",
"sha256": "fef66ffc241b7c5cd29e9c518e933c739618cb51c4ed4d745bf648a1afc3fe70",
"url": "https://github.com/mypaint/mypaint-brushes/releases/download/v2.0.2/mypaint-brushes-2.0.2.tar.xz",
"sha256": "7984a74edef94571d872d0629b224abaa956a36f632f5c5516b33d22e49eb566",
"x-checker-data": {
"type": "anitya",
"project-id": 17096,
"stable-only": true,
"//": "https://github.com/mypaint/libmypaint/issues/101",
"versions": {
"<": "2.0.0"
},
"url-template": "https://github.com/mypaint/mypaint-brushes/releases/download/v$version/mypaint-brushes-$version.tar.xz"
}
}

View File

@@ -42,7 +42,8 @@ if ("$PSCommandPath" -like "*1_build-deps-msys2.ps1*" -or "$CI_JOB_NAME" -like "
{
& $MSYS_ROOT\usr\bin\pacman --noconfirm -Suy
}
& $MSYS_ROOT\usr\bin\pacman --noconfirm -S --needed $(if ($MSYSTEM_PREFIX -ne 'mingw32') { "$(if ($MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })-perl" }) (Get-Content build/windows/all-deps-uni.txt | Where-Object { $_.Trim() -ne '' }).Replace('${MINGW_PACKAGE_PREFIX}',$(if ($MINGW_PACKAGE_PREFIX) { "$MINGW_PACKAGE_PREFIX" } elseif ($MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })).Replace(' \','')
# TODO: When we drop 32-bit support, move an unconditional mypaint-brushes2 dependency back to all-deps-uni.txt
& $MSYS_ROOT\usr\bin\pacman --noconfirm -S --needed $(if ($MSYSTEM_PREFIX -ne 'mingw32') { "$(if ($MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })-perl`n$(if ($MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })-mypaint-brushes2" } else { 'mingw-w64-i686-mypaint-brushes' }) (Get-Content build/windows/all-deps-uni.txt).Replace('${MINGW_PACKAGE_PREFIX}',$(if ($MINGW_PACKAGE_PREFIX) { "$MINGW_PACKAGE_PREFIX" } elseif ($MSYSTEM_PREFIX -eq 'clangarm64') { 'mingw-w64-clang-aarch64' } else { 'mingw-w64-clang-x86_64' })).Replace(' \','')
Write-Output "$([char]27)[0Ksection_end:$(Get-Date -UFormat %s -Millisecond 0):deps_install$([char]13)$([char]27)[0K"

View File

@@ -14,7 +14,7 @@ if not os.getenv("MESON_BUILD_ROOT"):
# Bundle deps and GIMP files
GIMP_SOURCE = Path(os.getenv("MESON_SOURCE_ROOT")).as_posix()
GIMP_SOURCE = Path(os.getenv("MESON_SOURCE_ROOT")).as_posix()
## System prefix: it is MSYSTEM_PREFIX
with open("meson-logs/meson-log.txt") as f:
@@ -144,7 +144,10 @@ for lang in lang_array:
# For language list in text tool options
bundle(MSYSTEM_PREFIX, f"share/locale/{lang}/LC_MESSAGES/iso_639_3.mo")
### mypaint brushes
bundle(MSYSTEM_PREFIX, "share/mypaint-data")
if "32" not in MSYSTEM_PREFIX:
bundle(MSYSTEM_PREFIX, "share/mypaint-data/2.0")
else:
bundle(MSYSTEM_PREFIX, "share/mypaint-data/1.0")
### Needed for full CJK and Cyrillic support in file-pdf
bundle(MSYSTEM_PREFIX, "share/poppler")
@@ -164,7 +167,7 @@ if (os.getenv("GIMP_UNSTABLE") or not os.getenv("GIMP_RELEASE")) and "32" not in
#### See: https://gitlab.gnome.org/GNOME/gimp/-/issues/12119
bundle(MSYSTEM_PREFIX, "bin/libgvplugin_dot*.dll")
bundle(MSYSTEM_PREFIX, "bin/libgvplugin_pango*.dll")
bundle(MSYSTEM_PREFIX, "bin/config6")
bundle(MSYSTEM_PREFIX, "bin/config6")
### Needed to not pollute output. See: https://gitlab.gnome.org/GNOME/gimp/-/issues/8877
bundle(MSYSTEM_PREFIX, "bin/gdbus.exe")
### Needed for hyperlink support etc... See: https://gitlab.gnome.org/GNOME/gimp/-/issues/12288
@@ -173,7 +176,7 @@ bundle(MSYSTEM_PREFIX, "bin/gspawn*-console.exe")
if not os.getenv("GIMP_UNSTABLE") and os.getenv("GIMP_RELEASE"):
#...when running from `gimp*.exe`
bundle(MSYSTEM_PREFIX, "bin/gspawn*-helper.exe")
## Binaries for GObject Introspection support. See: https://gitlab.gnome.org/GNOME/gimp/-/issues/13170
bundle(GIMP_PREFIX, "lib/girepository-*/*.typelib")
bundle(MSYSTEM_PREFIX, "bin/libgirepository-*.dll")

View File

@@ -37,7 +37,6 @@ ${MINGW_PACKAGE_PREFIX}-libtiff \
${MINGW_PACKAGE_PREFIX}-libwebp \
${MINGW_PACKAGE_PREFIX}-libwmf \
${MINGW_PACKAGE_PREFIX}-maxflow \
${MINGW_PACKAGE_PREFIX}-mypaint-brushes \
${MINGW_PACKAGE_PREFIX}-openexr \
${MINGW_PACKAGE_PREFIX}-openjpeg2 \
${MINGW_PACKAGE_PREFIX}-pango \

View File

@@ -444,7 +444,11 @@ lcms_minver = '2.8'
lcms = dependency('lcms2', version: '>='+lcms_minver)
libmypaint_minver = '1.3.0'
libmypaint = dependency('libmypaint', version: '>='+libmypaint_minver)
mypaint_brushes = dependency('mypaint-brushes-1.0',version: '>='+libmypaint_minver)
mypaint_brushes_n = 'mypaint-brushes-2.0'
if platform_windows and host_cpu_family == 'x86'
mypaint_brushes_n = 'mypaint-brushes-1.0'
endif
mypaint_brushes = dependency(mypaint_brushes_n,version: '>='+libmypaint_minver)
if not libmypaint.version().version_compare('>=1.4.0')
libmypaint_warning='''
@@ -458,7 +462,7 @@ endif
if relocatable_bundle
mypaint_brushes_dir = '${gimp_installation_dir}'\
/'share'/'mypaint-data'/'1.0'/'brushes'
/'share'/'mypaint-data'/'2.0'/'brushes'
else
mypaint_brushes_dir = mypaint_brushes.get_variable(pkgconfig: 'brushesdir')
endif