예제 #1
0
static void
gimp_drawable_edit_fill_direct (GimpDrawable    *drawable,
                                GimpFillOptions *options,
                                const gchar     *undo_desc)
{
  GeglBuffer    *buffer;
  GimpContext   *context;
  GimpLayerMode  mode;
  gint           width;
  gint           height;

  buffer  = gimp_drawable_get_buffer (drawable);
  context = GIMP_CONTEXT (options);
  mode    = gimp_context_get_paint_mode (context);
  width   = gimp_item_get_width  (GIMP_ITEM (drawable));
  height  = gimp_item_get_height (GIMP_ITEM (drawable));

  gimp_drawable_push_undo (drawable, undo_desc,
                           NULL, 0, 0, width, height);

  if (! gimp_layer_mode_is_subtractive (mode))
    gimp_fill_options_fill_buffer (options, drawable, buffer, 0, 0);
  else
    gimp_gegl_clear (buffer, NULL);
}
예제 #2
0
void
gimp_paint_core_finish (GimpPaintCore *core,
                        GimpDrawable  *drawable,
                        gboolean       push_undo)
{
  GimpImage *image;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));

  if (core->stroke_buffer)
    {
      g_array_free (core->stroke_buffer, TRUE);
      core->stroke_buffer = NULL;
    }

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  /*  Determine if any part of the image has been altered--
   *  if nothing has, then just return...
   */
  if ((core->x2 == core->x1) || (core->y2 == core->y1))
    {
      gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
      return;
    }

  if (push_undo)
    {
      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT,
                                   core->undo_desc);

      GIMP_PAINT_CORE_GET_CLASS (core)->push_undo (core, image, NULL);

      gimp_drawable_push_undo (drawable, NULL,
                               core->x1, core->y1,
                               core->x2 - core->x1, core->y2 - core->y1,
                               core->undo_tiles,
                               TRUE);

      gimp_image_undo_group_end (image);
    }

  tile_manager_unref (core->undo_tiles);
  core->undo_tiles = NULL;

  if (core->saved_proj_tiles)
    {
      tile_manager_unref (core->saved_proj_tiles);
      core->saved_proj_tiles = NULL;
    }

  gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
}
static void
gimp_n_point_deformation_tool_apply_deformation (GimpNPointDeformationTool *npd_tool)
{
  GimpTool                     *tool = GIMP_TOOL (npd_tool);
  GimpNPointDeformationOptions *npd_options;
  GeglBuffer                   *buffer;
  GimpImage                    *image;
  gint                          width, height, prev;

  npd_options = GIMP_N_POINT_DEFORMATION_TOOL_GET_OPTIONS (npd_tool);

  image  = gimp_display_get_image (tool->display);
  buffer = gimp_drawable_get_buffer (tool->drawable);

  width  = gegl_buffer_get_width  (buffer);
  height = gegl_buffer_get_height (buffer);

  prev = npd_options->rigidity;
  npd_options->rigidity = 0;
  gimp_n_point_deformation_tool_set_options (npd_tool, npd_options);
  npd_options->rigidity = prev;

  gimp_drawable_push_undo (tool->drawable, _("N-Point Deformation"), NULL,
                           0, 0, width, height);


  gimp_gegl_apply_operation (NULL, NULL, _("N-Point Deformation"),
                             npd_tool->npd_node,
                             gimp_drawable_get_buffer (tool->drawable),
                             NULL);

  gimp_drawable_update (tool->drawable,
                        0, 0, width, height);

  gimp_projection_flush (gimp_image_get_projection (image));
}
예제 #4
0
static void
gimp_image_convert_profile_rgb (GimpImage                *image,
                                GimpColorProfile         *src_profile,
                                GimpColorProfile         *dest_profile,
                                GimpColorRenderingIntent  intent,
                                gboolean                  bpc,
                                GimpProgress             *progress)
{
  GList *layers;
  GList *list;
  gint   n_drawables;
  gint   nth_drawable;

  layers = gimp_image_get_layer_list (image);

  n_drawables = g_list_length (layers);

  for (list = layers, nth_drawable = 0;
       list;
       list = g_list_next (list), nth_drawable++)
    {
      GimpDrawable    *drawable = list->data;
      cmsHPROFILE      src_lcms;
      cmsHPROFILE      dest_lcms;
      const Babl      *iter_format;
      cmsUInt32Number  lcms_format;
      cmsUInt32Number  flags;
      cmsHTRANSFORM    transform;

      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        continue;

      src_lcms  = gimp_color_profile_get_lcms_profile (src_profile);
      dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile);

      iter_format =
        gimp_color_profile_get_format (gimp_drawable_get_format (drawable),
                                       &lcms_format);

      flags = cmsFLAGS_NOOPTIMIZE;

      if (bpc)
        flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;

      transform = cmsCreateTransform (src_lcms,  lcms_format,
                                      dest_lcms, lcms_format,
                                      intent, flags);

      if (transform)
        {
          GeglBuffer         *buffer;
          GeglBufferIterator *iter;

          buffer = gimp_drawable_get_buffer (drawable);

          gimp_drawable_push_undo (drawable, NULL, NULL,
                                   0, 0,
                                   gegl_buffer_get_width  (buffer),
                                   gegl_buffer_get_height (buffer));

          iter = gegl_buffer_iterator_new (buffer, NULL, 0,
                                           iter_format,
                                           GEGL_ACCESS_READWRITE,
                                           GEGL_ABYSS_NONE);

          while (gegl_buffer_iterator_next (iter))
            {
              cmsDoTransform (transform,
                              iter->data[0], iter->data[0], iter->length);
            }

          gimp_drawable_update (drawable, 0, 0,
                                gegl_buffer_get_width  (buffer),
                                gegl_buffer_get_height (buffer));

          cmsDeleteTransform (transform);
        }

      if (progress)
        gimp_progress_set_value (progress,
                                 (gdouble) nth_drawable / (gdouble) n_drawables);
    }

  g_list_free (layers);
}
예제 #5
0
void
gimp_paint_core_finish (GimpPaintCore *core,
                        GimpDrawable  *drawable,
                        gboolean       push_undo)
{
  GimpImage *image;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));

  if (core->applicator)
    {
      g_object_unref (core->applicator);
      core->applicator = NULL;
    }

  if (core->stroke_buffer)
    {
      g_array_free (core->stroke_buffer, TRUE);
      core->stroke_buffer = NULL;
    }

  if (core->mask_buffer)
    {
      g_object_unref (core->mask_buffer);
      core->mask_buffer = NULL;
    }

  if (core->comp_buffer)
    {
      g_object_unref (core->comp_buffer);
      core->comp_buffer = NULL;
    }

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  /*  Determine if any part of the image has been altered--
   *  if nothing has, then just return...
   */
  if ((core->x2 == core->x1) || (core->y2 == core->y1))
    {
      gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
      return;
    }

  if (push_undo)
    {
      GeglBuffer *buffer;
      gint        x, y, width, height;

      gimp_rectangle_intersect (core->x1, core->y1,
                                core->x2 - core->x1, core->y2 - core->y1,
                                0, 0,
                                gimp_item_get_width  (GIMP_ITEM (drawable)),
                                gimp_item_get_height (GIMP_ITEM (drawable)),
                                &x, &y, &width, &height);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT,
                                   core->undo_desc);

      GIMP_PAINT_CORE_GET_CLASS (core)->push_undo (core, image, NULL);

      buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
                                gimp_drawable_get_format (drawable));

      gegl_buffer_copy (core->undo_buffer,
                        GEGL_RECTANGLE (x, y, width, height),
                        buffer,
                        GEGL_RECTANGLE (0, 0, 0, 0));

      gimp_drawable_push_undo (drawable, NULL,
                               buffer, x, y, width, height);

      g_object_unref (buffer);

      gimp_image_undo_group_end (image);
    }

  g_object_unref (core->undo_buffer);
  core->undo_buffer = NULL;

  if (core->saved_proj_buffer)
    {
      g_object_unref (core->saved_proj_buffer);
      core->saved_proj_buffer = NULL;
    }

  gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable));
}
예제 #6
0
void
gimp_drawable_real_apply_region (GimpDrawable         *drawable,
                                 PixelRegion          *src2PR,
                                 gboolean              push_undo,
                                 const gchar          *undo_desc,
                                 gdouble               opacity,
                                 GimpLayerModeEffects  mode,
                                 TileManager          *src1_tiles,
                                 PixelRegion          *destPR,
                                 gint                  x,
                                 gint                  y)
{
  GimpItem        *item  = GIMP_ITEM (drawable);
  GimpImage       *image = gimp_item_get_image (item);
  GimpChannel     *mask  = gimp_image_get_mask (image);
  gint             x1, y1, x2, y2;
  gint             offset_x, offset_y;
  PixelRegion      src1PR, my_destPR;
  CombinationMode  operation;
  gboolean         active_components[MAX_CHANNELS];

  /*  don't apply the mask to itself and don't apply an empty mask  */
  if (GIMP_DRAWABLE (mask) == drawable || gimp_channel_is_empty (mask))
    mask = NULL;

  /*  configure the active channel array  */
  gimp_drawable_get_active_components (drawable, active_components);

  /*  determine what sort of operation is being attempted and
   *  if it's actually legal...
   */
  operation = gimp_image_get_combination_mode (gimp_drawable_type (drawable),
                                               src2PR->bytes);
  if (operation == -1)
    {
      g_warning ("%s: illegal parameters.", G_STRFUNC);
      return;
    }

  /*  get the layer offsets  */
  gimp_item_get_offset (item, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within drawable bounds  */
  x1 = CLAMP (x,             0, gimp_item_get_width  (item));
  y1 = CLAMP (y,             0, gimp_item_get_height (item));
  x2 = CLAMP (x + src2PR->w, 0, gimp_item_get_width  (item));
  y2 = CLAMP (y + src2PR->h, 0, gimp_item_get_height (item));

  if (mask)
    {
      GimpItem *mask_item = GIMP_ITEM (mask);

      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
      x1 = CLAMP (x1, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y1 = CLAMP (y1, -offset_y, gimp_item_get_height (mask_item) - offset_y);
      x2 = CLAMP (x2, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y2 = CLAMP (y2, -offset_y, gimp_item_get_height (mask_item) - offset_y);
    }

  /*  If the calling procedure specified an undo step...  */
  if (push_undo)
    {
      GimpDrawableUndo *undo;

      gimp_drawable_push_undo (drawable, undo_desc,
                               x1, y1,
                               x2 - x1, y2 - y1,
                               NULL, FALSE);

      undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));

      if (undo)
        {
          PixelRegion tmp_srcPR;
          PixelRegion tmp_destPR;

          undo->paint_mode = mode;
          undo->opacity    = opacity;
          undo->src2_tiles = tile_manager_new (x2 - x1, y2 - y1,
                                               src2PR->bytes);

          tmp_srcPR = *src2PR;
          pixel_region_resize (&tmp_srcPR,
                               src2PR->x + (x1 - x), src2PR->y + (y1 - y),
                               x2 - x1, y2 - y1);
          pixel_region_init (&tmp_destPR, undo->src2_tiles,
                             0, 0,
                             x2 - x1, y2 - y1, TRUE);

          copy_region (&tmp_srcPR, &tmp_destPR);
        }
    }

  /* configure the pixel regions */

  /* check if an alternative to using the drawable's data as src1 was
   * provided...
   */
  if (src1_tiles)
    {
      pixel_region_init (&src1PR, src1_tiles,
                         x1, y1, x2 - x1, y2 - y1,
                         FALSE);
    }
  else
    {
      pixel_region_init (&src1PR, gimp_drawable_get_tiles (drawable),
                         x1, y1, x2 - x1, y2 - y1,
                         FALSE);
    }

  /* check if an alternative to using the drawable's data as dest was
   * provided...
   */
  if (!destPR)
    {
      pixel_region_init (&my_destPR, gimp_drawable_get_tiles (drawable),
                         x1, y1, x2 - x1, y2 - y1,
                         TRUE);
      destPR = &my_destPR;
    }

  pixel_region_resize (src2PR,
                       src2PR->x + (x1 - x), src2PR->y + (y1 - y),
                       x2 - x1, y2 - y1);

  if (mask)
    {
      PixelRegion maskPR;

      pixel_region_init (&maskPR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
                         x1 + offset_x,
                         y1 + offset_y,
                         x2 - x1, y2 - y1,
                         FALSE);

      combine_regions (&src1PR, src2PR, destPR, &maskPR, NULL,
                       opacity * 255.999,
                       mode,
                       active_components,
                       operation);
    }
  else
    {
      combine_regions (&src1PR, src2PR, destPR, NULL, NULL,
                       opacity * 255.999,
                       mode,
                       active_components,
                       operation);
    }
}
예제 #7
0
/*  Similar to gimp_drawable_apply_region but works in "replace" mode (i.e.
 *  transparent pixels in src2 make the result transparent rather than
 *  opaque.
 *
 * Takes an additional mask pixel region as well.
 */
void
gimp_drawable_real_replace_region (GimpDrawable *drawable,
                                   PixelRegion  *src2PR,
                                   gboolean      push_undo,
                                   const gchar  *undo_desc,
                                   gdouble       opacity,
                                   PixelRegion  *maskPR,
                                   gint          x,
                                   gint          y)
{
  GimpItem        *item  = GIMP_ITEM (drawable);
  GimpImage       *image = gimp_item_get_image (item);
  GimpChannel     *mask  = gimp_image_get_mask (image);
  gint             x1, y1, x2, y2;
  gint             offset_x, offset_y;
  PixelRegion      src1PR, destPR;
  CombinationMode  operation;
  gboolean         active_components[MAX_CHANNELS];

  /*  don't apply the mask to itself and don't apply an empty mask  */
  if (GIMP_DRAWABLE (mask) == drawable || gimp_channel_is_empty (mask))
    mask = NULL;

  /*  configure the active channel array  */
  gimp_drawable_get_active_components (drawable, active_components);

  /*  determine what sort of operation is being attempted and
   *  if it's actually legal...
   */
  operation = gimp_image_get_combination_mode (gimp_drawable_type (drawable),
                                               src2PR->bytes);
  if (operation == -1)
    {
      g_warning ("%s: illegal parameters.", G_STRFUNC);
      return;
    }

  /*  get the layer offsets  */
  gimp_item_get_offset (item, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within drawable bounds  */
  x1 = CLAMP (x, 0,             gimp_item_get_width  (item));
  y1 = CLAMP (y, 0,             gimp_item_get_height (item));
  x2 = CLAMP (x + src2PR->w, 0, gimp_item_get_width  (item));
  y2 = CLAMP (y + src2PR->h, 0, gimp_item_get_height (item));

  if (mask)
    {
      GimpItem *mask_item = GIMP_ITEM (mask);

      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
      x1 = CLAMP (x1, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y1 = CLAMP (y1, -offset_y, gimp_item_get_height (mask_item) - offset_y);
      x2 = CLAMP (x2, -offset_x, gimp_item_get_width  (mask_item) - offset_x);
      y2 = CLAMP (y2, -offset_y, gimp_item_get_height (mask_item) - offset_y);
    }

  /*  If the calling procedure specified an undo step...  */
  if (push_undo)
    gimp_drawable_push_undo (drawable, undo_desc,
                             x1, y1,
                             x2 - x1, y2 - y1,
                             NULL, FALSE);

  /* configure the pixel regions */
  pixel_region_init (&src1PR, gimp_drawable_get_tiles (drawable),
                     x1, y1, x2 - x1, y2 - y1,
                     FALSE);
  pixel_region_init (&destPR, gimp_drawable_get_tiles (drawable),
                     x1, y1, x2 - x1, y2 - y1,
                     TRUE);
  pixel_region_resize (src2PR,
                       src2PR->x + (x1 - x), src2PR->y + (y1 - y),
                       x2 - x1, y2 - y1);

  if (mask)
    {
      PixelRegion  mask2PR, tempPR;
      guchar      *temp_data;

      pixel_region_init (&mask2PR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
                         x1 + offset_x,
                         y1 + offset_y,
                         x2 - x1, y2 - y1,
                         FALSE);

      temp_data = g_malloc ((y2 - y1) * (x2 - x1));

      pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
                              0, 0, x2 - x1, y2 - y1);

      copy_region (&mask2PR, &tempPR);

      pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
                              0, 0, x2 - x1, y2 - y1);

      apply_mask_to_region (&tempPR, maskPR, OPAQUE_OPACITY);

      pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
                              0, 0, x2 - x1, y2 - y1);

      combine_regions_replace (&src1PR, src2PR, &destPR, &tempPR, NULL,
                               opacity * 255.999,
                               active_components,
                               operation);

      g_free (temp_data);
    }
  else
    {
      combine_regions_replace (&src1PR, src2PR, &destPR, maskPR, NULL,
                               opacity * 255.999,
                               active_components,
                               operation);
    }
}
예제 #8
0
void
gimp_drawable_real_apply_buffer (GimpDrawable         *drawable,
                                 GeglBuffer           *buffer,
                                 const GeglRectangle  *buffer_region,
                                 gboolean              push_undo,
                                 const gchar          *undo_desc,
                                 gdouble               opacity,
                                 GimpLayerModeEffects  mode,
                                 GeglBuffer           *base_buffer,
                                 gint                  base_x,
                                 gint                  base_y)
{
  GimpItem          *item        = GIMP_ITEM (drawable);
  GimpImage         *image       = gimp_item_get_image (item);
  GimpChannel       *mask        = gimp_image_get_mask (image);
  GeglBuffer        *mask_buffer = NULL;
  GeglNode          *apply;
  GimpComponentMask  affect;
  gint               x, y, width, height;
  gint               offset_x, offset_y;

  /*  don't apply the mask to itself and don't apply an empty mask  */
  if (GIMP_DRAWABLE (mask) == drawable || gimp_channel_is_empty (mask))
    mask = NULL;

  if (! base_buffer)
    base_buffer = gimp_drawable_get_buffer (drawable);

  /*  get the layer offsets  */
  gimp_item_get_offset (item, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within drawable bounds  */
  gimp_rectangle_intersect (base_x, base_y,
                            buffer_region->width, buffer_region->height,
                            0, 0,
                            gimp_item_get_width  (item),
                            gimp_item_get_height (item),
                            &x, &y, &width, &height);

  if (mask)
    {
      GimpItem *mask_item = GIMP_ITEM (mask);

      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
      gimp_rectangle_intersect (x, y, width, height,
                                -offset_x, -offset_y,
                                gimp_item_get_width  (mask_item),
                                gimp_item_get_height (mask_item),
                                &x, &y, &width, &height);
    }

  if (push_undo)
    {
      GimpDrawableUndo *undo;

      gimp_drawable_push_undo (drawable, undo_desc,
                               NULL, x, y, width, height);

      undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image));

      if (undo)
        {
          undo->paint_mode = mode;
          undo->opacity    = opacity;

          undo->applied_buffer =
            gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
                             gegl_buffer_get_format (buffer));

          gegl_buffer_copy (buffer,
                            GEGL_RECTANGLE (buffer_region->x + (x - base_x),
                                            buffer_region->y + (y - base_y),
                                            width, height),
                            undo->applied_buffer,
                            GEGL_RECTANGLE (0, 0, width, height));
        }
    }

  if (mask)
    mask_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));

  affect = gimp_drawable_get_active_mask (drawable);

  apply = gimp_gegl_create_apply_buffer_node (buffer,
                                              base_x - buffer_region->x,
                                              base_y - buffer_region->y,
                                              0,
                                              0,
                                              0,
                                              0,
                                              mask_buffer,
                                              -offset_x,
                                              -offset_y,
                                              opacity,
                                              mode,
                                              affect);

  gimp_gegl_apply_operation (base_buffer, NULL, NULL,
                             apply,
                             gimp_drawable_get_buffer (drawable),
                             GEGL_RECTANGLE (x, y, width, height));

  g_object_unref (apply);
}
예제 #9
0
/*  Similar to gimp_drawable_apply_region but works in "replace" mode (i.e.
 *  transparent pixels in src2 make the result transparent rather than
 *  opaque.
 *
 * Takes an additional mask pixel region as well.
 */
