Esempio n. 1
0
void
gimp_gegl_progress_connect (GeglNode     *node,
                            GimpProgress *progress,
                            const gchar  *text)
{
  GObject *operation = NULL;

  g_return_if_fail (GEGL_IS_NODE (node));
  g_return_if_fail (GIMP_IS_PROGRESS (progress));

  g_object_get (node, "gegl-operation", &operation, NULL);

  g_return_if_fail (operation != NULL);

  g_signal_connect (operation, "notify::progress",
                    G_CALLBACK (gimp_gegl_progress_notify),
                    progress);

  if (text)
    g_object_set_data_full (operation,
                            "gimp-progress-text", g_strdup (text),
                            (GDestroyNotify) g_free);

  g_object_unref (operation);
}
Esempio n. 2
0
void
gimp_gegl_mode_node_set_mode (GeglNode             *node,
                              GimpLayerModeEffects  mode,
                              gboolean              linear)
{
  const gchar *operation = "gimp:normal-mode";
  gdouble      opacity;

  g_return_if_fail (GEGL_IS_NODE (node));

  switch (mode)
    {
    case GIMP_NORMAL_MODE:        operation = "gimp:normal-mode"; break;
    case GIMP_DISSOLVE_MODE:      operation = "gimp:dissolve-mode"; break;
    case GIMP_BEHIND_MODE:        operation = "gimp:behind-mode"; break;
    case GIMP_MULTIPLY_MODE:      operation = "gimp:multiply-mode"; break;
    case GIMP_SCREEN_MODE:        operation = "gimp:screen-mode"; break;
    case GIMP_OVERLAY_MODE:       operation = "gimp:softlight-mode"; break;
    case GIMP_DIFFERENCE_MODE:    operation = "gimp:difference-mode"; break;
    case GIMP_ADDITION_MODE:      operation = "gimp:addition-mode"; break;
    case GIMP_SUBTRACT_MODE:      operation = "gimp:subtract-mode"; break;
    case GIMP_DARKEN_ONLY_MODE:   operation = "gimp:darken-only-mode"; break;
    case GIMP_LIGHTEN_ONLY_MODE:  operation = "gimp:lighten-only-mode"; break;
    case GIMP_HUE_MODE:           operation = "gimp:hue-mode"; break;
    case GIMP_SATURATION_MODE:    operation = "gimp:saturation-mode"; break;
    case GIMP_COLOR_MODE:         operation = "gimp:color-mode"; break;
    case GIMP_VALUE_MODE:         operation = "gimp:value-mode"; break;
    case GIMP_DIVIDE_MODE:        operation = "gimp:divide-mode"; break;
    case GIMP_DODGE_MODE:         operation = "gimp:dodge-mode"; break;
    case GIMP_BURN_MODE:          operation = "gimp:burn-mode"; break;
    case GIMP_HARDLIGHT_MODE:     operation = "gimp:hardlight-mode"; break;
    case GIMP_SOFTLIGHT_MODE:     operation = "gimp:softlight-mode"; break;
    case GIMP_GRAIN_EXTRACT_MODE: operation = "gimp:grain-extract-mode"; break;
    case GIMP_GRAIN_MERGE_MODE:   operation = "gimp:grain-merge-mode"; break;
    case GIMP_COLOR_ERASE_MODE:   operation = "gimp:color-erase-mode"; break;
    case GIMP_NEW_OVERLAY_MODE:   operation = "gimp:overlay-mode"; break;
    case GIMP_ERASE_MODE:         operation = "gimp:erase-mode"; break;
    case GIMP_REPLACE_MODE:       operation = "gimp:replace-mode"; break;
    case GIMP_ANTI_ERASE_MODE:    operation = "gimp:anti-erase-mode"; break;
    case GIMP_LCH_HUE_MODE:       operation = "gimp:lch-hue-mode"; break;
    case GIMP_LCH_CHROMA_MODE:    operation = "gimp:lch-chroma-mode"; break;
    case GIMP_LCH_COLOR_MODE:     operation = "gimp:lch-color-mode"; break;
    case GIMP_LCH_LIGHTNESS_MODE: operation = "gimp:lch-lightness-mode"; break;
    default:
      break;
    }

  gegl_node_get (node,
                 "opacity", &opacity,
                 NULL);

  /* setting the operation creates a new instance, so we have to set
   * all its properties
   */
  gegl_node_set (node,
                 "operation", operation,
                 "linear",    linear,
                 "opacity",   opacity,
                 NULL);
}
Esempio n. 3
0
static void
dispose (GObject *gobject)
{
    GeglCache *self = GEGL_CACHE (gobject);

    while (g_idle_remove_by_data (gobject)) ;

    /* Check with GEGL_IS_NODE since sometimes the node is destroyed
     * before we get here
     */
    if (GEGL_IS_NODE (self->node))
    {
        gint handler = g_signal_handler_find (self->node, G_SIGNAL_MATCH_DATA,
                                              g_signal_lookup ("invalidated",
                                                      GEGL_TYPE_NODE),
                                              0, NULL, NULL, self);
        if (handler)
        {
            g_signal_handler_disconnect (self->node, handler);
        }
        self->node = NULL;
    }

    G_OBJECT_CLASS (gegl_cache_parent_class)->dispose (gobject);
}
Esempio n. 4
0
GeglNode *
gimp_gegl_add_buffer_source (GeglNode   *parent,
                             GeglBuffer *buffer,
                             gint        offset_x,
                             gint        offset_y)
{
  GeglNode *buffer_source;

  g_return_val_if_fail (GEGL_IS_NODE (parent), NULL);
  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);

  buffer_source = gegl_node_new_child (parent,
                                       "operation", "gegl:buffer-source",
                                       "buffer",    buffer,
                                       NULL);

  if (offset_x != 0 || offset_y != 0)
    {
      GeglNode *translate =
        gegl_node_new_child (parent,
                             "operation", "gegl:translate",
                             "x",         (gdouble) offset_x,
                             "y",         (gdouble) offset_y,
                             NULL);

      gegl_node_connect_to (buffer_source, "output",
                            translate,     "input");

      buffer_source = translate;
    }

  return buffer_source;
}
Esempio n. 5
0
void
gimp_drawable_apply_operation_to_tiles (GimpDrawable *drawable,
                                        GimpProgress *progress,
                                        const gchar  *undo_desc,
                                        GeglNode     *operation,
                                        gboolean      linear,
                                        TileManager  *new_tiles)
{
  GeglRectangle rect;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
  g_return_if_fail (undo_desc != NULL);
  g_return_if_fail (GEGL_IS_NODE (operation));
  g_return_if_fail (new_tiles != NULL);

  rect.x      = 0;
  rect.y      = 0;
  rect.width  = tile_manager_width  (new_tiles);
  rect.height = tile_manager_height (new_tiles);

  gimp_drawable_apply_operation_private (drawable,
                                         progress,
                                         undo_desc,
                                         operation,
                                         linear,
                                         new_tiles,
                                         &rect);

  if (progress)
    gimp_progress_end (progress);
}
Esempio n. 6
0
void
gimp_gegl_config_proxy_sync (GimpObject  *proxy,
                             GeglNode    *node)
{
  GParamSpec **pspecs;
  gchar       *operation;
  guint        n_pspecs;
  gint         i;

  g_return_if_fail (GIMP_IS_OBJECT (proxy));
  g_return_if_fail (GEGL_IS_NODE (node));

  gegl_node_get (node,
                 "operation", &operation,
                 NULL);

  g_return_if_fail (operation != NULL);

  pspecs = gegl_operation_list_properties (operation, &n_pspecs);
  g_free (operation);

  for (i = 0; i < n_pspecs; i++)
    {
      GParamSpec *gegl_pspec = pspecs[i];
      GParamSpec *gimp_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy),
                                                             gegl_pspec->name);

      if (gimp_pspec)
        {
          GValue value = { 0, };

          g_value_init (&value, gimp_pspec->value_type);

          g_object_get_property (G_OBJECT (proxy), gimp_pspec->name,
                                 &value);

          if (GEGL_IS_PARAM_SPEC_COLOR (gegl_pspec))
            {
              GimpRGB    gimp_color;
              GeglColor *gegl_color;

              gimp_value_get_rgb (&value, &gimp_color);
              g_value_unset (&value);

              gegl_color = gimp_gegl_color_new (&gimp_color);

              g_value_init (&value, gegl_pspec->value_type);
              g_value_take_object (&value, gegl_color);
            }

          gegl_node_set_property (node, gegl_pspec->name,
                                  &value);

          g_value_unset (&value);
        }
    }

  g_free (pspecs);
}
Esempio n. 7
0
void
gegl_pad_set_node (GeglPad  *self,
                   GeglNode *node)
{
  g_return_if_fail (GEGL_IS_PAD (self));
  g_return_if_fail (GEGL_IS_NODE (node));

  self->node = node;
}
Esempio n. 8
0
void
gimp_gegl_mode_node_set_opacity (GeglNode *node,
                                 gdouble   opacity)
{
  g_return_if_fail (GEGL_IS_NODE (node));

  gegl_node_set (node,
                 "opacity", opacity,
                 NULL);
}
GeglTileHandler *
gimp_tile_handler_projection_new (GeglNode *graph)
{
  GimpTileHandlerProjection *projection;

  g_return_val_if_fail (GEGL_IS_NODE (graph), NULL);

  projection = g_object_new (GIMP_TYPE_TILE_HANDLER_PROJECTION, NULL);

  projection->graph = g_object_ref (graph);

  return GEGL_TILE_HANDLER (projection);
}
Esempio n. 10
0
void
gegl_operation_attach (GeglOperation *self,
                       GeglNode      *node)
{
  GeglOperationClass *klass;

  g_return_if_fail (GEGL_IS_OPERATION (self));
  g_return_if_fail (GEGL_IS_NODE (node));

  klass = GEGL_OPERATION_GET_CLASS (self);

  g_assert (klass->attach);
  self->node = node;
  klass->attach (self);
}
Esempio n. 11
0
static void
gimp_warp_tool_remove_op (GimpWarpTool *wt,
                          GeglNode     *op)
{
  GeglNode *previous;

  g_return_if_fail (GEGL_IS_NODE (wt->render_node));

  previous = gegl_node_get_producer (op, "input", NULL);

  gegl_node_disconnect (op,              "input");
  gegl_node_connect_to (previous,        "output",
                        wt->render_node, "aux");

  gegl_node_remove_child (wt->graph, op);
}
Esempio n. 12
0
void
gimp_gegl_node_set_matrix (GeglNode          *node,
                           const GimpMatrix3 *matrix)
{
  gchar *matrix_string;

  g_return_if_fail (GEGL_IS_NODE (node));
  g_return_if_fail (matrix != NULL);

  matrix_string = gegl_matrix3_to_string ((GeglMatrix3 *) matrix);

  gegl_node_set (node,
                 "transform", matrix_string,
                 NULL);

  g_free (matrix_string);
}
Esempio n. 13
0
void
gimp_gegl_node_set_color (GeglNode      *node,
                          const GimpRGB *color)
{
  GeglColor *gegl_color;

  g_return_if_fail (GEGL_IS_NODE (node));
  g_return_if_fail (color != NULL);

  gegl_color = gimp_gegl_color_new (color);

  gegl_node_set (node,
                 "value", gegl_color,
                 NULL);

  g_object_unref (gegl_color);
}
Esempio n. 14
0
static void
gimp_warp_tool_add_op (GimpWarpTool *wt,
                       GeglNode     *new_op)
{
  GeglNode *last_op;

  g_return_if_fail (GEGL_IS_NODE (wt->render_node));

  gegl_node_add_child (wt->graph, new_op);

  last_op = gegl_node_get_producer (wt->render_node, "aux", NULL);

  gegl_node_disconnect (wt->render_node, "aux");
  gegl_node_connect_to (last_op,         "output",
                        new_op,          "input");
  gegl_node_connect_to (new_op,          "output",
                        wt->render_node, "aux");
}
void
gimp_brightness_contrast_config_set_node (GimpBrightnessContrastConfig *config,
                                          GeglNode                     *node)
{
  gdouble brightness;
  gdouble contrast;

  g_return_if_fail (GIMP_IS_BRIGHTNESS_CONTRAST_CONFIG (config));
  g_return_if_fail (GEGL_IS_NODE (node));

  brightness = config->brightness / 2.0;
  contrast   = (config->contrast < 0 ?
                (config->contrast + 1.0) :
                config->contrast * 4.0 + 1.0);

  gegl_node_set (node,
                 "brightness", brightness,
                 "contrast",   contrast,
                 NULL);
}
Esempio n. 16
0
void
gimp_drawable_apply_operation (GimpDrawable *drawable,
                               GimpProgress *progress,
                               const gchar  *undo_desc,
                               GeglNode     *operation,
                               gboolean      linear)
{
  GeglRectangle rect;

  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
  g_return_if_fail (undo_desc != NULL);
  g_return_if_fail (GEGL_IS_NODE (operation));

  if (! gimp_item_mask_intersect (GIMP_ITEM (drawable),
                                  &rect.x,     &rect.y,
                                  &rect.width, &rect.height))
    return;

  gimp_drawable_apply_operation_private (drawable,
                                         progress,
                                         undo_desc,
                                         operation,
                                         linear,
                                         gimp_drawable_get_shadow_tiles (drawable),
                                         &rect);

  gimp_drawable_merge_shadow_tiles (drawable, TRUE, undo_desc);
  gimp_drawable_free_shadow_tiles (drawable);

  gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height);

  if (progress)
    gimp_progress_end (progress);
}
Esempio n. 17
0
GimpApplicator *
gimp_applicator_new (GeglNode *parent,
                     gboolean  linear,
                     gboolean  use_split_preview,
                     gboolean  use_result_cache)
{
  GimpApplicator *applicator;

  g_return_val_if_fail (parent == NULL || GEGL_IS_NODE (parent), NULL);

  applicator = g_object_new (GIMP_TYPE_APPLICATOR, NULL);

  applicator->linear = linear;

  if (parent)
    applicator->node = g_object_ref (parent);
  else
    applicator->node = gegl_node_new ();

  applicator->input_node =
    gegl_node_get_input_proxy  (applicator->node, "input");

  applicator->aux_node =
    gegl_node_get_input_proxy  (applicator->node, "aux");

  applicator->output_node =
    gegl_node_get_output_proxy (applicator->node, "output");

  applicator->mode_node = gegl_node_new_child (applicator->node,
                                               "operation", "gimp:normal-mode",
                                               NULL);

  gimp_gegl_mode_node_set_mode (applicator->mode_node,
                                applicator->paint_mode,
                                applicator->linear);
  gimp_gegl_mode_node_set_opacity (applicator->mode_node,
                                   applicator->opacity);

  gegl_node_connect_to (applicator->input_node, "output",
                        applicator->mode_node,  "input");

  applicator->apply_offset_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:translate",
                         NULL);

  applicator->dup_apply_buffer_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:copy-buffer",
                         NULL);

  gegl_node_link_many (applicator->aux_node,
                       applicator->apply_offset_node,
                       applicator->dup_apply_buffer_node,
                       NULL);

  if (use_split_preview)
    {
      applicator->preview_cache_node =
        gegl_node_new_child (applicator->node,
                             "operation", "gegl:cache",
                             NULL);

      applicator->preview_crop_node =
        gegl_node_new_child (applicator->node,
                             "operation", "gegl:nop",
                             NULL);

      gegl_node_link_many (applicator->dup_apply_buffer_node,
                           applicator->preview_cache_node,
                           applicator->preview_crop_node,
                           NULL);
      gegl_node_connect_to (applicator->preview_crop_node, "output",
                            applicator->mode_node,         "aux");
    }
  else
    {
      gegl_node_connect_to (applicator->dup_apply_buffer_node, "output",
                            applicator->mode_node,             "aux");
    }

  applicator->mask_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:buffer-source",
                         NULL);

  applicator->mask_offset_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:translate",
                         NULL);

  gegl_node_connect_to (applicator->mask_node,        "output",
                        applicator->mask_offset_node, "input");
  /* don't connect the the mask offset node to mode's aux2 yet */

  applicator->affect_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gimp:mask-components",
                         "mask",      applicator->affect,
                         NULL);

  if (use_result_cache)
    {
      applicator->output_cache_node =
        gegl_node_new_child (applicator->node,
                             "operation", "gegl:cache",
                             NULL);

      gegl_node_link_many (applicator->input_node,
                           applicator->affect_node,
                           applicator->output_cache_node,
                           applicator->output_node,
                           NULL);
    }
  else
    {
      gegl_node_link_many (applicator->input_node,
                           applicator->affect_node,
                           applicator->output_node,
                           NULL);
    }

  gegl_node_connect_to (applicator->mode_node,   "output",
                        applicator->affect_node, "aux");

  return applicator;
}
Esempio n. 18
0
gboolean
gimp_gegl_apply_cached_operation (GeglBuffer          *src_buffer,
                                  GimpProgress        *progress,
                                  const gchar         *undo_desc,
                                  GeglNode            *operation,
                                  GeglBuffer          *dest_buffer,
                                  const GeglRectangle *dest_rect,
                                  GeglBuffer          *cache,
                                  const GeglRectangle *valid_rects,
                                  gint                 n_valid_rects,
                                  gboolean             cancellable)
{
  GeglNode      *gegl;
  GeglNode      *dest_node;
  GeglRectangle  rect = { 0, };
  GeglProcessor *processor        = NULL;
  gboolean       progress_started = FALSE;
  gdouble        value;
  gboolean       cancel           = FALSE;

  g_return_val_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer), FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (GEGL_IS_NODE (operation), FALSE);
  g_return_val_if_fail (GEGL_IS_BUFFER (dest_buffer), FALSE);
  g_return_val_if_fail (cache == NULL || GEGL_IS_BUFFER (cache), FALSE);
  g_return_val_if_fail (valid_rects == NULL || cache != NULL, FALSE);
  g_return_val_if_fail (valid_rects == NULL || n_valid_rects != 0, FALSE);

  if (dest_rect)
    {
      rect = *dest_rect;
    }
  else
    {
      rect = *GEGL_RECTANGLE (0, 0, gegl_buffer_get_width  (dest_buffer),
                                    gegl_buffer_get_height (dest_buffer));
    }

  gegl = gegl_node_new ();

  if (! gegl_node_get_parent (operation))
    gegl_node_add_child (gegl, operation);

  if (src_buffer && gegl_node_has_pad (operation, "input"))
    {
      GeglNode *src_node;

      /* dup() because reading and writing the same buffer doesn't
       * work with area ops when using a processor. See bug #701875.
       */
      if (progress && (src_buffer == dest_buffer))
        src_buffer = gegl_buffer_dup (src_buffer);
      else
        g_object_ref (src_buffer);

      src_node = gegl_node_new_child (gegl,
                                      "operation", "gegl:buffer-source",
                                      "buffer",    src_buffer,
                                      NULL);

      g_object_unref (src_buffer);

      gegl_node_connect_to (src_node,  "output",
                            operation, "input");
    }

  dest_node = gegl_node_new_child (gegl,
                                   "operation", "gegl:write-buffer",
                                   "buffer",    dest_buffer,
                                   NULL);

  gegl_node_connect_to (operation, "output",
                        dest_node, "input");

  if (progress)
    {
      processor = gegl_node_new_processor (dest_node, &rect);

      if (gimp_progress_is_active (progress))
        {
          if (undo_desc)
            gimp_progress_set_text_literal (progress, undo_desc);

          progress_started = FALSE;
          cancellable      = FALSE;
        }
      else
        {
          gimp_progress_start (progress, cancellable, "%s", undo_desc);

          if (cancellable)
            g_signal_connect (progress, "cancel",
                              G_CALLBACK (gimp_gegl_apply_operation_cancel),
                              &cancel);

          progress_started = TRUE;
        }
    }

  if (cache)
    {
      cairo_region_t *region;
      gint            all_pixels;
      gint            done_pixels = 0;
      gint            n_rects;
      gint            i;

      region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);

      all_pixels = rect.width * rect.height;

      for (i = 0; i < n_valid_rects; i++)
        {
          gegl_buffer_copy (cache,       valid_rects + i, GEGL_ABYSS_NONE,
                            dest_buffer, valid_rects + i);

          cairo_region_subtract_rectangle (region,
                                           (cairo_rectangle_int_t *)
                                           valid_rects + i);

          done_pixels += valid_rects[i].width * valid_rects[i].height;

          if (progress)
            gimp_progress_set_value (progress,
                                     (gdouble) done_pixels /
                                     (gdouble) all_pixels);
        }

      n_rects = cairo_region_num_rectangles (region);

      for (i = 0; ! cancel && (i < n_rects); i++)
        {
          cairo_rectangle_int_t render_rect;

          cairo_region_get_rectangle (region, i, &render_rect);

          if (progress)
            {
              gint rect_pixels = render_rect.width * render_rect.height;

#ifdef REUSE_PROCESSOR
              gegl_processor_set_rectangle (processor,
                                            (GeglRectangle *) &render_rect);
#else
              g_object_unref (processor);
              processor = gegl_node_new_processor (dest_node,
                                                   (GeglRectangle *) &render_rect);
#endif

              while (! cancel && gegl_processor_work (processor, &value))
                {
                  gimp_progress_set_value (progress,
                                           ((gdouble) done_pixels +
                                            value * rect_pixels) /
                                           (gdouble) all_pixels);

                  if (cancellable)
                    while (! cancel && g_main_context_pending (NULL))
                      g_main_context_iteration (NULL, FALSE);
                }

              done_pixels += rect_pixels;
            }
          else
            {
              gegl_node_blit (dest_node, 1.0, (GeglRectangle *) &render_rect,
                              NULL, NULL, 0, GEGL_BLIT_DEFAULT);
            }
        }

      cairo_region_destroy (region);
    }
  else
    {
      if (progress)
        {
          while (! cancel && gegl_processor_work (processor, &value))
            {
              gimp_progress_set_value (progress, value);

              if (cancellable)
                while (! cancel && g_main_context_pending (NULL))
                  g_main_context_iteration (NULL, FALSE);
            }
        }
      else
        {
          gegl_node_blit (dest_node, 1.0, &rect,
                          NULL, NULL, 0, GEGL_BLIT_DEFAULT);
        }
    }

  if (processor)
    g_object_unref (processor);

  g_object_unref (gegl);

  if (progress_started)
    {
      gimp_progress_end (progress);

      if (cancellable)
        g_signal_handlers_disconnect_by_func (progress,
                                              gimp_gegl_apply_operation_cancel,
                                              &cancel);
    }

  return ! cancel;
}
Esempio n. 19
0
GimpApplicator *
gimp_applicator_new (GeglNode *parent)
{
  GimpApplicator *applicator;

  g_return_val_if_fail (parent == NULL || GEGL_IS_NODE (parent), NULL);

  applicator = g_object_new (GIMP_TYPE_APPLICATOR, NULL);

  if (parent)
    applicator->node = g_object_ref (parent);
  else
    applicator->node = gegl_node_new ();

  applicator->input_node =
    gegl_node_get_input_proxy  (applicator->node, "input");

  applicator->aux_node =
    gegl_node_get_input_proxy  (applicator->node, "aux");

  applicator->output_node =
    gegl_node_get_output_proxy (applicator->node, "output");

  applicator->mode_node = gegl_node_new_child (applicator->node,
                                               "operation", "gimp:normal",
                                               NULL);

  gimp_gegl_mode_node_set_mode (applicator->mode_node,
                                applicator->paint_mode,
                                applicator->blend_space,
                                applicator->composite_space,
                                applicator->composite_mode);
  gimp_gegl_mode_node_set_opacity (applicator->mode_node,
                                   applicator->opacity);

  gegl_node_connect_to (applicator->input_node, "output",
                        applicator->mode_node,  "input");

  applicator->apply_offset_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:translate",
                         NULL);

  gegl_node_link_many (applicator->aux_node,
                       applicator->apply_offset_node,
                       NULL);

  gegl_node_connect_to (applicator->apply_offset_node, "output",
                        applicator->mode_node,         "aux");

  applicator->mask_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:buffer-source",
                         NULL);

  applicator->mask_offset_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:translate",
                         NULL);

  gegl_node_connect_to (applicator->mask_node,        "output",
                        applicator->mask_offset_node, "input");
  /* don't connect the the mask offset node to mode's aux2 yet */

  applicator->affect_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gimp:mask-components",
                         "mask",      applicator->affect,
                         NULL);

  applicator->convert_format_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:nop",
                         NULL);

  applicator->cache_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:nop",
                         NULL);

  applicator->crop_node =
    gegl_node_new_child (applicator->node,
                         "operation", "gegl:nop",
                         NULL);

  gegl_node_link_many (applicator->input_node,
                       applicator->affect_node,
                       applicator->convert_format_node,
                       applicator->cache_node,
                       applicator->crop_node,
                       applicator->output_node,
                       NULL);

  gegl_node_connect_to (applicator->mode_node,   "output",
                        applicator->affect_node, "aux");

  return applicator;
}
Esempio n. 20
0
void
gimp_gegl_apply_operation (GeglBuffer          *src_buffer,
                           GimpProgress        *progress,
                           const gchar         *undo_desc,
                           GeglNode            *operation,
                           GeglBuffer          *dest_buffer,
                           const GeglRectangle *dest_rect)
{
  GeglNode      *gegl;
  GeglNode      *dest_node;
  GeglRectangle  rect = { 0, };
  gdouble        value;
  gboolean       progress_active = FALSE;

  g_return_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
  g_return_if_fail (GEGL_IS_NODE (operation));
  g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));

  if (dest_rect)
    {
      rect = *dest_rect;
    }
  else
    {
      rect = *GEGL_RECTANGLE (0, 0, gegl_buffer_get_width  (dest_buffer),
                                    gegl_buffer_get_height (dest_buffer));
    }

  gegl = gegl_node_new ();

  if (! gegl_node_get_parent (operation))
    gegl_node_add_child (gegl, operation);

  if (src_buffer && gegl_node_has_pad (operation, "input"))
    {
      GeglNode *src_node;

      /* dup() because reading and writing the same buffer doesn't
       * work with area ops when using a processor. See bug #701875.
       */
      if (progress && (src_buffer == dest_buffer))
        src_buffer = gegl_buffer_dup (src_buffer);
      else
        g_object_ref (src_buffer);

      src_node = gegl_node_new_child (gegl,
                                      "operation", "gegl:buffer-source",
                                      "buffer",    src_buffer,
                                      NULL);

      g_object_unref (src_buffer);

      gegl_node_connect_to (src_node,  "output",
                            operation, "input");
    }

  dest_node = gegl_node_new_child (gegl,
                                   "operation", "gegl:write-buffer",
                                   "buffer",    dest_buffer,
                                   NULL);


  gegl_node_connect_to (operation, "output",
                        dest_node, "input");

  if (progress)
    {
      GeglProcessor *processor;

      processor = gegl_node_new_processor (dest_node, &rect);

      progress_active = gimp_progress_is_active (progress);

      if (progress_active)
        {
          if (undo_desc)
            gimp_progress_set_text (progress, undo_desc);
        }
      else
        {
          gimp_progress_start (progress, undo_desc, FALSE);
        }

      while (gegl_processor_work (processor, &value))
        gimp_progress_set_value (progress, value);

      g_object_unref (processor);
    }
  else
    {
      gegl_node_blit (dest_node, 1.0, &rect,
                      NULL, NULL, 0, GEGL_BLIT_DEFAULT);
    }

  g_object_unref (gegl);

  if (progress && ! progress_active)
    gimp_progress_end (progress);
}