app: improve warp-tool cropped-area calculation

In the warp tool, use the gegl:map-relative node to calculate the
affected drawable area to which the filter is cropped, to account
for box filtering.

(cherry picked from commit daa09ef602)
This commit is contained in:
Ell
2019-03-04 08:25:39 -05:00
parent 2758a34b02
commit 6ae957088a

View File

@ -57,94 +57,95 @@
#define PREVIEW_SAMPLER GEGL_SAMPLER_NEAREST #define PREVIEW_SAMPLER GEGL_SAMPLER_NEAREST
static void gimp_warp_tool_control (GimpTool *tool, static void gimp_warp_tool_control (GimpTool *tool,
GimpToolAction action, GimpToolAction action,
GimpDisplay *display); GimpDisplay *display);
static void gimp_warp_tool_button_press (GimpTool *tool, static void gimp_warp_tool_button_press (GimpTool *tool,
const GimpCoords *coords, const GimpCoords *coords,
guint32 time, guint32 time,
GdkModifierType state, GdkModifierType state,
GimpButtonPressType press_type, GimpButtonPressType press_type,
GimpDisplay *display); GimpDisplay *display);
static void gimp_warp_tool_button_release (GimpTool *tool, static void gimp_warp_tool_button_release (GimpTool *tool,
const GimpCoords *coords, const GimpCoords *coords,
guint32 time, guint32 time,
GdkModifierType state, GdkModifierType state,
GimpButtonReleaseType release_type, GimpButtonReleaseType release_type,
GimpDisplay *display); GimpDisplay *display);
static void gimp_warp_tool_motion (GimpTool *tool, static void gimp_warp_tool_motion (GimpTool *tool,
const GimpCoords *coords, const GimpCoords *coords,
guint32 time, guint32 time,
GdkModifierType state, GdkModifierType state,
GimpDisplay *display); GimpDisplay *display);
static gboolean gimp_warp_tool_key_press (GimpTool *tool, static gboolean gimp_warp_tool_key_press (GimpTool *tool,
GdkEventKey *kevent, GdkEventKey *kevent,
GimpDisplay *display); GimpDisplay *display);
static void gimp_warp_tool_oper_update (GimpTool *tool, static void gimp_warp_tool_oper_update (GimpTool *tool,
const GimpCoords *coords, const GimpCoords *coords,
GdkModifierType state, GdkModifierType state,
gboolean proximity, gboolean proximity,
GimpDisplay *display); GimpDisplay *display);
static void gimp_warp_tool_cursor_update (GimpTool *tool, static void gimp_warp_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords, const GimpCoords *coords,
GdkModifierType state, GdkModifierType state,
GimpDisplay *display); GimpDisplay *display);
const gchar * gimp_warp_tool_can_undo (GimpTool *tool, const gchar * gimp_warp_tool_can_undo (GimpTool *tool,
GimpDisplay *display); GimpDisplay *display);
const gchar * gimp_warp_tool_can_redo (GimpTool *tool, const gchar * gimp_warp_tool_can_redo (GimpTool *tool,
GimpDisplay *display); GimpDisplay *display);
static gboolean gimp_warp_tool_undo (GimpTool *tool, static gboolean gimp_warp_tool_undo (GimpTool *tool,
GimpDisplay *display); GimpDisplay *display);
static gboolean gimp_warp_tool_redo (GimpTool *tool, static gboolean gimp_warp_tool_redo (GimpTool *tool,
GimpDisplay *display); GimpDisplay *display);
static void gimp_warp_tool_options_notify (GimpTool *tool, static void gimp_warp_tool_options_notify (GimpTool *tool,
GimpToolOptions *options, GimpToolOptions *options,
const GParamSpec *pspec); const GParamSpec *pspec);
static void gimp_warp_tool_draw (GimpDrawTool *draw_tool); static void gimp_warp_tool_draw (GimpDrawTool *draw_tool);
static gboolean gimp_warp_tool_can_stroke (GimpWarpTool *wt, static gboolean gimp_warp_tool_can_stroke (GimpWarpTool *wt,
GimpDisplay *display, GimpDisplay *display,
gboolean show_message); gboolean show_message);
static gboolean gimp_warp_tool_start (GimpWarpTool *wt, static gboolean gimp_warp_tool_start (GimpWarpTool *wt,
GimpDisplay *display); GimpDisplay *display);
static void gimp_warp_tool_halt (GimpWarpTool *wt); static void gimp_warp_tool_halt (GimpWarpTool *wt);
static void gimp_warp_tool_commit (GimpWarpTool *wt); static void gimp_warp_tool_commit (GimpWarpTool *wt);
static void gimp_warp_tool_start_stroke_timer (GimpWarpTool *wt); static void gimp_warp_tool_start_stroke_timer (GimpWarpTool *wt);
static void gimp_warp_tool_stop_stroke_timer (GimpWarpTool *wt); static void gimp_warp_tool_stop_stroke_timer (GimpWarpTool *wt);
static gboolean gimp_warp_tool_stroke_timer (GimpWarpTool *wt); static gboolean gimp_warp_tool_stroke_timer (GimpWarpTool *wt);
static void gimp_warp_tool_create_graph (GimpWarpTool *wt); static void gimp_warp_tool_create_graph (GimpWarpTool *wt);
static void gimp_warp_tool_create_filter (GimpWarpTool *wt, static void gimp_warp_tool_create_filter (GimpWarpTool *wt,
GimpDrawable *drawable); GimpDrawable *drawable);
static void gimp_warp_tool_set_sampler (GimpWarpTool *wt, static void gimp_warp_tool_set_sampler (GimpWarpTool *wt,
gboolean commit); gboolean commit);
static GeglRectangle static GeglRectangle
gimp_warp_tool_get_stroke_bounds (GeglNode *node); gimp_warp_tool_get_stroke_bounds (GeglNode *node);
static GeglRectangle static GeglRectangle gimp_warp_tool_get_node_bounds (GeglNode *node);
gimp_warp_tool_get_node_bounds (GeglNode *node); static void gimp_warp_tool_clear_node_bounds (GeglNode *node);
static void gimp_warp_tool_clear_node_bounds (GeglNode *node); static GeglRectangle gimp_warp_tool_get_invalidated_by_change (GimpWarpTool *wt,
static void gimp_warp_tool_update_bounds (GimpWarpTool *wt); const GeglRectangle *area);
static void gimp_warp_tool_update_area (GimpWarpTool *wt, static void gimp_warp_tool_update_bounds (GimpWarpTool *wt);
const GeglRectangle *area, static void gimp_warp_tool_update_area (GimpWarpTool *wt,
gboolean synchronous); const GeglRectangle *area,
static void gimp_warp_tool_update_stroke (GimpWarpTool *wt, gboolean synchronous);
GeglNode *node); static void gimp_warp_tool_update_stroke (GimpWarpTool *wt,
static void gimp_warp_tool_stroke_append (GimpWarpTool *wt, GeglNode *node);
gchar type, static void gimp_warp_tool_stroke_append (GimpWarpTool *wt,
gdouble x, gchar type,
gdouble y); gdouble x,
static void gimp_warp_tool_filter_flush (GimpDrawableFilter *filter, gdouble y);
GimpTool *tool); static void gimp_warp_tool_filter_flush (GimpDrawableFilter *filter,
static void gimp_warp_tool_add_op (GimpWarpTool *wt, GimpTool *tool);
GeglNode *op); static void gimp_warp_tool_add_op (GimpWarpTool *wt,
static void gimp_warp_tool_remove_op (GimpWarpTool *wt, GeglNode *op);
GeglNode *op); static void gimp_warp_tool_remove_op (GimpWarpTool *wt,
static void gimp_warp_tool_free_op (GeglNode *op); GeglNode *op);
static void gimp_warp_tool_free_op (GeglNode *op);
static void gimp_warp_tool_animate (GimpWarpTool *wt); static void gimp_warp_tool_animate (GimpWarpTool *wt);
G_DEFINE_TYPE (GimpWarpTool, gimp_warp_tool, GIMP_TYPE_DRAW_TOOL) G_DEFINE_TYPE (GimpWarpTool, gimp_warp_tool, GIMP_TYPE_DRAW_TOOL)
@ -620,6 +621,7 @@ gimp_warp_tool_options_notify (GimpTool *tool,
{ {
gimp_warp_tool_set_sampler (wt, /* commit = */ FALSE); gimp_warp_tool_set_sampler (wt, /* commit = */ FALSE);
gimp_warp_tool_update_bounds (wt);
gimp_warp_tool_update_stroke (wt, NULL); gimp_warp_tool_update_stroke (wt, NULL);
} }
} }
@ -638,6 +640,7 @@ gimp_warp_tool_options_notify (GimpTool *tool,
{ {
gimp_warp_tool_set_sampler (wt, /* commit = */ FALSE); gimp_warp_tool_set_sampler (wt, /* commit = */ FALSE);
gimp_warp_tool_update_bounds (wt);
gimp_warp_tool_update_stroke (wt, NULL); gimp_warp_tool_update_stroke (wt, NULL);
} }
} }
@ -1072,6 +1075,26 @@ gimp_warp_tool_clear_node_bounds (GeglNode *node)
g_object_set_data (G_OBJECT (node), "gimp-warp-tool-bounds", NULL); g_object_set_data (G_OBJECT (node), "gimp-warp-tool-bounds", NULL);
} }
static GeglRectangle
gimp_warp_tool_get_invalidated_by_change (GimpWarpTool *wt,
const GeglRectangle *area)
{
GeglRectangle result = *area;
if (! wt->filter)
return result;
if (wt->render_node)
{
GeglOperation *operation = gegl_node_get_gegl_operation (wt->render_node);
result = gegl_operation_get_invalidated_by_change (operation,
"aux", area);
}
return result;
}
static void static void
gimp_warp_tool_update_bounds (GimpWarpTool *wt) gimp_warp_tool_update_bounds (GimpWarpTool *wt)
{ {
@ -1085,6 +1108,8 @@ gimp_warp_tool_update_bounds (GimpWarpTool *wt)
GeglNode *node = gegl_node_get_producer (wt->render_node, "aux", NULL); GeglNode *node = gegl_node_get_producer (wt->render_node, "aux", NULL);
bounds = gimp_warp_tool_get_node_bounds (node); bounds = gimp_warp_tool_get_node_bounds (node);
bounds = gimp_warp_tool_get_invalidated_by_change (wt, &bounds);
} }
gimp_drawable_filter_set_crop (wt->filter, &bounds, FALSE); gimp_drawable_filter_set_crop (wt->filter, &bounds, FALSE);
@ -1095,17 +1120,12 @@ gimp_warp_tool_update_area (GimpWarpTool *wt,
const GeglRectangle *area, const GeglRectangle *area,
gboolean synchronous) gboolean synchronous)
{ {
GeglRectangle rect = *area; GeglRectangle rect;
if (! wt->filter) if (! wt->filter)
return; return;
if (wt->render_node) rect = gimp_warp_tool_get_invalidated_by_change (wt, area);
{
GeglOperation *operation = gegl_node_get_gegl_operation (wt->render_node);
rect = gegl_operation_get_invalidated_by_change (operation, "aux", &rect);
}
if (synchronous) if (synchronous)
{ {