[gimp/soc-2011-warp: 4/72] gimpwarptool: add gegl infrastructure and image map for preview
- From: Michael Murà <mmure src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2011-warp: 4/72] gimpwarptool: add gegl infrastructure and image map for preview
- Date: Wed, 14 Mar 2012 12:17:41 +0000 (UTC)
commit b5c194dff2cf522c3a49cb847224d90ae5941a4e
Author: Michael Murà <batolettre gmail com>
Date: Wed May 25 01:54:38 2011 +0200
gimpwarptool: add gegl infrastructure and image map for preview
app/tools/gimpwarptool.c | 177 +++++++++++++++++++++++++++++++++++++++++++++-
app/tools/gimpwarptool.h | 7 ++
2 files changed, 182 insertions(+), 2 deletions(-)
---
diff --git a/app/tools/gimpwarptool.c b/app/tools/gimpwarptool.c
index 58406cb..b9d19b6 100644
--- a/app/tools/gimpwarptool.c
+++ b/app/tools/gimpwarptool.c
@@ -97,6 +97,12 @@ static void gimp_warp_tool_oper_update (GimpTool *tool
static void gimp_warp_tool_draw (GimpDrawTool *draw_tool);
+static void gimp_warp_tool_create_image_map (GimpWarpTool *wt,
+ GimpDrawable *drawable);
+static void gimp_warp_tool_image_map_flush (GimpImageMap *image_map,
+ GimpTool *tool);
+static void gimp_warp_tool_image_map_update (GimpWarpTool *wt);
+
G_DEFINE_TYPE (GimpWarpTool, gimp_warp_tool, GIMP_TYPE_DRAW_TOOL)
#define parent_class gimp_warp_tool_parent_class
@@ -150,6 +156,10 @@ gimp_warp_tool_init (GimpWarpTool *self)
gimp_tool_control_set_wants_click (tool->control, TRUE);
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PERSPECTIVE);
+
+ self->coords_buffer = NULL;
+ self->render_node = NULL;
+ self->image_map = NULL;
}
static void
@@ -163,7 +173,35 @@ gimp_warp_tool_control (GimpTool *tool,
{
case GIMP_TOOL_ACTION_PAUSE:
case GIMP_TOOL_ACTION_RESUME:
+ break;
+
case GIMP_TOOL_ACTION_HALT:
+ if (wt->coords_buffer)
+ {
+ gegl_buffer_destroy (wt->coords_buffer);
+ wt->coords_buffer = NULL;
+ }
+
+ if (wt->render_node)
+ {
+ g_object_unref (wt->render_node);
+ wt->render_node = NULL;
+ }
+
+ if (wt->image_map)
+ {
+ gimp_tool_control_set_preserve (tool->control, TRUE);
+
+ gimp_image_map_abort (wt->image_map);
+ g_object_unref (wt->image_map);
+ wt->image_map = NULL;
+
+ gimp_tool_control_set_preserve (tool->control, FALSE);
+
+ gimp_image_flush (gimp_display_get_image (tool->display));
+ }
+
+ tool->display = NULL;
break;
}
@@ -174,12 +212,49 @@ static void
gimp_warp_tool_start (GimpWarpTool *wt,
GimpDisplay *display)
{
- GimpTool *tool = GIMP_TOOL (wt);
+ GimpTool *tool = GIMP_TOOL (wt);
+ GimpImage *image = gimp_display_get_image (display);
+ GimpDrawable *drawable = gimp_image_get_active_drawable (image);
+ Babl *format;
+ gint x1, x2, y1, y2;
+ GeglRectangle bbox;
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
tool->display = display;
+ if (wt->coords_buffer)
+ {
+ gegl_buffer_destroy (wt->coords_buffer);
+ wt->coords_buffer = NULL;
+ }
+
+ if (wt->render_node)
+ {
+ g_object_unref (wt->render_node);
+ wt->render_node = NULL;
+ }
+
+ if (wt->image_map)
+ {
+ gimp_image_map_abort (wt->image_map);
+ g_object_unref (wt->image_map);
+ wt->image_map = NULL;
+ }
+
+ /* Create the coords buffer, with the size of the selection */
+ format = babl_format_n (babl_type ("float"), 2);
+
+ gimp_channel_bounds (gimp_image_get_mask (image), &x1, &y1, &x2, &y2);
+
+ bbox.x = MIN (x1, x2);
+ bbox.y = MIN (y1, y2);
+ bbox.width = ABS (x1 - x2);
+ bbox.height = ABS (y1 - y2);
+
+ wt->coords_buffer = gegl_buffer_new (&bbox, format);
+
+ gimp_warp_tool_create_image_map (wt, drawable);
gimp_draw_tool_start (GIMP_DRAW_TOOL (wt), display);
}
@@ -188,7 +263,7 @@ gimp_warp_tool_options_notify (GimpTool *tool,
GimpToolOptions *options,
const GParamSpec *pspec)
{
- GimpWarpTool *ct = GIMP_WARP_TOOL (tool);
+ GimpWarpTool *wt = GIMP_WARP_TOOL (tool);
GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec);
@@ -273,6 +348,8 @@ gimp_warp_tool_button_press (GimpTool *tool,
if (display != tool->display)
gimp_warp_tool_start (wt, display);
+ gimp_warp_tool_image_map_update (wt);
+
gimp_tool_control_activate (tool->control);
}
@@ -323,3 +400,99 @@ gimp_warp_tool_draw (GimpDrawTool *draw_tool)
{
GimpWarpTool *wt = GIMP_WARP_TOOL (draw_tool);
}
+
+static void
+gimp_warp_tool_create_render_node (GimpWarpTool *wt)
+{
+ GeglNode *coords, *render; /* Render nodes */
+ GeglNode *input, *output; /* Proxy nodes*/
+ GeglNode *node; /* wraper to be returned */
+
+ g_return_if_fail (wt->render_node == NULL);
+ /* render_node is not supposed to be recreated */
+
+ node = gegl_node_new ();
+
+ input = gegl_node_get_input_proxy (node, "input");
+ output = gegl_node_get_output_proxy (node, "output");
+
+ coords = gegl_node_new_child (node,
+ "operation", "gegl:buffer-source",
+ "buffer", wt->coords_buffer,
+ NULL);
+
+ render = gegl_node_new_child (node,
+ "operation", "gegl:map-absolute",
+ NULL);
+
+ gegl_node_connect_to (input, "output",
+ render, "input");
+
+ gegl_node_connect_to (coords, "output",
+ render, "aux");
+
+ gegl_node_connect_to (render, "output",
+ output, "input");
+
+ wt->render_node = node;
+ wt->coords_node = coords;
+}
+
+static void
+gimp_warp_tool_create_image_map (GimpWarpTool *wt,
+ GimpDrawable *drawable)
+{
+ if (!wt->render_node)
+ gimp_warp_tool_create_render_node (wt);
+
+ wt->image_map = gimp_image_map_new (drawable,
+ _("Warp transform"),
+ wt->render_node,
+ NULL,
+ NULL);
+
+ g_signal_connect (wt->image_map, "flush",
+ G_CALLBACK (gimp_warp_tool_image_map_flush),
+ wt);
+}
+
+static void
+gimp_warp_tool_image_map_flush (GimpImageMap *image_map,
+ GimpTool *tool)
+{
+ GimpImage *image = gimp_display_get_image (tool->display);
+
+ gimp_projection_flush_now (gimp_image_get_projection (image));
+ gimp_display_flush_now (tool->display);
+}
+
+static void
+gimp_warp_tool_image_map_update (GimpWarpTool *wt)
+{
+ GimpTool *tool = GIMP_TOOL (wt);
+ GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
+ GimpItem *item = GIMP_ITEM (tool->drawable);
+ gint x, y;
+ gint w, h;
+ gint off_x, off_y;
+ GeglRectangle visible;
+
+ gimp_display_shell_untransform_viewport (shell, &x, &y, &w, &h);
+
+ gimp_item_get_offset (item, &off_x, &off_y);
+
+ gimp_rectangle_intersect (x, y, w, h,
+ off_x,
+ off_y,
+ gimp_item_get_width (item),
+ gimp_item_get_height (item),
+ &visible.x,
+ &visible.y,
+ &visible.width,
+ &visible.height);
+
+ visible.x -= off_x;
+ visible.y -= off_y;
+
+ gimp_image_map_apply (wt->image_map, &visible);
+}
diff --git a/app/tools/gimpwarptool.h b/app/tools/gimpwarptool.h
index 7144ff6..6a3b6c1 100644
--- a/app/tools/gimpwarptool.h
+++ b/app/tools/gimpwarptool.h
@@ -40,6 +40,13 @@ typedef struct _GimpWarpToolClass GimpWarpToolClass;
struct _GimpWarpTool
{
GimpDrawTool parent_instance;
+
+ GeglBuffer *coords_buffer; /* Gegl buffer where coordinates are stored */
+
+ GeglNode *coords_node; /* Gegl node that read in the coords buffer */
+ GeglNode *render_node; /* Gegl node graph to render the transfromation */
+
+ GimpImageMap *image_map; /* For preview */
};
struct _GimpWarpToolClass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]