void gimp_vectors_add_strokes (const GimpVectors *src_vectors, GimpVectors *dest_vectors) { GList *current_lstroke; GList *strokes_copy; g_return_if_fail (GIMP_IS_VECTORS (src_vectors)); g_return_if_fail (GIMP_IS_VECTORS (dest_vectors)); gimp_vectors_freeze (dest_vectors); strokes_copy = g_list_copy (src_vectors->strokes); current_lstroke = strokes_copy; while (current_lstroke) { current_lstroke->data = gimp_stroke_duplicate (current_lstroke->data); dest_vectors->last_stroke_ID ++; gimp_stroke_set_ID (current_lstroke->data, dest_vectors->last_stroke_ID); current_lstroke = g_list_next (current_lstroke); } dest_vectors->strokes = g_list_concat (dest_vectors->strokes, strokes_copy); gimp_vectors_thaw (dest_vectors); }
GimpUndo * gimp_image_undo_push_vectors_remove (GimpImage *image, const gchar *undo_desc, GimpVectors *vectors, GimpVectors *prev_parent, gint prev_position, GimpVectors *prev_vectors) { g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (vectors)), NULL); g_return_val_if_fail (prev_parent == NULL || GIMP_IS_VECTORS (prev_parent), NULL); g_return_val_if_fail (prev_vectors == NULL || GIMP_IS_VECTORS (prev_vectors), NULL); return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_UNDO, GIMP_UNDO_VECTORS_REMOVE, undo_desc, GIMP_DIRTY_IMAGE_STRUCTURE, "item", vectors, "prev-parent", prev_parent, "prev-position", prev_position, "prev-vectors", prev_vectors, NULL); }
gint gimp_vectors_get_n_strokes (const GimpVectors *vectors) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0); return g_list_length (vectors->strokes); }
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); } }
GimpVectors * gimp_vectors_get_parent (GimpVectors *vectors) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); return GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors))); }
GimpStroke * gimp_pdb_get_vectors_stroke (GimpVectors *vectors, gint stroke_ID, GimpPDBItemModify modify, GError **error) { GimpStroke *stroke = NULL; g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); if (! gimp_pdb_item_is_not_group (GIMP_ITEM (vectors), error)) return NULL; if (! modify || gimp_pdb_item_is_modifyable (GIMP_ITEM (vectors), modify, error)) { stroke = gimp_vectors_stroke_get_by_ID (vectors, stroke_ID); if (! stroke) g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT, _("Vectors object %d does not contain stroke with ID %d"), gimp_item_get_ID (GIMP_ITEM (vectors)), stroke_ID); } return stroke; }
GimpStroke * gimp_vectors_stroke_get (const GimpVectors *vectors, const GimpCoords *coord) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get (vectors, coord); }
gdouble gimp_vectors_get_distance (const GimpVectors *vectors, const GimpCoords *coord) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); return GIMP_VECTORS_GET_CLASS (vectors)->get_distance (vectors, coord); }
GimpStroke * gimp_vectors_stroke_get_next (const GimpVectors *vectors, const GimpStroke *prev) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_next (vectors, prev); }
gdouble gimp_vectors_get_length (const GimpVectors *vectors, const GimpAnchor *start) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); return GIMP_VECTORS_GET_CLASS (vectors)->get_length (vectors, start); }
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); }
/** * gimp_vectors_export_string: * @image: the #GimpImage from which to export vectors * @vectors: a #GimpVectors object or %NULL to export all vectors in @image * * Exports one or more vectors to a SVG string. * * Return value: a %NUL-terminated string that holds a complete XML document **/ gchar * gimp_vectors_export_string (const GimpImage *image, const GimpVectors *vectors) { g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors), NULL); return g_string_free (gimp_vectors_export (image, vectors), FALSE); }
gdouble gimp_vectors_stroke_get_length (const GimpVectors *vectors, const GimpStroke *stroke) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0.0); return GIMP_VECTORS_GET_CLASS (vectors)->stroke_get_length (vectors, stroke); }
static gdouble gimp_vectors_real_stroke_get_length (const GimpVectors *vectors, const GimpStroke *stroke) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0.0); g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0.0); return gimp_stroke_get_length (stroke, vectors->precision); }
void gimp_vectors_anchor_delete (GimpVectors *vectors, GimpAnchor *anchor) { g_return_if_fail (GIMP_IS_VECTORS (vectors)); g_return_if_fail (anchor != NULL); GIMP_VECTORS_GET_CLASS (vectors)->anchor_delete (vectors, anchor); }
GimpAnchor * gimp_vectors_anchor_get (const GimpVectors *vectors, const GimpCoords *coord, GimpStroke **ret_stroke) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); return GIMP_VECTORS_GET_CLASS (vectors)->anchor_get (vectors, coord, ret_stroke); }
void gimp_vectors_freeze (GimpVectors *vectors) { g_return_if_fail (GIMP_IS_VECTORS (vectors)); vectors->freeze_count++; if (vectors->freeze_count == 1) g_signal_emit (vectors, gimp_vectors_signals[FREEZE], 0); }
GimpUndo * gimp_image_undo_push_vectors_add (GimpImage *image, const gchar *undo_desc, GimpVectors *vectors, GimpVectors *prev_vectors) { g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); g_return_val_if_fail (! gimp_item_is_attached (GIMP_ITEM (vectors)), NULL); g_return_val_if_fail (prev_vectors == NULL || GIMP_IS_VECTORS (prev_vectors), NULL); return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_UNDO, GIMP_UNDO_VECTORS_ADD, undo_desc, GIMP_DIRTY_IMAGE_STRUCTURE, "item", vectors, "prev-vectors", prev_vectors, NULL); }
void gimp_vectors_thaw (GimpVectors *vectors) { g_return_if_fail (GIMP_IS_VECTORS (vectors)); g_return_if_fail (vectors->freeze_count > 0); vectors->freeze_count--; if (vectors->freeze_count == 0) g_signal_emit (vectors, gimp_vectors_signals[THAW], 0); }
const GimpBezierDesc * gimp_vectors_get_bezier (GimpVectors *vectors) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); if (! vectors->bezier_desc) { vectors->bezier_desc = gimp_vectors_make_bezier (vectors); } return vectors->bezier_desc; }
void gimp_vectors_copy_strokes (const GimpVectors *src_vectors, GimpVectors *dest_vectors) { g_return_if_fail (GIMP_IS_VECTORS (src_vectors)); g_return_if_fail (GIMP_IS_VECTORS (dest_vectors)); gimp_vectors_freeze (dest_vectors); if (dest_vectors->strokes) { g_list_free_full (dest_vectors->strokes, (GDestroyNotify) g_object_unref); } dest_vectors->strokes = NULL; dest_vectors->last_stroke_ID = 0; gimp_vectors_add_strokes (src_vectors, dest_vectors); gimp_vectors_thaw (dest_vectors); }
void gimp_vectors_stroke_remove (GimpVectors *vectors, GimpStroke *stroke) { g_return_if_fail (GIMP_IS_VECTORS (vectors)); g_return_if_fail (GIMP_IS_STROKE (stroke)); gimp_vectors_freeze (vectors); GIMP_VECTORS_GET_CLASS (vectors)->stroke_remove (vectors, stroke); gimp_vectors_thaw (vectors); }
gint gimp_vectors_interpolate (const GimpVectors *vectors, const GimpStroke *stroke, gdouble precision, gint max_points, GimpCoords *ret_coords) { g_return_val_if_fail (GIMP_IS_VECTORS (vectors), 0); return GIMP_VECTORS_GET_CLASS (vectors)->interpolate (vectors, stroke, precision, max_points, ret_coords); }
GimpUndo * gimp_image_undo_push_vectors_mod (GimpImage *image, const gchar *undo_desc, GimpVectors *vectors) { g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (vectors)), NULL); return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_MOD_UNDO, GIMP_UNDO_VECTORS_MOD, undo_desc, GIMP_DIRTY_ITEM | GIMP_DIRTY_VECTORS, "item", vectors, NULL); }
GimpStroke * gimp_vectors_stroke_get_by_ID (const GimpVectors *vectors, gint id) { GList *list; g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); for (list = vectors->strokes; list; list = g_list_next (list)) { if (gimp_stroke_get_ID (list->data) == id) return list->data; } return NULL; }
static void gimp_vectors_prop_undo_constructed (GObject *object) { /* GimpVectors *vectors; */ G_OBJECT_CLASS (parent_class)->constructed (object); gimp_assert (GIMP_IS_VECTORS (GIMP_ITEM_UNDO (object)->item)); /* vectors = GIMP_VECTORS (GIMP_ITEM_UNDO (object)->item); */ switch (GIMP_UNDO (object)->undo_type) { default: gimp_assert_not_reached (); } }
static GimpItem * gimp_vectors_duplicate (GimpItem *item, GType new_type) { GimpItem *new_item; g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_VECTORS), NULL); new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type); if (GIMP_IS_VECTORS (new_item)) { GimpVectors *vectors = GIMP_VECTORS (item); GimpVectors *new_vectors = GIMP_VECTORS (new_item); gimp_vectors_copy_strokes (vectors, new_vectors); } return new_item; }
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; }
/** * gimp_vectors_export_file: * @image: the #GimpImage from which to export vectors * @vectors: a #GimpVectors object or %NULL to export all vectors in @image * @filename: the name of the file to write * @error: return location for errors * * Exports one or more vectors to a SVG file. * * Return value: %TRUE on success, * %FALSE if there was an error writing the file **/ gboolean gimp_vectors_export_file (const GimpImage *image, const GimpVectors *vectors, const gchar *filename, GError **error) { FILE *file; GString *str; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors), FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); file = g_fopen (filename, "w"); if (!file) { g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), _("Could not open '%s' for writing: %s"), gimp_filename_to_utf8 (filename), g_strerror (errno)); return FALSE; } str = gimp_vectors_export (image, vectors); fprintf (file, "%s", str->str); g_string_free (str, TRUE); if (fclose (file)) { g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), _("Error while writing '%s': %s"), gimp_filename_to_utf8 (filename), g_strerror (errno)); return FALSE; } return TRUE; }
static GObject * gimp_vectors_mod_undo_constructor (GType type, guint n_params, GObjectConstructParam *params) { GObject *object; GimpVectorsModUndo *vectors_mod_undo; GimpVectors *vectors; object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params); vectors_mod_undo = GIMP_VECTORS_MOD_UNDO (object); g_assert (GIMP_IS_VECTORS (GIMP_ITEM_UNDO (object)->item)); vectors = GIMP_VECTORS (GIMP_ITEM_UNDO (object)->item); vectors_mod_undo->vectors = GIMP_VECTORS (gimp_item_duplicate (GIMP_ITEM (vectors), G_TYPE_FROM_INSTANCE (vectors), FALSE)); return object; }