[gimp] app: fix airbrush periodic stamp behavior
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: fix airbrush periodic stamp behavior
- Date: Wed, 18 Apr 2018 18:51:22 +0000 (UTC)
commit 542a04735be9df70377dd4d5020370d2e4437e59
Author: Ell <ell_se yahoo com>
Date: Wed Apr 18 13:35:28 2018 -0400
app: fix airbrush periodic stamp behavior
Commit ddfc7715cbcd8d165520902bc0abfff3c09b88f4 changed the
airbrush periodic stamp behavior, so that instead of using the main
brush, it issued a full MOTION event, potentially using a different
brush when using a GIH brush.
Fix this, by renaming the "timeout" signal of GimpAirbrush to
"stamp", and by adding a new gimp_airbrush_stamp() function, which
should be used for painting the periodic airbrush dab in response,
instead of calling gimp_paint_core_paint() directly, and which
calls gimp_airbrush_paint() instead, as the old code did.
In order to call this function from the paint thread, we replace
the various gimp_paint_tool_paint_core_foo() functions, introduced
in the above commit, with a generic gimp_paint_tool_paint_push()
function, which takes a callback (and a data pointer) to run on the
paint thread, and queues it for execution (when not using the paint
thread, the function is called directly from the calling thread.)
app/paint/gimpairbrush.c | 37 +++++-
app/paint/gimpairbrush.h | 12 ++-
app/tools/gimpairbrushtool.c | 37 ++++--
app/tools/gimppainttool-paint.c | 258 ++++++++++++++-------------------------
app/tools/gimppainttool-paint.h | 46 ++++----
5 files changed, 186 insertions(+), 204 deletions(-)
---
diff --git a/app/paint/gimpairbrush.c b/app/paint/gimpairbrush.c
index 042cb2b..c30cc24 100644
--- a/app/paint/gimpairbrush.c
+++ b/app/paint/gimpairbrush.c
@@ -38,7 +38,7 @@
enum
{
- TIMEOUT,
+ STAMP,
LAST_SIGNAL
};
@@ -88,11 +88,11 @@ gimp_airbrush_class_init (GimpAirbrushClass *klass)
paint_core_class->paint = gimp_airbrush_paint;
- airbrush_signals[TIMEOUT] =
- g_signal_new ("timeout",
+ airbrush_signals[STAMP] =
+ g_signal_new ("stamp",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GimpAirbrushClass, timeout),
+ G_STRUCT_OFFSET (GimpAirbrushClass, stamp),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@@ -114,6 +114,8 @@ gimp_airbrush_finalize (GObject *object)
airbrush->timeout_id = 0;
}
+ g_clear_object (&airbrush->sym);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -158,6 +160,13 @@ gimp_airbrush_paint (GimpPaintCore *paint_core,
fade_point = gimp_paint_options_get_fade (paint_options, image,
paint_core->pixel_dist);
+ airbrush->drawable = drawable;
+ airbrush->paint_options = paint_options;
+
+ if (airbrush->sym)
+ g_object_unref (airbrush->sym);
+ airbrush->sym = g_object_ref (sym);
+
/* Base our timeout on the original stroke. */
coords = gimp_symmetry_get_origin (sym);
@@ -180,6 +189,8 @@ gimp_airbrush_paint (GimpPaintCore *paint_core,
paint_options,
sym,
paint_state, time);
+
+ g_clear_object (&airbrush->sym);
break;
}
}
@@ -221,7 +232,23 @@ gimp_airbrush_timeout (gpointer data)
airbrush->timeout_id = 0;
- g_signal_emit (airbrush, airbrush_signals[TIMEOUT], 0);
+ g_signal_emit (airbrush, airbrush_signals[STAMP], 0);
return G_SOURCE_REMOVE;
}
+
+
+/* public functions */
+
+
+void
+gimp_airbrush_stamp (GimpAirbrush *airbrush)
+{
+ g_return_if_fail (GIMP_IS_AIRBRUSH (airbrush));
+
+ gimp_airbrush_paint (GIMP_PAINT_CORE (airbrush),
+ airbrush->drawable,
+ airbrush->paint_options,
+ airbrush->sym,
+ GIMP_PAINT_STATE_MOTION, 0);
+}
diff --git a/app/paint/gimpairbrush.h b/app/paint/gimpairbrush.h
index 7aa802c..4efb8d7 100644
--- a/app/paint/gimpairbrush.h
+++ b/app/paint/gimpairbrush.h
@@ -34,9 +34,13 @@ typedef struct _GimpAirbrushClass GimpAirbrushClass;
struct _GimpAirbrush
{
- GimpPaintbrush parent_instance;
+ GimpPaintbrush parent_instance;
- guint timeout_id;
+ guint timeout_id;
+
+ GimpSymmetry *sym;
+ GimpDrawable *drawable;
+ GimpPaintOptions *paint_options;
};
struct _GimpAirbrushClass
@@ -44,7 +48,7 @@ struct _GimpAirbrushClass
GimpPaintbrushClass parent_class;
/* signals */
- void (* timeout) (GimpAirbrush *airbrush);
+ void (* stamp) (GimpAirbrush *airbrush);
};
@@ -53,5 +57,7 @@ void gimp_airbrush_register (Gimp *gimp,
GType gimp_airbrush_get_type (void) G_GNUC_CONST;
+void gimp_airbrush_stamp (GimpAirbrush *airbrush);
+
#endif /* __GIMP_AIRBRUSH_H__ */
diff --git a/app/tools/gimpairbrushtool.c b/app/tools/gimpairbrushtool.c
index 2374a37..a315bb7 100644
--- a/app/tools/gimpairbrushtool.c
+++ b/app/tools/gimpairbrushtool.c
@@ -24,6 +24,7 @@
#include "tools-types.h"
+#include "paint/gimpairbrush.h"
#include "paint/gimpairbrushoptions.h"
#include "widgets/gimphelp-ids.h"
@@ -37,12 +38,15 @@
#include "gimp-intl.h"
-static void gimp_airbrush_tool_constructed (GObject *object);
+static void gimp_airbrush_tool_constructed (GObject *object);
-static void gimp_airbrush_tool_airbrush_timeout (GimpAirbrush *airbrush,
- GimpAirbrushTool *airbrush_tool);
+static void gimp_airbrush_tool_airbrush_stamp (GimpAirbrush *airbrush,
+ GimpAirbrushTool *airbrush_tool);
-static GtkWidget * gimp_airbrush_options_gui (GimpToolOptions *tool_options);
+static void gimp_airbrush_tool_stamp (GimpAirbrushTool *airbrush_tool,
+ gpointer data);
+
+static GtkWidget * gimp_airbrush_options_gui (GimpToolOptions *tool_options);
G_DEFINE_TYPE (GimpAirbrushTool, gimp_airbrush_tool, GIMP_TYPE_PAINTBRUSH_TOOL)
@@ -91,17 +95,30 @@ gimp_airbrush_tool_constructed (GObject *object)
G_OBJECT_CLASS (parent_class)->constructed (object);
- g_signal_connect_object (paint_tool->core, "timeout",
- G_CALLBACK (gimp_airbrush_tool_airbrush_timeout),
+ g_signal_connect_object (paint_tool->core, "stamp",
+ G_CALLBACK (gimp_airbrush_tool_airbrush_stamp),
object, 0);
}
static void
-gimp_airbrush_tool_airbrush_timeout (GimpAirbrush *airbrush,
- GimpAirbrushTool *airbrush_tool)
+gimp_airbrush_tool_airbrush_stamp (GimpAirbrush *airbrush,
+ GimpAirbrushTool *airbrush_tool)
{
- gimp_paint_tool_paint_core_paint (GIMP_PAINT_TOOL (airbrush_tool),
- GIMP_PAINT_STATE_MOTION, 0);
+ GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (airbrush_tool);
+
+ gimp_paint_tool_paint_push (
+ paint_tool,
+ (GimpPaintToolPaintFunc) gimp_airbrush_tool_stamp,
+ NULL);
+}
+
+static void
+gimp_airbrush_tool_stamp (GimpAirbrushTool *airbrush_tool,
+ gpointer data)
+{
+ GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (airbrush_tool);
+
+ gimp_airbrush_stamp (GIMP_AIRBRUSH (paint_tool->core));
}
diff --git a/app/tools/gimppainttool-paint.c b/app/tools/gimppainttool-paint.c
index 869c2d6..cf64b8d 100644
--- a/app/tools/gimppainttool-paint.c
+++ b/app/tools/gimppainttool-paint.c
@@ -41,44 +41,36 @@
#define DISPLAY_UPDATE_INTERVAL 10000 /* microseconds */
-typedef enum
-{
- PAINT_ITEM_TYPE_CORE_PAINT,
- PAINT_ITEM_TYPE_CORE_INTERPOLATE,
- PAINT_ITEM_TYPE_FINISH
-} PaintItemType;
+#define PAINT_FINISH NULL
typedef struct
{
- PaintItemType type;
-
+ GimpPaintTool *paint_tool;
+ GimpPaintToolPaintFunc func;
union
- {
- struct
{
- GimpPaintTool *paint_tool;
-
- union
- {
- GimpPaintState state;
- GimpCoords coords;
- };
-
- guint32 time;
+ gpointer data;
+ gboolean *finished;
};
-
- gboolean *finished;
- };
} PaintItem;
+typedef struct
+{
+ GimpCoords coords;
+ guint32 time;
+} InterpolateData;
+
/* local function prototypes */
-static gboolean gimp_paint_tool_paint_use_thread (GimpPaintTool *paint_tool);
-static gpointer gimp_paint_tool_paint_thread (gpointer data);
+static gboolean gimp_paint_tool_paint_use_thread (GimpPaintTool *paint_tool);
+static gpointer gimp_paint_tool_paint_thread (gpointer data);
+
+static gboolean gimp_paint_tool_paint_timeout (GimpPaintTool *paint_tool);
-static gboolean gimp_paint_tool_paint_timeout (GimpPaintTool *paint_tool);
+static void gimp_paint_tool_paint_interpolate (GimpPaintTool *paint_tool,
+ InterpolateData *data);
/* static variables */
@@ -136,56 +128,23 @@ gimp_paint_tool_paint_thread (gpointer data)
while (! (item = g_queue_pop_head (&paint_queue)))
g_cond_wait (&paint_queue_cond, &paint_queue_mutex);
- switch (item->type)
+ if (item->func == PAINT_FINISH)
{
- case PAINT_ITEM_TYPE_CORE_PAINT:
- {
- GimpPaintTool *paint_tool = item->paint_tool;
- GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
- GimpPaintCore *core = paint_tool->core;
- GimpDrawable *drawable = paint_tool->drawable;
-
- g_mutex_unlock (&paint_queue_mutex);
- g_mutex_lock (&paint_mutex);
-
- while (paint_timeout_pending)
- g_cond_wait (&paint_cond, &paint_mutex);
-
- gimp_paint_core_paint (core, drawable, paint_options,
- item->state, item->time);
-
- g_mutex_unlock (&paint_mutex);
- g_mutex_lock (&paint_queue_mutex);
- }
- break;
-
- case PAINT_ITEM_TYPE_CORE_INTERPOLATE:
- {
- GimpPaintTool *paint_tool = item->paint_tool;
- GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
- GimpPaintCore *core = paint_tool->core;
- GimpDrawable *drawable = paint_tool->drawable;
-
- g_mutex_unlock (&paint_queue_mutex);
- g_mutex_lock (&paint_mutex);
-
- while (paint_timeout_pending)
- g_cond_wait (&paint_cond, &paint_mutex);
-
- gimp_paint_core_interpolate (core, drawable, paint_options,
- &item->coords, item->time);
-
- g_mutex_unlock (&paint_mutex);
- g_mutex_lock (&paint_queue_mutex);
- }
- break;
-
- case PAINT_ITEM_TYPE_FINISH:
- {
- *item->finished = TRUE;
- g_cond_signal (&paint_queue_cond);
- }
- break;
+ *item->finished = TRUE;
+ g_cond_signal (&paint_queue_cond);
+ }
+ else
+ {
+ g_mutex_unlock (&paint_queue_mutex);
+ g_mutex_lock (&paint_mutex);
+
+ while (paint_timeout_pending)
+ g_cond_wait (&paint_cond, &paint_mutex);
+
+ item->func (item->paint_tool, item->data);
+
+ g_mutex_unlock (&paint_mutex);
+ g_mutex_lock (&paint_queue_mutex);
}
g_slice_free (PaintItem, item);
@@ -233,6 +192,20 @@ gimp_paint_tool_paint_timeout (GimpPaintTool *paint_tool)
return G_SOURCE_CONTINUE;
}
+static void
+gimp_paint_tool_paint_interpolate (GimpPaintTool *paint_tool,
+ InterpolateData *data)
+{
+ GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
+ GimpPaintCore *core = paint_tool->core;
+ GimpDrawable *drawable = paint_tool->drawable;
+
+ gimp_paint_core_interpolate (core, drawable, paint_options,
+ &data->coords, data->time);
+
+ g_slice_free (InterpolateData, data);
+}
+
/* public functions */
@@ -380,13 +353,16 @@ gimp_paint_tool_paint_end (GimpPaintTool *paint_tool,
gboolean finished = FALSE;
guint64 end_time;
+ g_return_if_fail (gimp_paint_tool_paint_is_active (paint_tool));
+
g_source_remove (paint_timeout_id);
paint_timeout_id = 0;
item = g_slice_new (PaintItem);
- item->type = PAINT_ITEM_TYPE_FINISH;
- item->finished = &finished;
+ item->paint_tool = paint_tool;
+ item->func = PAINT_FINISH;
+ item->finished = &finished;
g_mutex_lock (&paint_queue_mutex);
@@ -446,65 +422,27 @@ gimp_paint_tool_paint_is_active (GimpPaintTool *paint_tool)
gimp_drawable_is_painting (paint_tool->drawable);
}
-
void
-gimp_paint_tool_paint_motion (GimpPaintTool *paint_tool,
- const GimpCoords *coords,
- guint32 time)
-{
- GimpPaintOptions *paint_options;
- GimpPaintCore *core;
- GimpDrawable *drawable;
- GimpCoords curr_coords;
- gint off_x, off_y;
-
- g_return_if_fail (GIMP_IS_PAINT_TOOL (paint_tool));
- g_return_if_fail (coords != NULL);
- g_return_if_fail (paint_tool->display != NULL);
-
- paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
- core = paint_tool->core;
- drawable = paint_tool->drawable;
-
- curr_coords = *coords;
-
- gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
-
- curr_coords.x -= off_x;
- curr_coords.y -= off_y;
-
- gimp_paint_core_smooth_coords (core, paint_options, &curr_coords);
-
- /* Don't paint while the Shift key is pressed for line drawing */
- if (paint_tool->draw_line)
- {
- gimp_paint_core_set_current_coords (core, &curr_coords);
-
- return;
- }
-
- gimp_paint_tool_paint_core_interpolate (paint_tool, &curr_coords, time);
-}
-
-void
-gimp_paint_tool_paint_core_paint (GimpPaintTool *paint_tool,
- GimpPaintState state,
- guint32 time)
+gimp_paint_tool_paint_push (GimpPaintTool *paint_tool,
+ GimpPaintToolPaintFunc func,
+ gpointer data)
{
g_return_if_fail (GIMP_IS_PAINT_TOOL (paint_tool));
+ g_return_if_fail (func != NULL);
if (gimp_paint_tool_paint_use_thread (paint_tool))
{
PaintItem *item;
+ g_return_if_fail (gimp_paint_tool_paint_is_active (paint_tool));
+
/* Push an item to the queue, to be processed by the paint thread */
item = g_slice_new (PaintItem);
- item->type = PAINT_ITEM_TYPE_CORE_PAINT;
item->paint_tool = paint_tool;
- item->state = state;
- item->time = time;
+ item->func = func;
+ item->data = data;
g_mutex_lock (&paint_queue_mutex);
@@ -515,19 +453,15 @@ gimp_paint_tool_paint_core_paint (GimpPaintTool *paint_tool,
}
else
{
- GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (paint_tool);
- GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
- GimpPaintCore *core = paint_tool->core;
- GimpDisplay *display = paint_tool->display;
- GimpImage *image = gimp_display_get_image (display);
- GimpDrawable *drawable = paint_tool->drawable;
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (paint_tool);
+ GimpDisplay *display = paint_tool->display;
+ GimpImage *image = gimp_display_get_image (display);
/* Paint directly */
gimp_draw_tool_pause (draw_tool);
- gimp_paint_core_paint (core,
- drawable, paint_options, state, time);
+ func (paint_tool, data);
gimp_projection_flush_now (gimp_image_get_projection (image));
gimp_display_flush_now (display);
@@ -537,52 +471,48 @@ gimp_paint_tool_paint_core_paint (GimpPaintTool *paint_tool,
}
void
-gimp_paint_tool_paint_core_interpolate (GimpPaintTool *paint_tool,
- const GimpCoords *coords,
- guint32 time)
+gimp_paint_tool_paint_motion (GimpPaintTool *paint_tool,
+ const GimpCoords *coords,
+ guint32 time)
{
+ GimpPaintOptions *paint_options;
+ GimpPaintCore *core;
+ GimpDrawable *drawable;
+ InterpolateData *data;
+ gint off_x, off_y;
+
g_return_if_fail (GIMP_IS_PAINT_TOOL (paint_tool));
g_return_if_fail (coords != NULL);
+ g_return_if_fail (paint_tool->display != NULL);
- if (gimp_paint_tool_paint_use_thread (paint_tool))
- {
- PaintItem *item;
+ paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
+ core = paint_tool->core;
+ drawable = paint_tool->drawable;
- /* Push an item to the queue, to be processed by the paint thread */
+ data = g_slice_new (InterpolateData);
- item = g_slice_new (PaintItem);
+ data->coords = *coords;
+ data->time = time;
- item->type = PAINT_ITEM_TYPE_CORE_INTERPOLATE;
- item->paint_tool = paint_tool;
- item->coords = *coords;
- item->time = time;
+ gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
- g_mutex_lock (&paint_queue_mutex);
+ data->coords.x -= off_x;
+ data->coords.y -= off_y;
- g_queue_push_tail (&paint_queue, item);
- g_cond_signal (&paint_queue_cond);
+ gimp_paint_core_smooth_coords (core, paint_options, &data->coords);
- g_mutex_unlock (&paint_queue_mutex);
- }
- else
+ /* Don't paint while the Shift key is pressed for line drawing */
+ if (paint_tool->draw_line)
{
- GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (paint_tool);
- GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (paint_tool);
- GimpPaintCore *core = paint_tool->core;
- GimpDisplay *display = paint_tool->display;
- GimpImage *image = gimp_display_get_image (display);
- GimpDrawable *drawable = paint_tool->drawable;
-
- /* Paint directly */
-
- gimp_draw_tool_pause (draw_tool);
+ gimp_paint_core_set_current_coords (core, &data->coords);
- gimp_paint_core_interpolate (core,
- drawable, paint_options, coords, time);
+ g_slice_free (InterpolateData, data);
- gimp_projection_flush_now (gimp_image_get_projection (image));
- gimp_display_flush_now (display);
-
- gimp_draw_tool_resume (draw_tool);
+ return;
}
+
+ gimp_paint_tool_paint_push (
+ paint_tool,
+ (GimpPaintToolPaintFunc) gimp_paint_tool_paint_interpolate,
+ data);
}
diff --git a/app/tools/gimppainttool-paint.h b/app/tools/gimppainttool-paint.h
index 8dcc056..23d13b3 100644
--- a/app/tools/gimppainttool-paint.h
+++ b/app/tools/gimppainttool-paint.h
@@ -19,28 +19,30 @@
#define __GIMP_PAINT_TOOL_PAINT_H__
-gboolean gimp_paint_tool_paint_start (GimpPaintTool *tool,
- GimpDisplay *display,
- const GimpCoords *coords,
- guint32 time,
- gboolean constrain,
- GError **error);
-void gimp_paint_tool_paint_end (GimpPaintTool *tool,
- guint32 time,
- gboolean cancel);
-
-gboolean gimp_paint_tool_paint_is_active (GimpPaintTool *tool);
-
-void gimp_paint_tool_paint_motion (GimpPaintTool *tool,
- const GimpCoords *coords,
- guint32 time);
-
-void gimp_paint_tool_paint_core_paint (GimpPaintTool *tool,
- GimpPaintState state,
- guint32 time);
-void gimp_paint_tool_paint_core_interpolate (GimpPaintTool *tool,
- const GimpCoords *coords,
- guint32 time);
+typedef void (* GimpPaintToolPaintFunc) (GimpPaintTool *tool,
+ gpointer data);
+
+
+
+gboolean gimp_paint_tool_paint_start (GimpPaintTool *tool,
+ GimpDisplay *display,
+ const GimpCoords *coords,
+ guint32 time,
+ gboolean constrain,
+ GError **error);
+void gimp_paint_tool_paint_end (GimpPaintTool *tool,
+ guint32 time,
+ gboolean cancel);
+
+gboolean gimp_paint_tool_paint_is_active (GimpPaintTool *tool);
+
+void gimp_paint_tool_paint_push (GimpPaintTool *tool,
+ GimpPaintToolPaintFunc func,
+ gpointer data);
+
+void gimp_paint_tool_paint_motion (GimpPaintTool *tool,
+ const GimpCoords *coords,
+ guint32 time);
#endif /* __GIMP_PAINT_TOOL_PAINT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]