From 7084cbbec7d90d1664a6bfd582e87de25bb5b727 Mon Sep 17 00:00:00 2001 From: askmeaboutloom Date: Wed, 2 Oct 2024 12:15:36 +0200 Subject: [PATCH] Make MyPaint brushes not ignore their first stroke Inexplicably, they sometimes just don't do anything on the first stroke made with them. This is now fixed by issuing a dummy stroke when the brush engine is constructed, which gets that initial, potentially ignored stroke out of the way. --- ChangeLog | 1 + .../libengine/dpengine/brush_engine.c | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/ChangeLog b/ChangeLog index ba211d0a2..54bcdc429 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,7 @@ Unreleased Version 2.2.2-pre * Feature: Add Layer > Group View to show the parent group of the current layer in isolation. Thanks Rylan for suggesting. * Fix: Save and export images according to the current view mode. Thanks incoheart for reporting. * Server Fix: Don't get announcement refreshes stuck in an infinite loop. Thanks Meru for reporting. + * Fix: Make MyPaint brushes not ignore the first stroke made with them. This would also sometimes lead to a blank preview. 2024-08-09 Version 2.2.2-beta.3 * Fix: Use more accurate timers for performance profiles if the platform supports it. diff --git a/src/drawdance/libengine/dpengine/brush_engine.c b/src/drawdance/libengine/dpengine/brush_engine.c index 18e098f4f..a523aa9d9 100644 --- a/src/drawdance/libengine/dpengine/brush_engine.c +++ b/src/drawdance/libengine/dpengine/brush_engine.c @@ -680,6 +680,70 @@ static void get_color_mypaint(MyPaintSurface *self, float x, float y, } +// The MyPaint brush engine sometimes ignores the first stroke issued. We do a +// dummy stroke to begin with to get that out of the way, these dummy functions +// here just accept the stroke and throw it away. + +static int add_dab_mypaint_pigment_dummy( + DP_UNUSED MyPaintSurface2 *self, DP_UNUSED float x, DP_UNUSED float y, + DP_UNUSED float radius, DP_UNUSED float color_r, DP_UNUSED float color_g, + DP_UNUSED float color_b, DP_UNUSED float opaque, DP_UNUSED float hardness, + DP_UNUSED float alpha_eraser, DP_UNUSED float aspect_ratio, + DP_UNUSED float angle, DP_UNUSED float lock_alpha, DP_UNUSED float colorize, + DP_UNUSED float posterize, DP_UNUSED float posterize_num, + DP_UNUSED float paint) +{ + return 1; +} + +static int add_dab_mypaint_dummy(MyPaintSurface *self, float x, float y, + float radius, float color_r, float color_g, + float color_b, float opaque, float hardness, + float alpha_eraser, float aspect_ratio, + float angle, float lock_alpha, float colorize) +{ + return add_dab_mypaint_pigment_dummy( + (MyPaintSurface2 *)self, x, y, radius, color_r, color_g, color_b, + opaque, hardness, alpha_eraser, aspect_ratio, angle, lock_alpha, + colorize, 0.0f, 0.0f, 0.0f); +} + +static void get_color_mypaint_pigment_dummy( + DP_UNUSED MyPaintSurface2 *self, DP_UNUSED float x, DP_UNUSED float y, + DP_UNUSED float radius, float *color_r, float *color_g, float *color_b, + float *color_a, DP_UNUSED float paint) +{ + *color_r = 0.0f; + *color_g = 0.0f; + *color_b = 0.0f; + *color_a = 0.0f; +} + +static void get_color_mypaint_dummy(MyPaintSurface *self, float x, float y, + float radius, float *color_r, + float *color_g, float *color_b, + float *color_a) +{ + get_color_mypaint_pigment_dummy((MyPaintSurface2 *)self, x, y, radius, + color_r, color_g, color_b, color_a, 0.0f); +} + +static void issue_dummy_mypaint_stroke(MyPaintBrush *mb) +{ + MyPaintSurface2 surface = {{add_dab_mypaint_dummy, get_color_mypaint_dummy, + NULL, NULL, NULL, NULL, 0}, + add_dab_mypaint_pigment_dummy, + get_color_mypaint_pigment_dummy, + NULL}; + mypaint_brush_reset(mb); + mypaint_brush_new_stroke(mb); + mypaint_brush_stroke_to_2(mb, &surface, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 1000.0f, 1.0f, 0.0f, 0.0f); + mypaint_brush_stroke_to_2(mb, &surface, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0, + 1.0f, 0.0f, 0.0f); +} + + DP_BrushEngine * DP_brush_engine_new(DP_BrushEnginePushMessageFn push_message, DP_BrushEnginePollControlFn poll_control_or_null, @@ -720,6 +784,7 @@ DP_brush_engine_new(DP_BrushEnginePushMessageFn push_message, user}; DP_queue_init(&be->stabilizer.queue, 128, sizeof(DP_BrushPoint)); DP_vector_init(&be->stabilizer.points, 128, sizeof(DP_BrushPoint)); + issue_dummy_mypaint_stroke(be->mypaint_brush); return be; }