[gimp/gimp-2-10] app: properly implement "spacing" option in the warp tool
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app: properly implement "spacing" option in the warp tool
- Date: Sun, 3 Mar 2019 21:24:33 +0000 (UTC)
commit 40a9b38b5c34fa20c99711d6bcddcd58c2e33ef3
Author: Ell <ell_se yahoo com>
Date: Sun Mar 3 15:53:28 2019 -0500
app: properly implement "spacing" option in the warp tool
The "spacing" option of the warp tool used to be handled by the
gegl:warp op, and have little effect. Instead, implement it in the
warp tool directly, having the same effect as the other paint
tools.
Having a properly-working "spacing" option allows us to use EXACT
motion mode without cirppling down performance, which means that
the stroke now follows the pointer exactly, even when processing
takes a while.
Decrease the default "spacing" value to 10.
(cherry picked from commit e8a39d5c49a01d128f4237100845eda7523255f0)
app/tools/gimpwarpoptions.c | 2 +-
app/tools/gimpwarptool.c | 139 +++++++++++++++++++++++++++++---------------
app/tools/gimpwarptool.h | 6 +-
3 files changed, 98 insertions(+), 49 deletions(-)
---
diff --git a/app/tools/gimpwarpoptions.c b/app/tools/gimpwarpoptions.c
index de0cbe67b1..f534c279c4 100644
--- a/app/tools/gimpwarpoptions.c
+++ b/app/tools/gimpwarpoptions.c
@@ -111,7 +111,7 @@ gimp_warp_options_class_init (GimpWarpOptionsClass *klass)
"stroke-spacing",
_("Spacing"),
_("Stroke Spacing"),
- 1.0, 100.0, 20.0,
+ 1.0, 100.0, 10.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_ENUM (object_class, PROP_INTERPOLATION,
diff --git a/app/tools/gimpwarptool.c b/app/tools/gimpwarptool.c
index 1d93d2924b..76d414714c 100644
--- a/app/tools/gimpwarptool.c
+++ b/app/tools/gimpwarptool.c
@@ -131,9 +131,10 @@ static void gimp_warp_tool_update_area (GimpWarpTool *wt,
const GeglRectangle *area);
static void gimp_warp_tool_update_stroke (GimpWarpTool *wt,
GeglNode *node);
-static void gimp_warp_tool_stroke_changed (GeglPath *stroke,
- const GeglRectangle *roi,
- GimpWarpTool *wt);
+static void gimp_warp_tool_stroke_append (GimpWarpTool *wt,
+ gchar type,
+ gdouble x,
+ gdouble y);
static void gimp_warp_tool_filter_flush (GimpDrawableFilter *filter,
GimpTool *tool);
static void gimp_warp_tool_add_op (GimpWarpTool *wt,
@@ -194,6 +195,7 @@ gimp_warp_tool_init (GimpWarpTool *self)
{
GimpTool *tool = GIMP_TOOL (self);
+ gimp_tool_control_set_motion_mode (tool->control, GIMP_MOTION_MODE_EXACT);
gimp_tool_control_set_scroll_lock (tool->control, TRUE);
gimp_tool_control_set_preserve (tool->control, FALSE);
gimp_tool_control_set_dirty_mask (tool->control,
@@ -266,27 +268,32 @@ gimp_warp_tool_button_press (GimpTool *tool,
wt->current_stroke = gegl_path_new ();
+ wt->last_pos.x = coords->x;
+ wt->last_pos.y = coords->y;
+
+ wt->total_dist = 0.0;
+
new_op = gegl_node_new_child (NULL,
"operation", "gegl:warp",
"behavior", options->behavior,
"size", options->effect_size,
"hardness", options->effect_hardness / 100.0,
"strength", options->effect_strength,
- "spacing", options->stroke_spacing / 100.0,
+ /* we implement spacing manually.
+ * anything > 1 will do.
+ */
+ "spacing", 10.0,
"stroke", wt->current_stroke,
NULL);
gimp_warp_tool_add_op (wt, new_op);
g_object_unref (new_op);
- g_signal_connect (wt->current_stroke, "changed",
- G_CALLBACK (gimp_warp_tool_stroke_changed),
- wt);
-
gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y);
- gegl_path_append (wt->current_stroke,
- 'M', coords->x - off_x, coords->y - off_y);
+ gimp_warp_tool_stroke_append (wt,
+ 'M', wt->last_pos.x - off_x,
+ wt->last_pos.y - off_y);
gimp_warp_tool_start_stroke_timer (wt);
@@ -309,10 +316,6 @@ gimp_warp_tool_button_release (GimpTool *tool,
gimp_warp_tool_stop_stroke_timer (wt);
- g_signal_handlers_disconnect_by_func (wt->current_stroke,
- gimp_warp_tool_stroke_changed,
- wt);
-
#ifdef WARP_DEBUG
g_printerr ("%s\n", gegl_path_to_string (wt->current_stroke));
#endif
@@ -354,27 +357,64 @@ gimp_warp_tool_motion (GimpTool *tool,
GdkModifierType state,
GimpDisplay *display)
{
- GimpWarpTool *wt = GIMP_WARP_TOOL (tool);
- GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt);
+ GimpWarpTool *wt = GIMP_WARP_TOOL (tool);
+ GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt);
+ GimpVector2 old_cursor_pos;
+ GimpVector2 delta;
+ gdouble dist;
+ gdouble step;
+ gboolean stroke_changed = FALSE;
+
+ old_cursor_pos = wt->cursor_pos;
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ wt->cursor_pos.x = coords->x;
+ wt->cursor_pos.y = coords->y;
- wt->cursor_x = coords->x;
- wt->cursor_y = coords->y;
+ gimp_vector2_sub (&delta, &wt->cursor_pos, &old_cursor_pos);
+ dist = gimp_vector2_length (&delta);
- if (options->stroke_during_motion)
+ step = options->effect_size * options->stroke_spacing / 100.0;
+
+ while (wt->total_dist + dist >= step)
{
- gint off_x, off_y;
+ gdouble diff = step - wt->total_dist;
- gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y);
+ gimp_vector2_mul (&delta, diff / dist);
+ gimp_vector2_add (&old_cursor_pos, &old_cursor_pos, &delta);
- gegl_path_append (wt->current_stroke,
- 'L', wt->cursor_x - off_x, wt->cursor_y - off_y);
+ gimp_vector2_sub (&delta, &wt->cursor_pos, &old_cursor_pos);
+ dist -= diff;
- gimp_warp_tool_start_stroke_timer (wt);
+ wt->last_pos = old_cursor_pos;
+ wt->total_dist = 0.0;
+
+ if (options->stroke_during_motion)
+ {
+ gint off_x, off_y;
+
+ if (! stroke_changed)
+ {
+ stroke_changed = TRUE;
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ }
+
+ gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y);
+
+ gimp_warp_tool_stroke_append (wt,
+ 'L', wt->last_pos.x - off_x,
+ wt->last_pos.y - off_y);
+ }
}
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ wt->total_dist += dist;
+
+ if (stroke_changed)
+ {
+ gimp_warp_tool_start_stroke_timer (wt);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ }
}
static gboolean
@@ -420,8 +460,10 @@ gimp_warp_tool_oper_update (GimpTool *tool,
if (! tool->display || display == tool->display)
{
- wt->cursor_x = coords->x;
- wt->cursor_y = coords->y;
+ wt->cursor_pos.x = coords->x;
+ wt->cursor_pos.y = coords->y;
+
+ wt->last_pos = wt->cursor_pos;
}
if (! gimp_draw_tool_is_active (draw_tool))
@@ -607,8 +649,8 @@ gimp_warp_tool_draw (GimpDrawTool *draw_tool)
gimp_draw_tool_add_arc (draw_tool,
FALSE,
- wt->cursor_x - options->effect_size * 0.5,
- wt->cursor_y - options->effect_size * 0.5,
+ wt->last_pos.x - options->effect_size * 0.5,
+ wt->last_pos.y - options->effect_size * 0.5,
options->effect_size,
options->effect_size,
0.0, 2.0 * G_PI);
@@ -859,8 +901,9 @@ gimp_warp_tool_stroke_timer (GimpWarpTool *wt)
gimp_item_get_offset (GIMP_ITEM (tool->drawable), &off_x, &off_y);
- gegl_path_append (wt->current_stroke,
- 'L', wt->cursor_x - off_x, wt->cursor_y - off_y);
+ gimp_warp_tool_stroke_append (wt,
+ 'L', wt->last_pos.x - off_x,
+ wt->last_pos.y - off_y);
return TRUE;
}
@@ -1099,24 +1142,28 @@ gimp_warp_tool_update_stroke (GimpWarpTool *wt,
}
static void
-gimp_warp_tool_stroke_changed (GeglPath *path,
- const GeglRectangle *roi,
- GimpWarpTool *wt)
+gimp_warp_tool_stroke_append (GimpWarpTool *wt,
+ gchar type,
+ gdouble x,
+ gdouble y)
{
- GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt);
- GeglRectangle update_region;
+ GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt);
+ GeglRectangle area;
+
+ if (! wt->filter)
+ return;
+
+ gegl_path_append (wt->current_stroke, type, x, y);
- update_region.x = floor (roi->x - options->effect_size * 0.5);
- update_region.y = floor (roi->y - options->effect_size * 0.5);
- update_region.width = ceil (roi->x + roi->width +
- options->effect_size * 0.5) - update_region.x;
- update_region.height = ceil (roi->y + roi->height +
- options->effect_size * 0.5) - update_region.y;
+ area.x = floor (x - options->effect_size * 0.5);
+ area.y = floor (y - options->effect_size * 0.5);
+ area.width = ceil (x + options->effect_size * 0.5) - area.x;
+ area.height = ceil (y + options->effect_size * 0.5) - area.y;
#ifdef WARP_DEBUG
g_printerr ("update rect: (%d,%d), %dx%d\n",
- update_region.x, update_region.y,
- update_region.width, update_region.height);
+ area.x, area.y,
+ area.width, area.height);
#endif
if (wt->render_node)
@@ -1128,7 +1175,7 @@ gimp_warp_tool_stroke_changed (GeglPath *path,
gimp_warp_tool_update_bounds (wt);
}
- gimp_warp_tool_update_area (wt, &update_region);
+ gimp_warp_tool_update_area (wt, &area);
}
static void
diff --git a/app/tools/gimpwarptool.h b/app/tools/gimpwarptool.h
index 4cf4031c61..89f0ef4749 100644
--- a/app/tools/gimpwarptool.h
+++ b/app/tools/gimpwarptool.h
@@ -41,8 +41,7 @@ struct _GimpWarpTool
{
GimpDrawTool parent_instance;
- gdouble cursor_x; /* Hold the cursor x position */
- gdouble cursor_y; /* Hold the cursor y position */
+ GimpVector2 cursor_pos; /* Hold the cursor position */
GeglBuffer *coords_buffer; /* Buffer where coordinates are stored */
@@ -52,6 +51,9 @@ struct _GimpWarpTool
GeglPath *current_stroke;
guint stroke_timer;
+ GimpVector2 last_pos;
+ gdouble total_dist;
+
GimpDrawableFilter *filter;
GList *redo_stack;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]