[gimp/blend-tool-fun: 5/5] foo



commit f4c59334bd047501ead6b63352bc5804bcc891c8
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..471cc99 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, render, 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]