[gimp/blend-tool-fun] foo
- From: Michael Henning <mhenning src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/blend-tool-fun] foo
- Date: Mon, 27 Apr 2015 01:38:57 +0000 (UTC)
commit 52f51d3516706523d3b25622dd39bbf69d89d462
Author: Michael Henning <drawoc darkrefraction com>
Date: Sun Apr 26 21:38:11 2015 -0400
foo
app/tools/gimpblendtool.c | 146 ++++++++++++++++++++++++++++++++++++++++++++-
app/tools/gimpblendtool.h | 4 +
2 files changed, 148 insertions(+), 2 deletions(-)
---
diff --git a/app/tools/gimpblendtool.c b/app/tools/gimpblendtool.c
index 265653c..74ea230 100644
--- a/app/tools/gimpblendtool.c
+++ b/app/tools/gimpblendtool.c
@@ -912,12 +912,112 @@ gimp_blend_tool_push_status (GimpBlendTool *blend_tool,
/* gegl graph stuff */
+static GeglBuffer *
+gradient_precalc_shapeburst (GimpImage *image,
+ GimpDrawable *drawable,
+ const GeglRectangle *region,
+ gdouble dist,
+ GimpProgress *progress)
+{
+ GimpChannel *mask;
+ GeglBuffer *dist_buffer;
+ GeglBuffer *temp_buffer;
+ GeglNode *shapeburst;
+
+ //gimp_progress_set_text_literal (progress, _("Calculating distance map"));
+
+ /* allocate the distance map */
+ dist_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ region->width, region->height),
+ babl_format ("Y float"));
+
+ /* allocate the selection mask copy
+ */
+ temp_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ region->width, region->height),
+ babl_format ("Y float"));
+
+ mask = gimp_image_get_mask (image);
+
+ /* If the image mask is not empty, use it as the shape burst source */
+ if (! gimp_channel_is_empty (mask))
+ {
+ gint x, y, width, height;
+ gint off_x, off_y;
+
+ gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height);
+ gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+
+ /* copy the mask to the temp mask */
+ gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
+ GEGL_RECTANGLE (x + off_x, y + off_y, width, height),
+ temp_buffer,
+ GEGL_RECTANGLE (0, 0, 0, 0));
+ }
+ else
+ {
+ /* If the intended drawable has an alpha channel, use that */
+ if (gimp_drawable_has_alpha (drawable))
+ {
+ const Babl *component_format;
+
+ component_format = babl_format ("A float");
+
+ /* extract the aplha into the temp mask */
+ gegl_buffer_set_format (temp_buffer, component_format);
+ gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
+ GEGL_RECTANGLE (region->x, region->y,
+ region->width, region->height),
+ temp_buffer,
+ GEGL_RECTANGLE (0, 0, 0, 0));
+ gegl_buffer_set_format (temp_buffer, NULL);
+ }
+ else
+ {
+ GeglColor *white = gegl_color_new ("white");
+
+ /* Otherwise, just fill the shapeburst to white */
+ gegl_buffer_set_color (temp_buffer, NULL, white);
+ g_object_unref (white);
+ }
+ }
+
+ shapeburst = gegl_node_new_child (NULL,
+ "operation", "gegl:distance-transform",
+ "normalize", FALSE,
+ NULL);
+
+ //gimp_gegl_progress_connect (shapeburst, progress, NULL);
+
+ gimp_gegl_apply_operation (temp_buffer, NULL, NULL,
+ shapeburst,
+ dist_buffer, NULL);
+
+ g_object_unref (shapeburst);
+
+ g_object_unref (temp_buffer);
+
+ return dist_buffer;
+}
+
+
+
static void
gimp_blend_tool_create_graph (GimpBlendTool *blend_tool)
{
+ GimpTool *tool = GIMP_TOOL (blend_tool);
+
GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool);
GimpContext *context = GIMP_CONTEXT (options);
- GeglNode *graph, *output, *render;
+ GeglNode *graph, *output, *render, *shapeburst, *translate, *subtract, *divide;
+ GimpImage *image = gimp_display_get_image (tool->display);
+ GimpDrawable *drawable = gimp_image_get_active_drawable (image);
+ GeglBuffer *buf = NULL;
+
+ gint x, y, width, height;
+
+ if (! gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
+ return;
/* render_node is not supposed to be recreated */
g_return_if_fail (blend_tool->graph == NULL);
@@ -931,10 +1031,27 @@ gimp_blend_tool_create_graph (GimpBlendTool *blend_tool)
"operation", "gimp:blend",
NULL);
- gegl_node_link (render, output);
+ buf = gradient_precalc_shapeburst (image, drawable,
+ GEGL_RECTANGLE (0, 0, width, height), 0.0, NULL);
+
+ translate = gegl_node_new_child (graph, "operation", "gegl:translate",
+ "x", (gdouble) x, "y", (gdouble) y, NULL);
+
+ subtract = gegl_node_new_child (graph, "operation", "gegl:subtract", NULL);
+ divide = gegl_node_new_child (graph, "operation", "gegl:divide", NULL);
+
+ shapeburst = gegl_node_new_child (graph, "operation", "gegl:buffer-source",
+ "buffer", buf, NULL);
+
+ gegl_node_link_many (/*render*/shapeburst, translate, subtract, divide, output, NULL);
blend_tool->graph = graph;
blend_tool->render_node = render;
+ blend_tool->subtract_node = subtract;
+ blend_tool->divide_node = divide;
+ blend_tool->dist_buffer = buf;
+ blend_tool->dist_buffer_off_x = x;
+ blend_tool->dist_buffer_off_y = y;
gegl_node_set (render,
"context", context,
@@ -955,6 +1072,31 @@ gimp_blend_tool_update_preview_coords (GimpBlendTool *blend_tool)
"end_x", blend_tool->end_x - off_x,
"end_y", blend_tool->end_y - off_y,
NULL);
+
+ gfloat start, end;
+
+ gegl_buffer_get (blend_tool->dist_buffer,
+ GEGL_RECTANGLE (blend_tool->start_x - blend_tool->dist_buffer_off_x,
+ blend_tool->start_y - blend_tool->dist_buffer_off_y,
+ 1, 1),
+ 1.0, babl_format("Y float"), &start,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+ gegl_buffer_get (blend_tool->dist_buffer,
+ GEGL_RECTANGLE (blend_tool->end_x - blend_tool->dist_buffer_off_x,
+ blend_tool->end_y - blend_tool->dist_buffer_off_y,
+ 1, 1),
+ 1.0, babl_format("Y float"), &end,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+ if (start != end) {
+ gegl_node_set (blend_tool->subtract_node,
+ "value", (gdouble) start,
+ NULL);
+ gegl_node_set (blend_tool->divide_node,
+ "value", (gdouble) (end - start),
+ NULL);
+ }
}
static void
diff --git a/app/tools/gimpblendtool.h b/app/tools/gimpblendtool.h
index 0362b0b..0159491 100644
--- a/app/tools/gimpblendtool.h
+++ b/app/tools/gimpblendtool.h
@@ -68,6 +68,10 @@ struct _GimpBlendTool
GeglNode *graph;
GeglNode *render_node;
+ GeglNode *subtract_node;
+ GeglNode *divide_node;
+ GeglBuffer *dist_buffer;
+ gint dist_buffer_off_x, dist_buffer_off_y;
GimpImageMap *image_map;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]