void gimp_channel_select_polygon (GimpChannel *channel, const gchar *undo_desc, gint n_points, GimpVector2 *points, GimpChannelOps op, gboolean antialias, gboolean feather, gdouble feather_radius_x, gdouble feather_radius_y, gboolean push_undo) { GimpScanConvert *scan_convert; 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); scan_convert = gimp_scan_convert_new (); gimp_scan_convert_add_polyline (scan_convert, n_points, points, TRUE); gimp_channel_select_scan_convert (channel, undo_desc, scan_convert, 0, 0, op, antialias, feather, feather_radius_x, feather_radius_y, push_undo); gimp_scan_convert_free (scan_convert); }
void gimp_channel_select_vectors (GimpChannel *channel, const gchar *undo_desc, GimpVectors *vectors, GimpChannelOps op, gboolean antialias, gboolean feather, gdouble feather_radius_x, gdouble feather_radius_y, gboolean push_undo) { const GimpBezierDesc *bezier; 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 (GIMP_IS_VECTORS (vectors)); bezier = gimp_vectors_get_bezier (vectors); if (bezier && bezier->num_data > 4) { GimpScanConvert *scan_convert; scan_convert = gimp_scan_convert_new (); gimp_scan_convert_add_bezier (scan_convert, bezier); gimp_channel_select_scan_convert (channel, undo_desc, scan_convert, 0, 0, op, antialias, feather, feather_radius_x, feather_radius_y, push_undo); gimp_scan_convert_free (scan_convert); } }
void gimp_drawable_stroke_boundary (GimpDrawable *drawable, GimpStrokeOptions *options, const GimpBoundSeg *bound_segs, gint n_bound_segs, gint offset_x, gint offset_y, gboolean push_undo) { GimpScanConvert *scan_convert; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options)); g_return_if_fail (bound_segs == NULL || n_bound_segs != 0); g_return_if_fail (gimp_fill_options_get_style (GIMP_FILL_OPTIONS (options)) != GIMP_FILL_STYLE_PATTERN || gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL); scan_convert = gimp_scan_convert_new_from_boundary (bound_segs, n_bound_segs, offset_x, offset_y); if (scan_convert) { gimp_drawable_stroke_scan_convert (drawable, options, scan_convert, push_undo); gimp_scan_convert_free (scan_convert); } }
static void gimp_foreground_select_tool_stroke (GimpChannel *mask, FgSelectStroke *stroke) { GimpScanConvert *scan_convert = gimp_scan_convert_new (); if (stroke->num_points == 1) { GimpVector2 points[2]; points[0] = points[1] = stroke->points[0]; points[1].x += 0.01; points[1].y += 0.01; gimp_scan_convert_add_polyline (scan_convert, 2, points, FALSE); } else { gimp_scan_convert_add_polyline (scan_convert, stroke->num_points, stroke->points, FALSE); } gimp_scan_convert_stroke (scan_convert, stroke->width, GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0, 0.0, NULL); gimp_scan_convert_compose_value (scan_convert, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)), 0, 0, stroke->background ? 0 : 255); gimp_scan_convert_free (scan_convert); }
void gimp_drawable_stroke_vectors (GimpDrawable *drawable, GimpStrokeOptions *options, GimpVectors *vectors) { GimpScanConvert *scan_convert; GimpStroke *stroke; gint num_coords = 0; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options)); g_return_if_fail (GIMP_IS_VECTORS (vectors)); scan_convert = gimp_scan_convert_new (); /* For each Stroke in the vector, interpolate it, and add it to the * ScanConvert */ for (stroke = gimp_vectors_stroke_get_next (vectors, NULL); stroke; stroke = gimp_vectors_stroke_get_next (vectors, stroke)) { GArray *coords; gboolean closed; /* Get the interpolated version of this stroke, and add it to our * scanconvert. */ coords = gimp_stroke_interpolate (stroke, 0.2, &closed); if (coords && coords->len) { GimpVector2 *points = g_new0 (GimpVector2, coords->len); gint i; for (i = 0; i < coords->len; i++) { points[i].x = g_array_index (coords, GimpCoords, i).x; points[i].y = g_array_index (coords, GimpCoords, i).y; num_coords++; } gimp_scan_convert_add_polyline (scan_convert, coords->len, points, closed); g_free (points); } if (coords) g_array_free (coords, TRUE); } if (num_coords > 0) gimp_drawable_stroke_scan_convert (drawable, options, scan_convert); gimp_scan_convert_free (scan_convert); }
static void gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTool *fg_select, GimpDisplay *display, GimpForegroundSelectOptions *options) { GimpScanConvert *scan_convert; gint width; gdouble opacity; g_return_if_fail (fg_select->stroke != NULL); scan_convert = gimp_scan_convert_new (); if (fg_select->stroke->len == 1) { GimpVector2 points[2]; points[0] = points[1] = ((GimpVector2 *) fg_select->stroke->data)[0]; points[1].x += 0.01; points[1].y += 0.01; gimp_scan_convert_add_polyline (scan_convert, 2, points, FALSE); } else { gimp_scan_convert_add_polyline (scan_convert, fg_select->stroke->len, (GimpVector2 *) fg_select->stroke->data, FALSE); } width = ROUND ((gdouble) options->stroke_width); gimp_scan_convert_stroke (scan_convert, width, GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0, 0.0, NULL); if (options->draw_mode == GIMP_MATTING_DRAW_MODE_FOREGROUND) opacity = 1.0; else if (options->draw_mode == GIMP_MATTING_DRAW_MODE_BACKGROUND) opacity = 0.0; else opacity = 0.5; gimp_scan_convert_compose_value (scan_convert, fg_select->trimap, 0, 0, opacity); gimp_scan_convert_free (scan_convert); g_array_free (fg_select->stroke, TRUE); fg_select->stroke = NULL; }
static void gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel, GimpDisplay *display) { GimpForegroundSelectTool *fg_select; GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable; GimpScanConvert *scan_convert; const GimpVector2 *points; gint n_points; drawable = gimp_image_get_active_drawable (image); fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel); if (! drawable) return; if (fg_select->state == MATTING_STATE_FREE_SELECT) { scan_convert = gimp_scan_convert_new (); gimp_free_select_tool_get_points (free_sel, &points, &n_points); gimp_scan_convert_add_polyline (scan_convert, n_points, points, TRUE); fg_select->trimap = gegl_buffer_new (GEGL_RECTANGLE (0, 0, gimp_image_get_width (image), gimp_image_get_height (image)), gimp_image_get_mask_format (image)); gimp_scan_convert_render_value (scan_convert, fg_select->trimap, 0, 0, 1.0); gimp_scan_convert_free (scan_convert); gimp_foreground_select_tool_set_trimap (fg_select, display); } }
gboolean gimp_drawable_stroke_vectors (GimpDrawable *drawable, GimpStrokeOptions *options, GimpVectors *vectors, gboolean push_undo, GError **error) { const GimpBezierDesc *bezier; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE); g_return_val_if_fail (GIMP_IS_STROKE_OPTIONS (options), FALSE); g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE); g_return_val_if_fail (gimp_fill_options_get_style (GIMP_FILL_OPTIONS (options)) != GIMP_FILL_STYLE_PATTERN || gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); bezier = gimp_vectors_get_bezier (vectors); if (bezier && bezier->num_data >= 2) { GimpScanConvert *scan_convert = gimp_scan_convert_new (); gimp_scan_convert_add_bezier (scan_convert, bezier); gimp_drawable_stroke_scan_convert (drawable, options, scan_convert, push_undo); gimp_scan_convert_free (scan_convert); return TRUE; } g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Not enough points to stroke")); return FALSE; }
static void gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel, GimpDisplay *display) { GimpForegroundSelectTool *fg_select; GimpForegroundSelectOptions *options; GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable; GimpScanConvert *scan_convert; GimpChannel *mask; const GimpVector2 *points; gint n_points; drawable = gimp_image_get_active_drawable (image); fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel); options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (free_sel); if (fg_select->idle_id) { g_source_remove (fg_select->idle_id); fg_select->idle_id = 0; } if (! drawable) return; scan_convert = gimp_scan_convert_new (); gimp_free_select_tool_get_points (free_sel, &points, &n_points); gimp_scan_convert_add_polyline (scan_convert, n_points, points, TRUE); mask = gimp_channel_new (image, gimp_image_get_width (image), gimp_image_get_height (image), "foreground-extraction", NULL); gimp_scan_convert_render_value (scan_convert, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)), 0, 0, 128); gimp_scan_convert_free (scan_convert); if (fg_select->strokes) { GList *list; gimp_set_busy (image->gimp); /* apply foreground and background markers */ for (list = fg_select->strokes; list; list = list->next) gimp_foreground_select_tool_stroke (mask, list->data); if (fg_select->state) gimp_drawable_foreground_extract_siox (GIMP_DRAWABLE (mask), fg_select->state, fg_select->refinement, options->smoothness, options->sensitivity, ! options->contiguous, GIMP_PROGRESS (fg_select)); fg_select->refinement = SIOX_REFINEMENT_NO_CHANGE; gimp_unset_busy (image->gimp); } else { gint x1, y1; gint x2, y2; g_object_set (options, "background", FALSE, NULL); gimp_foreground_select_tool_get_area (mask, &x1, &y1, &x2, &y2); if (fg_select->state) g_warning ("state should be NULL here"); fg_select->state = gimp_drawable_foreground_extract_siox_init (drawable, x1, y1, x2 - x1, y2 - y1); } gimp_foreground_select_tool_set_mask (fg_select, display, mask); g_object_unref (mask); }
void gimp_channel_select_vectors (GimpChannel *channel, const gchar *undo_desc, GimpVectors *vectors, GimpChannelOps op, gboolean antialias, gboolean feather, gdouble feather_radius_x, gdouble feather_radius_y, gboolean push_undo) { GimpScanConvert *scan_convert; GList *stroke; gboolean coords_added = FALSE; 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 (GIMP_IS_VECTORS (vectors)); scan_convert = gimp_scan_convert_new (); for (stroke = vectors->strokes; stroke; stroke = stroke->next) { GArray *coords; gboolean closed; coords = gimp_stroke_interpolate (GIMP_STROKE (stroke->data), 1.0, &closed); if (coords && coords->len) { GimpVector2 *points; gint i; points = g_new0 (GimpVector2, coords->len); for (i = 0; i < coords->len; i++) { points[i].x = g_array_index (coords, GimpCoords, i).x; points[i].y = g_array_index (coords, GimpCoords, i).y; } gimp_scan_convert_add_polyline (scan_convert, coords->len, points, TRUE); coords_added = TRUE; g_free (points); } if (coords) g_array_free (coords, TRUE); } if (coords_added) gimp_channel_select_scan_convert (channel, undo_desc, scan_convert, 0, 0, op, antialias, feather, feather_radius_x, feather_radius_y, push_undo); gimp_scan_convert_free (scan_convert); }
void gimp_drawable_stroke_boundary (GimpDrawable *drawable, GimpStrokeOptions *options, const BoundSeg *bound_segs, gint n_bound_segs, gint offset_x, gint offset_y) { GimpScanConvert *scan_convert; BoundSeg *stroke_segs; gint n_stroke_segs; GimpVector2 *points; gint n_points; gint seg; gint i; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options)); if (n_bound_segs == 0) return; g_return_if_fail (bound_segs != NULL); stroke_segs = boundary_sort (bound_segs, n_bound_segs, &n_stroke_segs); if (n_stroke_segs == 0) return; scan_convert = gimp_scan_convert_new (); points = g_new0 (GimpVector2, n_bound_segs + 4); seg = 0; n_points = 0; points[n_points].x = (gdouble) (stroke_segs[0].x1 + offset_x); points[n_points].y = (gdouble) (stroke_segs[0].y1 + offset_y); n_points++; for (i = 0; i < n_stroke_segs; i++) { while (stroke_segs[seg].x1 != -1 || stroke_segs[seg].x2 != -1 || stroke_segs[seg].y1 != -1 || stroke_segs[seg].y2 != -1) { points[n_points].x = (gdouble) (stroke_segs[seg].x1 + offset_x); points[n_points].y = (gdouble) (stroke_segs[seg].y1 + offset_y); n_points++; seg++; } /* Close the stroke points up */ points[n_points] = points[0]; n_points++; gimp_scan_convert_add_polyline (scan_convert, n_points, points, TRUE); n_points = 0; seg++; points[n_points].x = (gdouble) (stroke_segs[seg].x1 + offset_x); points[n_points].y = (gdouble) (stroke_segs[seg].y1 + offset_y); n_points++; } g_free (points); g_free (stroke_segs); gimp_drawable_stroke_scan_convert (drawable, options, scan_convert); gimp_scan_convert_free (scan_convert); }