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); }
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)); }
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); }
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)); }
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); } }
/* 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); } }
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); }
/* 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); } }
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); }