void gimp_channel_combine_mask (GimpChannel *mask, GimpChannel *add_on, GimpChannelOps op, gint off_x, gint off_y) { PixelRegion srcPR, destPR; gint x, y, w, h; g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GIMP_IS_CHANNEL (add_on)); if (! gimp_rectangle_intersect (off_x, off_y, gimp_item_get_width (GIMP_ITEM (add_on)), gimp_item_get_height (GIMP_ITEM (add_on)), 0, 0, gimp_item_get_width (GIMP_ITEM (mask)), gimp_item_get_height (GIMP_ITEM (mask)), &x, &y, &w, &h)) return; pixel_region_init (&srcPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (add_on)), x - off_x, y - off_y, w, h, FALSE); pixel_region_init (&destPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)), x, y, w, h, TRUE); switch (op) { case GIMP_CHANNEL_OP_ADD: case GIMP_CHANNEL_OP_REPLACE: pixel_regions_process_parallel ((PixelProcessorFunc) gimp_channel_combine_sub_region_add, NULL, 2, &srcPR, &destPR); break; case GIMP_CHANNEL_OP_SUBTRACT: pixel_regions_process_parallel ((PixelProcessorFunc) gimp_channel_combine_sub_region_sub, NULL, 2, &srcPR, &destPR); break; case GIMP_CHANNEL_OP_INTERSECT: pixel_regions_process_parallel ((PixelProcessorFunc) gimp_channel_combine_sub_region_intersect, NULL, 2, &srcPR, &destPR); break; default: g_warning ("%s: unknown operation type", G_STRFUNC); break; } mask->bounds_known = FALSE; gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h); }
void floating_sel_anchor (GimpLayer *layer) { GimpImage *image; GimpDrawable *drawable; GimpFilter *filter = NULL; gint off_x, off_y; gint dr_off_x, dr_off_y; g_return_if_fail (GIMP_IS_LAYER (layer)); g_return_if_fail (gimp_layer_is_floating_sel (layer)); /* Don't let gimp_image_remove_layer free the layer while we still need it */ g_object_ref (layer); image = gimp_item_get_image (GIMP_ITEM (layer)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_ANCHOR, C_("undo-type", "Anchor Floating Selection")); drawable = gimp_layer_get_floating_sel_drawable (layer); gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y); gimp_item_get_offset (GIMP_ITEM (drawable), &dr_off_x, &dr_off_y); if (gimp_item_get_visible (GIMP_ITEM (layer)) && gimp_rectangle_intersect (off_x, off_y, gimp_item_get_width (GIMP_ITEM (layer)), gimp_item_get_height (GIMP_ITEM (layer)), dr_off_x, dr_off_y, gimp_item_get_width (GIMP_ITEM (drawable)), gimp_item_get_height (GIMP_ITEM (drawable)), NULL, NULL, NULL, NULL)) { filter = gimp_drawable_get_floating_sel_filter (drawable); g_object_ref (filter); } /* first remove the filter, then merge it, or we will get warnings * about already connected nodes */ gimp_image_remove_layer (image, layer, TRUE, NULL); if (filter) { gimp_drawable_merge_filter (drawable, filter, NULL, NULL); g_object_unref (filter); } gimp_image_undo_group_end (image); /* invalidate the boundaries */ gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (gimp_image_get_mask (image))); g_object_unref (layer); }
void gimp_channel_combine_rect (GimpChannel *mask, GimpChannelOps op, gint x, gint y, gint w, gint h) { GeglBuffer *buffer; g_return_if_fail (GIMP_IS_CHANNEL (mask)); buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)); if (! gimp_gegl_mask_combine_rect (buffer, op, x, y, w, h)) return; gimp_rectangle_intersect (x, y, w, h, 0, 0, gimp_item_get_width (GIMP_ITEM (mask)), gimp_item_get_height (GIMP_ITEM (mask)), &x, &y, &w, &h); /* Determine new boundary */ if (mask->bounds_known && (op == GIMP_CHANNEL_OP_ADD) && ! mask->empty) { if (x < mask->x1) mask->x1 = x; if (y < mask->y1) mask->y1 = y; if ((x + w) > mask->x2) mask->x2 = (x + w); if ((y + h) > mask->y2) mask->y2 = (y + h); } else if (op == GIMP_CHANNEL_OP_REPLACE || mask->empty) { mask->empty = FALSE; mask->x1 = x; mask->y1 = y; mask->x2 = x + w; mask->y2 = y + h; } else { mask->bounds_known = FALSE; } mask->x1 = CLAMP (mask->x1, 0, gimp_item_get_width (GIMP_ITEM (mask))); mask->y1 = CLAMP (mask->y1, 0, gimp_item_get_height (GIMP_ITEM (mask))); mask->x2 = CLAMP (mask->x2, 0, gimp_item_get_width (GIMP_ITEM (mask))); mask->y2 = CLAMP (mask->y2, 0, gimp_item_get_height (GIMP_ITEM (mask))); gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h); }
static void gimp_image_map_tool_guide_moved (GimpGuide *guide, const GParamSpec *pspec, GimpImageMapTool *im_tool) { GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool); GimpItem *item = GIMP_ITEM (im_tool->drawable); gdouble position; if (options->preview_alignment == GIMP_ALIGN_LEFT || options->preview_alignment == GIMP_ALIGN_RIGHT) { position = ((gdouble) (gimp_guide_get_position (guide) - gimp_item_get_offset_x (item)) / (gdouble) gimp_item_get_width (item)); } else { position = ((gdouble) (gimp_guide_get_position (guide) - gimp_item_get_offset_y (item)) / (gdouble) gimp_item_get_height (item)); } g_object_set (options, "preview-position", CLAMP (position, 0.0, 1.0), NULL); }
/* * Position the dropped item in the middle of the viewport. */ static void gimp_display_shell_dnd_position_item (GimpDisplayShell *shell, GimpImage *image, GimpItem *item) { gint item_width = gimp_item_get_width (item); gint item_height = gimp_item_get_height (item); gint off_x, off_y; if (item_width >= gimp_image_get_width (image) && item_height >= gimp_image_get_height (image)) { off_x = (gimp_image_get_width (image) - item_width) / 2; off_y = (gimp_image_get_height (image) - item_height) / 2; } else { gint x, y; gint width, height; gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height); off_x = x + (width - item_width) / 2; off_y = y + (height - item_height) / 2; } gimp_item_translate (item, off_x - gimp_item_get_offset_x (item), off_y - gimp_item_get_offset_y (item), FALSE); }
static void gimp_cage_tool_image_map_update (GimpCageTool *ct) { GimpTool *tool = GIMP_TOOL (ct); GimpDisplayShell *shell = gimp_display_get_shell (tool->display); GimpItem *item = GIMP_ITEM (tool->drawable); gint x, y; gint w, h; gint off_x, off_y; GeglRectangle visible; gimp_display_shell_untransform_viewport (shell, &x, &y, &w, &h); gimp_item_get_offset (item, &off_x, &off_y); gimp_rectangle_intersect (x, y, w, h, off_x, off_y, gimp_item_get_width (item), gimp_item_get_height (item), &visible.x, &visible.y, &visible.width, &visible.height); visible.x -= off_x; visible.y -= off_y; gimp_image_map_apply (ct->image_map, &visible); }
void gimp_drawable_foreground_extract (GimpDrawable *drawable, GimpForegroundExtractMode mode, GimpDrawable *mask, GimpProgress *progress) { SioxState *state; const gdouble sensitivity[3] = { SIOX_DEFAULT_SENSITIVITY_L, SIOX_DEFAULT_SENSITIVITY_A, SIOX_DEFAULT_SENSITIVITY_B }; g_return_if_fail (GIMP_IS_DRAWABLE (mask)); g_return_if_fail (mode == GIMP_FOREGROUND_EXTRACT_SIOX); state = gimp_drawable_foreground_extract_siox_init (drawable, 0, 0, gimp_item_get_width (GIMP_ITEM (mask)), gimp_item_get_height (GIMP_ITEM (mask))); if (state) { gimp_drawable_foreground_extract_siox (mask, state, SIOX_REFINEMENT_RECALCULATE, SIOX_DEFAULT_SMOOTHNESS, sensitivity, FALSE, progress); gimp_drawable_foreground_extract_siox_done (state); } }
static void gimp_image_rotate_item_offset (GimpImage *image, GimpRotationType rotate_type, GimpItem *item, gint off_x, gint off_y) { gint x = 0; gint y = 0; switch (rotate_type) { case GIMP_ROTATE_90: x = gimp_image_get_height (image) - off_y - gimp_item_get_width (item); y = off_x; break; case GIMP_ROTATE_270: x = off_y; y = gimp_image_get_width (image) - off_x - gimp_item_get_height (item); break; case GIMP_ROTATE_180: return; } gimp_item_get_offset (item, &off_x, &off_y); x -= off_x; y -= off_y; if (x || y) gimp_item_translate (item, x, y, FALSE); }
static void gimp_tiling_update_strokes (GimpSymmetry *sym, GimpDrawable *drawable, GimpCoords *origin) { GimpTiling *tiling = GIMP_TILING (sym); GList *strokes = NULL; GimpCoords *coords; gint width; gint height; gint startx = origin->x; gint starty = origin->y; gint x; gint y; gint x_count; gint y_count; g_list_free_full (sym->strokes, g_free); sym->strokes = NULL; width = gimp_item_get_width (GIMP_ITEM (drawable)); height = gimp_item_get_height (GIMP_ITEM (drawable)); if (origin->x > 0 && tiling->max_x == 0) startx = origin->x - tiling->interval_x * (gint) (origin->x / tiling->interval_x + 1); if (origin->y > 0 && tiling->max_y == 0) { starty = origin->y - tiling->interval_y * (gint) (origin->y / tiling->interval_y + 1); if (tiling->shift > 0.0) startx -= tiling->shift * (gint) (origin->y / tiling->interval_y + 1); } for (y_count = 0, y = starty; y < height + tiling->interval_y; y_count++, y += tiling->interval_y) { if (tiling->max_y && y_count >= (gint) tiling->max_y) break; for (x_count = 0, x = startx; x < width + tiling->interval_x; x_count++, x += tiling->interval_x) { if (tiling->max_x && x_count >= (gint) tiling->max_x) break; coords = g_memdup (origin, sizeof (GimpCoords)); coords->x = x; coords->y = y; strokes = g_list_prepend (strokes, coords); if (tiling->interval_x < 1.0) break; } if (tiling->max_x || startx + tiling->shift <= 0.0) startx = startx + tiling->shift; else startx = startx - tiling->interval_x + tiling->shift; if (tiling->interval_y < 1.0) break; } sym->strokes = strokes; g_signal_emit_by_name (sym, "strokes-updated", sym->image); }
static void gimp_text_layer_render_layout (GimpTextLayer *layer, GimpTextLayout *layout) { GimpDrawable *drawable = GIMP_DRAWABLE (layer); GimpItem *item = GIMP_ITEM (layer); GeglBuffer *buffer; cairo_t *cr; cairo_surface_t *surface; gint width; gint height; g_return_if_fail (gimp_drawable_has_alpha (drawable)); width = gimp_item_get_width (item); height = gimp_item_get_height (item); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE); cairo_destroy (cr); cairo_surface_flush (surface); buffer = gimp_cairo_surface_create_buffer (surface); gegl_buffer_copy (buffer, NULL, gimp_drawable_get_buffer (drawable), NULL); g_object_unref (buffer); cairo_surface_destroy (surface); gimp_drawable_update (drawable, 0, 0, width, height); }
static void gimp_channel_combine_clear_complement (GimpChannel *mask, const GeglRectangle *rect) { gint width = gimp_item_get_width (GIMP_ITEM (mask)); gint height = gimp_item_get_height (GIMP_ITEM (mask)); gimp_channel_combine_clear ( mask, GEGL_RECTANGLE (0, 0, width, rect->y)); gimp_channel_combine_clear ( mask, GEGL_RECTANGLE (0, rect->y + rect->height, width, height - (rect->y + rect->height))); gimp_channel_combine_clear ( mask, GEGL_RECTANGLE (0, rect->y, rect->x, rect->height)); gimp_channel_combine_clear ( mask, GEGL_RECTANGLE (rect->x + rect->width, rect->y, width - (rect->x + rect->width), rect->height)); }
static TempBuf * gimp_ink_get_paint_area (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, const GimpCoords *coords) { GimpInk *ink = GIMP_INK (paint_core); gint x, y; gint width, height; gint dwidth, dheight; gint x1, y1, x2, y2; gint bytes; bytes = gimp_drawable_bytes_with_alpha (drawable); gimp_blob_bounds (ink->cur_blob, &x, &y, &width, &height); dwidth = gimp_item_get_width (GIMP_ITEM (drawable)); dheight = gimp_item_get_height (GIMP_ITEM (drawable)); x1 = CLAMP (x / SUBSAMPLE - 1, 0, dwidth); y1 = CLAMP (y / SUBSAMPLE - 1, 0, dheight); x2 = CLAMP ((x + width) / SUBSAMPLE + 2, 0, dwidth); y2 = CLAMP ((y + height) / SUBSAMPLE + 2, 0, dheight); /* configure the canvas buffer */ if ((x2 - x1) && (y2 - y1)) paint_core->canvas_buf = temp_buf_resize (paint_core->canvas_buf, bytes, x1, y1, (x2 - x1), (y2 - y1)); else return NULL; return paint_core->canvas_buf; }
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_channel_combine_buffer (GimpChannel *mask, GeglBuffer *add_on_buffer, GimpChannelOps op, gint off_x, gint off_y) { GeglBuffer *buffer; gint x, y, w, h; g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GEGL_IS_BUFFER (add_on_buffer)); buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)); if (! gimp_gegl_mask_combine_buffer (buffer, add_on_buffer, op, off_x, off_y)) return; gimp_rectangle_intersect (off_x, off_y, gegl_buffer_get_width (add_on_buffer), gegl_buffer_get_height (add_on_buffer), 0, 0, gimp_item_get_width (GIMP_ITEM (mask)), gimp_item_get_height (GIMP_ITEM (mask)), &x, &y, &w, &h); mask->bounds_known = FALSE; gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h); }
static BoundSeg * gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel, GimpDisplay *display, gint *n_segs) { GimpDisplayShell *shell = gimp_display_get_shell (display); BoundSeg *segs; PixelRegion maskPR; gimp_display_shell_set_override_cursor (shell, GDK_WATCH); if (region_sel->region_mask) g_object_unref (region_sel->region_mask); region_sel->region_mask = GIMP_REGION_SELECT_TOOL_GET_CLASS (region_sel)->get_mask (region_sel, display); if (! region_sel->region_mask) { gimp_display_shell_unset_override_cursor (shell); *n_segs = 0; return NULL; } /* calculate and allocate a new segment array which represents the * boundary of the contiguous region */ pixel_region_init (&maskPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (region_sel->region_mask)), 0, 0, gimp_item_get_width (GIMP_ITEM (region_sel->region_mask)), gimp_item_get_height (GIMP_ITEM (region_sel->region_mask)), FALSE); segs = boundary_find (&maskPR, BOUNDARY_WITHIN_BOUNDS, 0, 0, gimp_item_get_width (GIMP_ITEM (region_sel->region_mask)), gimp_item_get_height (GIMP_ITEM (region_sel->region_mask)), BOUNDARY_HALF_WAY, n_segs); gimp_display_shell_unset_override_cursor (shell); return segs; }
void gimp_image_resize_to_layers (GimpImage *image, GimpContext *context, GimpProgress *progress) { GList *list; GimpItem *item; gint x, y; gint width, height; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); list = gimp_image_get_layer_iter (image); if (! list) return; /* figure out starting values */ item = list->data; x = gimp_item_get_offset_x (item); y = gimp_item_get_offset_y (item); width = gimp_item_get_width (item); height = gimp_item_get_height (item); /* Respect all layers */ for (list = g_list_next (list); list; list = g_list_next (list)) { item = list->data; gimp_rectangle_union (x, y, width, height, gimp_item_get_offset_x (item), gimp_item_get_offset_y (item), gimp_item_get_width (item), gimp_item_get_height (item), &x, &y, &width, &height); } gimp_image_resize (image, context, width, height, -x, -y, progress); }
gboolean gimp_item_get_popup_size (GimpViewable *viewable, gint width, gint height, gboolean dot_for_dot, gint *popup_width, gint *popup_height) { GimpItem *item = GIMP_ITEM (viewable); GimpImage *image = gimp_item_get_image (item); if (image && ! image->gimp->config->layer_previews) return FALSE; if (gimp_item_get_width (item) > width || gimp_item_get_height (item) > height) { gboolean scaling_up; gdouble xres = 1.0; gdouble yres = 1.0; if (image) gimp_image_get_resolution (image, &xres, &yres); gimp_viewable_calc_preview_size (gimp_item_get_width (item), gimp_item_get_height (item), width * 2, height * 2, dot_for_dot, xres, yres, popup_width, popup_height, &scaling_up); if (scaling_up) { *popup_width = gimp_item_get_width (item); *popup_height = gimp_item_get_height (item); } return TRUE; } return FALSE; }
void gimp_channel_select_round_rect (GimpChannel *channel, gint x, gint y, gint w, gint h, gdouble corner_radius_x, gdouble corner_radius_y, GimpChannelOps op, gboolean antialias, gboolean feather, gdouble feather_radius_x, gdouble feather_radius_y, gboolean push_undo) { g_return_if_fail (GIMP_IS_CHANNEL (channel)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel))); if (push_undo) gimp_channel_push_undo (channel, C_("undo-type", "Rounded Rectangle Select")); /* if applicable, replace the current selection */ if (op == GIMP_CHANNEL_OP_REPLACE) gimp_channel_clear (channel, NULL, FALSE); /* if feathering for rect, make a new mask with the * rectangle and feather that with the old mask */ if (feather || op == GIMP_CHANNEL_OP_INTERSECT) { GimpItem *item = GIMP_ITEM (channel); GeglBuffer *add_on; add_on = gegl_buffer_new (GEGL_RECTANGLE (0, 0, gimp_item_get_width (item), gimp_item_get_height (item)), babl_format ("Y float")); gimp_gegl_mask_combine_ellipse_rect (add_on, GIMP_CHANNEL_OP_ADD, x, y, w, h, corner_radius_x, corner_radius_y, antialias); if (feather) gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL, feather_radius_x, feather_radius_y); gimp_channel_combine_buffer (channel, add_on, op, 0, 0); g_object_unref (add_on); } else { gimp_channel_combine_ellipse_rect (channel, op, x, y, w, h, corner_radius_x, corner_radius_y, antialias); } }
/** * gimp_projection_initialize: * @proj: A #GimpProjection. * @x: * @y: * @w: * @h: * * This function determines whether a visible layer with combine mode * Normal provides complete coverage over the specified area. If not, * the projection is initialized to transparent black. */ static void gimp_projection_initialize (GimpProjection *proj, gint x, gint y, gint w, gint h) { GList *list; gint proj_off_x; gint proj_off_y; gboolean coverage = FALSE; gimp_projectable_get_offset (proj->projectable, &proj_off_x, &proj_off_y); for (list = gimp_projectable_get_layers (proj->projectable); list; list = g_list_next (list)) { GimpLayer *layer = list->data; GimpDrawable *drawable = GIMP_DRAWABLE (layer); GimpItem *item = GIMP_ITEM (layer); gint off_x, off_y; gimp_item_get_offset (item, &off_x, &off_y); /* subtract the projectable's offsets because the list of * update areas is in tile-pyramid coordinates, but our * external API is always in terms of image coordinates. */ off_x -= proj_off_x; off_y -= proj_off_y; if (gimp_item_get_visible (item) && ! gimp_drawable_has_alpha (drawable) && ! gimp_layer_get_mask (layer) && gimp_layer_get_mode (layer) == GIMP_NORMAL_MODE && gimp_layer_get_opacity (layer) == GIMP_OPACITY_OPAQUE && off_x <= x && off_y <= y && (off_x + gimp_item_get_width (item)) >= (x + w) && (off_y + gimp_item_get_height (item)) >= (y + h)) { coverage = TRUE; break; } } if (! coverage) { PixelRegion region; pixel_region_init (®ion, gimp_pickable_get_tiles (GIMP_PICKABLE (proj)), x, y, w, h, TRUE); clear_region (®ion); } }
GimpTempBuf * gimp_drawable_get_sub_preview (GimpDrawable *drawable, gint src_x, gint src_y, gint src_width, gint src_height, gint dest_width, gint dest_height) { GimpItem *item; GimpImage *image; GeglBuffer *buffer; GimpTempBuf *preview; gdouble scale; gint scaled_x; gint scaled_y; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (src_x >= 0, NULL); g_return_val_if_fail (src_y >= 0, NULL); g_return_val_if_fail (src_width > 0, NULL); g_return_val_if_fail (src_height > 0, NULL); g_return_val_if_fail (dest_width > 0, NULL); g_return_val_if_fail (dest_height > 0, NULL); item = GIMP_ITEM (drawable); g_return_val_if_fail ((src_x + src_width) <= gimp_item_get_width (item), NULL); g_return_val_if_fail ((src_y + src_height) <= gimp_item_get_height (item), NULL); image = gimp_item_get_image (item); if (! image->gimp->config->layer_previews) return NULL; buffer = gimp_drawable_get_buffer (drawable); preview = gimp_temp_buf_new (dest_width, dest_height, gimp_drawable_get_preview_format (drawable)); scale = MIN ((gdouble) dest_width / (gdouble) src_width, (gdouble) dest_height / (gdouble) src_height); scaled_x = RINT ((gdouble) src_x * scale); scaled_y = RINT ((gdouble) src_y * scale); gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, dest_width, dest_height), scale, gimp_temp_buf_get_format (preview), gimp_temp_buf_get_data (preview), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); return preview; }
static GeglBuffer * gimp_ink_get_paint_buffer (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, const GimpCoords *coords, gint *paint_buffer_x, gint *paint_buffer_y) { GimpInk *ink = GIMP_INK (paint_core); gint x, y; gint width, height; gint dwidth, dheight; gint x1, y1, x2, y2; gimp_blob_bounds (ink->cur_blob, &x, &y, &width, &height); dwidth = gimp_item_get_width (GIMP_ITEM (drawable)); dheight = gimp_item_get_height (GIMP_ITEM (drawable)); x1 = CLAMP (x / SUBSAMPLE - 1, 0, dwidth); y1 = CLAMP (y / SUBSAMPLE - 1, 0, dheight); x2 = CLAMP ((x + width) / SUBSAMPLE + 2, 0, dwidth); y2 = CLAMP ((y + height) / SUBSAMPLE + 2, 0, dheight); /* configure the canvas buffer */ if ((x2 - x1) && (y2 - y1)) { GimpTempBuf *temp_buf; const Babl *format; if (gimp_drawable_get_linear (drawable)) format = babl_format ("RGBA float"); else format = babl_format ("R'G'B'A float"); temp_buf = gimp_temp_buf_new ((x2 - x1), (y2 - y1), format); *paint_buffer_x = x1; *paint_buffer_y = y1; if (paint_core->paint_buffer) g_object_unref (paint_core->paint_buffer); paint_core->paint_buffer = gimp_temp_buf_create_buffer (temp_buf); gimp_temp_buf_unref (temp_buf); return paint_core->paint_buffer; } return NULL; }
gboolean floating_sel_to_layer (GimpLayer *layer, GError **error) { GimpItem *item; GimpImage *image; g_return_val_if_fail (GIMP_IS_LAYER (layer), FALSE); g_return_val_if_fail (gimp_layer_is_floating_sel (layer), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); item = GIMP_ITEM (layer); image = gimp_item_get_image (item); /* Check if the floating layer belongs to a channel */ if (GIMP_IS_CHANNEL (gimp_layer_get_floating_sel_drawable (layer))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot create a new layer from the floating " "selection because it belongs to a layer mask " "or channel.")); return FALSE; } gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_TO_LAYER, C_("undo-type", "Floating Selection to Layer")); gimp_image_undo_push_fs_to_layer (image, NULL, layer); gimp_drawable_detach_floating_sel (gimp_layer_get_floating_sel_drawable (layer)); gimp_layer_set_floating_sel_drawable (layer, NULL); gimp_item_set_visible (item, TRUE, TRUE); gimp_layer_set_lock_alpha (layer, FALSE, TRUE); gimp_image_undo_group_end (image); /* When the floating selection is converted to/from a normal layer * it does something resembling a name change, so emit the * "name-changed" signal */ gimp_object_name_changed (GIMP_OBJECT (layer)); gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, gimp_item_get_width (item), gimp_item_get_height (item)); return TRUE; }
static void offset_half_y_callback (GtkWidget *widget, OffsetDialog *dialog) { GimpImage *image = dialog->image; if (image) { GimpItem *item = GIMP_ITEM (gimp_image_get_active_drawable (image)); gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (dialog->off_se), 1, gimp_item_get_height (item) / 2); } }
void gimp_channel_select_buffer (GimpChannel *channel, const gchar *undo_desc, GeglBuffer *add_on, gint offset_x, gint offset_y, GimpChannelOps op, gboolean feather, gdouble feather_radius_x, gdouble feather_radius_y) { g_return_if_fail (GIMP_IS_CHANNEL (channel)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel))); g_return_if_fail (undo_desc != NULL); g_return_if_fail (GEGL_IS_BUFFER (add_on)); gimp_channel_push_undo (channel, undo_desc); /* if applicable, replace the current selection */ if (op == GIMP_CHANNEL_OP_REPLACE) gimp_channel_clear (channel, NULL, FALSE); if (feather || op == GIMP_CHANNEL_OP_INTERSECT) { GimpItem *item = GIMP_ITEM (channel); GeglBuffer *add_on2; add_on2 = gegl_buffer_new (GEGL_RECTANGLE (0, 0, gimp_item_get_width (item), gimp_item_get_height (item)), babl_format ("Y float")); gimp_gegl_mask_combine_buffer (add_on2, add_on, GIMP_CHANNEL_OP_ADD, offset_x, offset_y); if (feather) gimp_gegl_apply_feather (add_on2, NULL, NULL, add_on2, NULL, feather_radius_x, feather_radius_y); gimp_channel_combine_buffer (channel, add_on2, op, 0, 0); g_object_unref (add_on2); } else { gimp_channel_combine_buffer (channel, add_on, op, offset_x, offset_y); } }
void gimp_drawable_foreground_extract_siox (GimpDrawable *mask, SioxState *state, SioxRefinementType refinement, gint smoothness, const gdouble sensitivity[3], gboolean multiblob, GimpProgress *progress) { GeglBuffer *buffer; gint x1, y1; gint x2, y2; g_return_if_fail (GIMP_IS_DRAWABLE (mask)); g_return_if_fail (babl_format_get_bytes_per_pixel (gimp_drawable_get_format (mask)) == 1); g_return_if_fail (state != NULL); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); if (progress) gimp_progress_start (progress, _("Foreground Extraction"), FALSE); if (GIMP_IS_CHANNEL (mask)) { gimp_channel_bounds (GIMP_CHANNEL (mask), &x1, &y1, &x2, &y2); } else { x1 = 0; y1 = 0; x2 = gimp_item_get_width (GIMP_ITEM (mask)); y2 = gimp_item_get_height (GIMP_ITEM (mask)); } buffer = gimp_drawable_get_buffer (mask); siox_foreground_extract (state, refinement, gimp_gegl_buffer_get_tiles (buffer), x1, y1, x2, y2, smoothness, sensitivity, multiblob, (SioxProgressFunc) gimp_progress_set_value, progress); if (progress) gimp_progress_end (progress); gimp_drawable_update (mask, x1, y1, x2, y2); }
void gimp_item_get_preview_size (GimpViewable *viewable, gint size, gboolean is_popup, gboolean dot_for_dot, gint *width, gint *height) { GimpItem *item = GIMP_ITEM (viewable); GimpImage *image = gimp_item_get_image (item); if (image && ! image->gimp->config->layer_previews && ! is_popup) { *width = size; *height = size; return; } if (image && ! is_popup) { gdouble xres; gdouble yres; gimp_image_get_resolution (image, &xres, &yres); gimp_viewable_calc_preview_size (gimp_image_get_width (image), gimp_image_get_height (image), size, size, dot_for_dot, xres, yres, width, height, NULL); } else { gimp_viewable_calc_preview_size (gimp_item_get_width (item), gimp_item_get_height (item), size, size, dot_for_dot, 1.0, 1.0, width, height, NULL); } }
static void gimp_floating_sel_undo_pop (GimpUndo *undo, GimpUndoMode undo_mode, GimpUndoAccumulator *accum) { GimpFloatingSelUndo *floating_sel_undo = GIMP_FLOATING_SEL_UNDO (undo); GimpLayer *floating_layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item); GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum); switch (undo->undo_type) { case GIMP_UNDO_FS_TO_LAYER: if (undo_mode == GIMP_UNDO_MODE_UNDO) { /* Update the preview for the floating sel */ gimp_viewable_invalidate_preview (GIMP_VIEWABLE (floating_layer)); gimp_layer_set_floating_sel_drawable (floating_layer, floating_sel_undo->drawable); gimp_image_set_active_layer (undo->image, floating_layer); gimp_drawable_attach_floating_sel (gimp_layer_get_floating_sel_drawable (floating_layer), floating_layer); } else { gimp_drawable_detach_floating_sel (gimp_layer_get_floating_sel_drawable (floating_layer)); gimp_layer_set_floating_sel_drawable (floating_layer, NULL); } /* When the floating selection is converted to/from a normal * layer it does something resembling a name change, so emit the * "name-changed" signal */ gimp_object_name_changed (GIMP_OBJECT (floating_layer)); gimp_drawable_update (GIMP_DRAWABLE (floating_layer), 0, 0, gimp_item_get_width (GIMP_ITEM (floating_layer)), gimp_item_get_height (GIMP_ITEM (floating_layer))); break; default: g_assert_not_reached (); } }
void gimp_channel_select_scan_convert (GimpChannel *channel, const gchar *undo_desc, GimpScanConvert *scan_convert, gint offset_x, gint offset_y, GimpChannelOps op, gboolean antialias, gboolean feather, gdouble feather_radius_x, gdouble feather_radius_y, gboolean push_undo) { GimpItem *item; GeglBuffer *add_on; g_return_if_fail (GIMP_IS_CHANNEL (channel)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel))); g_return_if_fail (undo_desc != NULL); g_return_if_fail (scan_convert != NULL); if (push_undo) gimp_channel_push_undo (channel, undo_desc); /* if applicable, replace the current selection */ if (op == GIMP_CHANNEL_OP_REPLACE) gimp_channel_clear (channel, NULL, FALSE); item = GIMP_ITEM (channel); add_on = gegl_buffer_new (GEGL_RECTANGLE (0, 0, gimp_item_get_width (item), gimp_item_get_height (item)), babl_format ("Y float")); gimp_scan_convert_render (scan_convert, add_on, offset_x, offset_y, antialias); if (feather) gimp_gegl_apply_feather (add_on, NULL, NULL, add_on, NULL, feather_radius_x, feather_radius_y); gimp_channel_combine_buffer (channel, add_on, op, 0, 0); g_object_unref (add_on); }
static void gimp_image_map_tool_add_guide (GimpImageMapTool *im_tool) { GimpImageMapOptions *options = GIMP_IMAGE_MAP_TOOL_GET_OPTIONS (im_tool); GimpItem *item; GimpImage *image; GimpOrientationType orientation; gint position; if (im_tool->percent_guide) return; item = GIMP_ITEM (im_tool->drawable); image = gimp_item_get_image (item); if (options->preview_alignment == GIMP_ALIGN_LEFT || options->preview_alignment == GIMP_ALIGN_RIGHT) { orientation = GIMP_ORIENTATION_VERTICAL; position = (gimp_item_get_offset_x (item) + gimp_item_get_width (item) * options->preview_position); } else { orientation = GIMP_ORIENTATION_HORIZONTAL; position = (gimp_item_get_offset_y (item) + gimp_item_get_height (item) * options->preview_position); } im_tool->percent_guide = gimp_guide_custom_new (orientation, image->gimp->next_guide_ID++, GIMP_GUIDE_STYLE_SPLIT_VIEW); gimp_image_add_guide (image, im_tool->percent_guide, position); g_signal_connect (im_tool->percent_guide, "removed", G_CALLBACK (gimp_image_map_tool_guide_removed), im_tool); g_signal_connect (im_tool->percent_guide, "notify::position", G_CALLBACK (gimp_image_map_tool_guide_moved), im_tool); }
/* * Position the dropped item in the middle of the viewport. */ static void gimp_display_shell_dnd_position_item (GimpDisplayShell *shell, GimpItem *item) { gint x, y; gint width, height; gint off_x, off_y; gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height); gimp_item_get_offset (item, &off_x, &off_y); off_x = x + (width - gimp_item_get_width (item)) / 2 - off_x; off_y = y + (height - gimp_item_get_height (item)) / 2 - off_y; gimp_item_translate (item, off_x, off_y, FALSE); }