void
gimp_drawable_real_replace_buffer (GimpDrawable        *drawable,
                                   GeglBuffer          *buffer,
                                   const GeglRectangle *buffer_region,
                                   gboolean             push_undo,
                                   const gchar         *undo_desc,
                                   gdouble              opacity,
                                   GeglBuffer          *mask_buffer,
                                   const GeglRectangle *mask_buffer_region,
                                   gint                 dest_x,
                                   gint                 dest_y)
{
  GimpItem        *item  = GIMP_ITEM (drawable);
  GimpImage       *image = gimp_item_get_image (item);
  GimpChannel     *mask  = gimp_image_get_mask (image);
  GeglBuffer      *drawable_buffer;
  gint             x, y, width, height;
  gint             offset_x, offset_y;
  gboolean         active_components[MAX_CHANNELS];

  /*  don't apply the mask to itself and don't apply an empty mask  */
  if (GIMP_DRAWABLE (mask) == drawable || gimp_channel_is_empty (mask))
    mask = NULL;

  /*  configure the active channel array  */
  gimp_drawable_get_active_components (drawable, active_components);

  /*  get the layer offsets  */
  gimp_item_get_offset (item, &offset_x, &offset_y);

  /*  make sure the image application coordinates are within drawable bounds  */
  gimp_rectangle_intersect (dest_x, dest_y,
                            buffer_region->width, buffer_region->height,
                            0, 0,
                            gimp_item_get_width  (item),
                            gimp_item_get_height (item),
                            &x, &y, &width, &height);

  if (mask)
    {
      GimpItem *mask_item = GIMP_ITEM (mask);

      /*  make sure coordinates are in mask bounds ...
       *  we need to add the layer offset to transform coords
       *  into the mask coordinate system
       */
      gimp_rectangle_intersect (x, y, width, height,
                                -offset_x, -offset_y,
                                gimp_item_get_width  (mask_item),
                                gimp_item_get_height (mask_item),
                                &x, &y, &width, &height);
    }

  /*  If the calling procedure specified an undo step...  */
  if (push_undo)
    gimp_drawable_push_undo (drawable, undo_desc,
                             NULL, x, y, width, height);

  drawable_buffer = gimp_drawable_get_buffer (drawable);

  if (mask)
    {
      GeglBuffer *src_buffer;
      GeglBuffer *dest_buffer;

      src_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));

      dest_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
                                     gegl_buffer_get_format (src_buffer));

      gegl_buffer_copy (src_buffer,
                        GEGL_RECTANGLE (x + offset_x, y + offset_y,
                                        width, height),
                        dest_buffer,
                        GEGL_RECTANGLE (0, 0, 0, 0));

      gimp_gegl_combine_mask (mask_buffer, mask_buffer_region,
                              dest_buffer, GEGL_RECTANGLE (0, 0, width, height),
                              1.0);

      gimp_gegl_replace (buffer,          buffer_region,
                         drawable_buffer, GEGL_RECTANGLE (x, y, width, height),
                         dest_buffer,     GEGL_RECTANGLE (0, 0, width, height),
                         drawable_buffer, GEGL_RECTANGLE (x, y, width, height),
                         opacity,
                         active_components);

      g_object_unref (dest_buffer);
    }
  else
    {
      gimp_gegl_replace (buffer,          buffer_region,
                         drawable_buffer, GEGL_RECTANGLE (x, y, width, height),
                         mask_buffer,     mask_buffer_region,
                         drawable_buffer, GEGL_RECTANGLE (x, y, width, height),
                         opacity,
                         active_components);
    }
}
예제 #10
0
static void
gimp_image_convert_profile_layers (GimpImage                *image,
                                   GimpColorProfile         *src_profile,
                                   GimpColorProfile         *dest_profile,
                                   GimpColorRenderingIntent  intent,
                                   gboolean                  bpc,
                                   GimpProgress             *progress)
{
  GList *layers;
  GList *list;
  gint   n_drawables  = 0;
  gint   nth_drawable = 0;

  layers = gimp_image_get_layer_list (image);

  for (list = layers; list; list = g_list_next (list))
    {
      if (! gimp_viewable_get_children (list->data))
        n_drawables++;
    }

  for (list = layers; list; list = g_list_next (list))
    {
      GimpDrawable *drawable     = list->data;
      GimpProgress *sub_progress = NULL;

      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        continue;

      if (progress)
        {
          sub_progress = gimp_sub_progress_new (progress);
          gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                      nth_drawable, n_drawables);
        }

      nth_drawable++;

      gimp_drawable_push_undo (drawable, NULL, NULL,
                               0, 0,
                               gimp_item_get_width  (GIMP_ITEM (drawable)),
                               gimp_item_get_height (GIMP_ITEM (drawable)));

      gimp_gegl_convert_color_profile (gimp_drawable_get_buffer (drawable),
                                       NULL,
                                       src_profile,
                                       gimp_drawable_get_buffer (drawable),
                                       NULL,
                                       dest_profile,
                                       intent, bpc,
                                       sub_progress);

      gimp_drawable_update (drawable, 0, 0,
                            gimp_item_get_width  (GIMP_ITEM (drawable)),
                            gimp_item_get_height (GIMP_ITEM (drawable)));

      if (sub_progress)
        g_object_unref (sub_progress);
    }

  g_list_free (layers);
}