Index: app/core/gimpselection.c =================================================================== --- app/core/gimpselection.c (revision 27379) +++ app/core/gimpselection.c (working copy) @@ -76,6 +76,7 @@ static void gimp_selection_rotate static gboolean gimp_selection_stroke (GimpItem *item, GimpDrawable *drawable, GimpStrokeDesc *stroke_desc, + gboolean push_undo, GimpProgress *progress, GError **error); static void gimp_selection_invalidate_boundary (GimpDrawable *drawable); @@ -256,6 +257,7 @@ static gboolean gimp_selection_stroke (GimpItem *item, GimpDrawable *drawable, GimpStrokeDesc *stroke_desc, + gboolean push_undo, GimpProgress *progress, GError **error) { @@ -279,7 +281,7 @@ gimp_selection_stroke (GimpItem * selection->stroking = TRUE; retval = GIMP_ITEM_CLASS (parent_class)->stroke (item, drawable, stroke_desc, - progress, error); + push_undo, progress, error); selection->stroking = FALSE; Index: app/core/gimpdrawable-stroke.c =================================================================== --- app/core/gimpdrawable-stroke.c (revision 27379) +++ app/core/gimpdrawable-stroke.c (working copy) @@ -53,9 +53,17 @@ /* local function prototypes */ -static void gimp_drawable_stroke_scan_convert (GimpDrawable *drawable, - GimpStrokeOptions *options, - GimpScanConvert *scan_convert); +static void gimp_drawable_render_vectors (GimpDrawable *drawable, + GimpFillOptions *options, + GimpVectors *vectors, + gboolean do_stroke, + gboolean push_undo); + +static void gimp_drawable_stroke_scan_convert (GimpDrawable *drawable, + GimpFillOptions *options, + GimpScanConvert *scan_convert, + gboolean do_stroke, + gboolean push_undo); /* public functions */ @@ -66,7 +74,8 @@ gimp_drawable_stroke_boundary (GimpDrawa const BoundSeg *bound_segs, gint n_bound_segs, gint offset_x, - gint offset_y) + gint offset_y, + gboolean push_undo) { GimpScanConvert *scan_convert; BoundSeg *stroke_segs; @@ -135,24 +144,60 @@ gimp_drawable_stroke_boundary (GimpDrawa g_free (points); g_free (stroke_segs); - gimp_drawable_stroke_scan_convert (drawable, options, scan_convert); + gimp_drawable_stroke_scan_convert (drawable, GIMP_FILL_OPTIONS (options), + scan_convert, TRUE, push_undo); gimp_scan_convert_free (scan_convert); } void +gimp_drawable_fill_vectors (GimpDrawable *drawable, + GimpFillOptions *options, + GimpVectors *vectors, + gboolean push_undo) +{ + 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_FILL_OPTIONS (options)); + g_return_if_fail (GIMP_IS_VECTORS (vectors)); + g_return_if_fail (options->style != GIMP_FILL_STYLE_PATTERN || + gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL); + + gimp_drawable_render_vectors (drawable, options, vectors, FALSE, + push_undo); +} + +void gimp_drawable_stroke_vectors (GimpDrawable *drawable, GimpStrokeOptions *options, - GimpVectors *vectors) + GimpVectors *vectors, + gboolean push_undo) { - 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)); + g_return_if_fail (GIMP_FILL_OPTIONS (options)->style != GIMP_FILL_STYLE_PATTERN || + gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL); + + gimp_drawable_render_vectors (drawable, GIMP_FILL_OPTIONS (options), + vectors, TRUE, + push_undo); +} + + +/* private functions */ + +static void +gimp_drawable_render_vectors (GimpDrawable *drawable, + GimpFillOptions *options, + GimpVectors *vectors, + gboolean do_stroke, + gboolean push_undo) +{ + GimpScanConvert *scan_convert; + GimpStroke *stroke; + gint num_coords = 0; scan_convert = gimp_scan_convert_new (); @@ -184,7 +229,7 @@ gimp_drawable_stroke_vectors (GimpDrawab } gimp_scan_convert_add_polyline (scan_convert, coords->len, - points, closed); + points, closed || !do_stroke); g_free (points); } @@ -194,22 +239,21 @@ gimp_drawable_stroke_vectors (GimpDrawab } if (num_coords > 0) - gimp_drawable_stroke_scan_convert (drawable, options, scan_convert); + gimp_drawable_stroke_scan_convert (drawable, options, scan_convert, + do_stroke, push_undo); gimp_scan_convert_free (scan_convert); } - -/* private functions */ - static void -gimp_drawable_stroke_scan_convert (GimpDrawable *drawable, - GimpStrokeOptions *options, - GimpScanConvert *scan_convert) +gimp_drawable_stroke_scan_convert (GimpDrawable *drawable, + GimpFillOptions *options, + GimpScanConvert *scan_convert, + gboolean do_stroke, + gboolean push_undo) { GimpContext *context = GIMP_CONTEXT (options); GimpImage *image; - gdouble width; TileManager *base; TileManager *mask; gint x, y, w, h; @@ -240,26 +284,32 @@ gimp_drawable_stroke_scan_convert (GimpD gimp_item_offsets (GIMP_ITEM (drawable), &off_x, &off_y); - width = options->width; - - if (options->unit != GIMP_UNIT_PIXEL) + if (do_stroke) { - gdouble xres; - gdouble yres; + GimpStrokeOptions *stroke_options = GIMP_STROKE_OPTIONS (options); + + gdouble width = stroke_options->width; - gimp_image_get_resolution (image, &xres, &yres); + if (stroke_options->unit != GIMP_UNIT_PIXEL) + { + gdouble xres; + gdouble yres; - gimp_scan_convert_set_pixel_ratio (scan_convert, yres / xres); + gimp_image_get_resolution (image, &xres, &yres); - width *= (yres / _gimp_unit_get_factor (image->gimp, options->unit)); - } + gimp_scan_convert_set_pixel_ratio (scan_convert, yres / xres); - gimp_scan_convert_stroke (scan_convert, width, - options->join_style, - options->cap_style, - options->miter_limit, - options->dash_offset, - options->dash_info); + width *= (image->yresolution / + _gimp_unit_get_factor (image->gimp, stroke_options->unit)); + } + + gimp_scan_convert_stroke (scan_convert, width, + stroke_options->join_style, + stroke_options->cap_style, + stroke_options->miter_limit, + stroke_options->dash_offset, + stroke_options->dash_info); + } /* fill a 1-bpp Tilemanager with black, this will describe the shape * of the stroke. @@ -321,7 +371,7 @@ gimp_drawable_stroke_scan_convert (GimpD /* Apply to drawable */ pixel_region_init (&basePR, base, 0, 0, w, h, FALSE); gimp_drawable_apply_region (drawable, &basePR, - TRUE, _("Render Stroke"), + push_undo, _("Render Stroke"), gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), NULL, x, y); Index: app/core/gimpdrawable-stroke.h =================================================================== --- app/core/gimpdrawable-stroke.h (revision 27379) +++ app/core/gimpdrawable-stroke.h (working copy) @@ -28,11 +28,18 @@ void gimp_drawable_stroke_boundary (Gi const BoundSeg *bound_segs, gint n_bound_segs, gint offset_x, - gint offset_y); + gint offset_y, + gboolean push_undo); + +void gimp_drawable_fill_vectors (GimpDrawable *drawable, + GimpFillOptions *options, + GimpVectors *vectors, + gboolean push_undo); void gimp_drawable_stroke_vectors (GimpDrawable *drawable, GimpStrokeOptions *options, - GimpVectors *vectors); + GimpVectors *vectors, + gboolean push_undo); #endif /* __GIMP_DRAWABLE_STROKE_H__ */ Index: app/core/gimpitem.c =================================================================== --- app/core/gimpitem.c (revision 27379) +++ app/core/gimpitem.c (working copy) @@ -1009,6 +1009,7 @@ gimp_item_stroke (GimpItem *item, GimpContext *context, GimpStrokeDesc *stroke_desc, gboolean use_default_values, + gboolean push_undo, GimpProgress *progress, GError **error) { @@ -1032,12 +1033,15 @@ gimp_item_stroke (GimpItem *item, gimp_stroke_desc_prepare (stroke_desc, context, use_default_values); - gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT, - item_class->stroke_desc); + if (push_undo) + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT, + item_class->stroke_desc); - retval = item_class->stroke (item, drawable, stroke_desc, progress, error); + retval = item_class->stroke (item, drawable, stroke_desc, push_undo, + progress, error); - gimp_image_undo_group_end (image); + if (push_undo) + gimp_image_undo_group_end (image); gimp_stroke_desc_finish (stroke_desc); } Index: app/core/gimpitem.h =================================================================== --- app/core/gimpitem.h (revision 27379) +++ app/core/gimpitem.h (working copy) @@ -111,6 +111,7 @@ struct _GimpItemClass gboolean (* stroke) (GimpItem *item, GimpDrawable *drawable, GimpStrokeDesc *stroke_desc, + gboolean push_undo, GimpProgress *progress, GError **error); @@ -215,6 +216,7 @@ gboolean gimp_item_stroke GimpContext *context, GimpStrokeDesc *stroke_desc, gboolean use_default_values, + gboolean push_undo, GimpProgress *progress, GError **error); Index: app/core/gimpstrokedesc.c =================================================================== --- app/core/gimpstrokedesc.c (revision 27379) +++ app/core/gimpstrokedesc.c (working copy) @@ -55,18 +55,29 @@ enum static void gimp_stroke_desc_config_iface_init (gpointer iface, gpointer iface_data); -static GObject * gimp_stroke_desc_constructor (GType type, - guint n_params, - GObjectConstructParam *params); -static void gimp_stroke_desc_finalize (GObject *object); -static void gimp_stroke_desc_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_stroke_desc_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); +static GObject * gimp_stroke_desc_constructor (GType type, + guint n_params, + GObjectConstructParam *params); +static void gimp_stroke_desc_finalize (GObject *object); +static void gimp_stroke_desc_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_stroke_desc_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static gboolean gimp_stroke_desc_serialize_property (GimpConfig *config, + guint property_id, + const GValue *value, + GParamSpec *pspec, + GimpConfigWriter *writer); +static gboolean gimp_stroke_desc_deserialize_property (GimpConfig *object, + guint property_id, + GValue *value, + GParamSpec *pspec, + GScanner *scanner, + GTokenType *expected); static GimpConfig * gimp_stroke_desc_duplicate (GimpConfig *config); @@ -126,7 +137,9 @@ gimp_stroke_desc_config_iface_init (gpoi { GimpConfigInterface *config_iface = (GimpConfigInterface *) iface; - config_iface->duplicate = gimp_stroke_desc_duplicate; + config_iface->duplicate = gimp_stroke_desc_duplicate; + config_iface->serialize_property = gimp_stroke_desc_serialize_property; + config_iface->deserialize_property = gimp_stroke_desc_deserialize_property; } static void @@ -293,6 +306,89 @@ gimp_stroke_desc_duplicate (GimpConfig * return GIMP_CONFIG (new_desc); } +static gboolean +gimp_stroke_desc_serialize_property (GimpConfig *config, + guint property_id, + const GValue *value, + GParamSpec *pspec, + GimpConfigWriter *writer) +{ + GimpObject *serialize_obj; + + if (property_id == PROP_PAINT_INFO) + serialize_obj = g_value_get_object (value); + else + return FALSE; + + gimp_config_writer_open (writer, pspec->name); + + if (serialize_obj) + gimp_config_writer_string (writer, gimp_object_get_name (serialize_obj)); + else + gimp_config_writer_print (writer, "NULL", 4); + + gimp_config_writer_close (writer); + + return TRUE; +} + +static gboolean +gimp_stroke_desc_deserialize_property (GimpConfig *object, + guint property_id, + GValue *value, + GParamSpec *pspec, + GScanner *scanner, + GTokenType *expected) +{ + GimpStrokeDesc *stroke_desc = GIMP_STROKE_DESC (object); + GimpContainer *container; + GimpObject *current; + gboolean no_data = FALSE; + gchar *object_name; + + if (property_id == PROP_PAINT_INFO) + { + container = stroke_desc->gimp->paint_info_list; + current = (GimpObject *) (GIMP_CONTEXT (stroke_desc->stroke_options)->paint_info); + no_data = TRUE; + } + else + return FALSE; + + if (! no_data) + no_data = stroke_desc->gimp->no_data; + + if (gimp_scanner_parse_identifier (scanner, "NULL")) + { + g_value_set_object (value, NULL); + } + else if (gimp_scanner_parse_string (scanner, &object_name)) + { + GimpObject *deserialize_obj; + + if (! object_name) + object_name = g_strdup (""); + + deserialize_obj = gimp_container_get_child_by_name (container, + object_name); + + if (! deserialize_obj && ! no_data) + { + deserialize_obj = current; + } + + g_value_set_object (value, deserialize_obj); + + g_free (object_name); + } + else + { + *expected = G_TOKEN_STRING; + } + + return TRUE; +} + /* public functions */ @@ -307,13 +403,11 @@ gimp_stroke_desc_new (Gimp *gimp, g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL); if (context) - { paint_info = gimp_context_get_paint_info (context); - - if (! paint_info) - paint_info = gimp_paint_info_get_standard (gimp); - } - + + if (! paint_info) + paint_info = gimp_paint_info_get_standard (gimp); + desc = g_object_new (GIMP_TYPE_STROKE_DESC, "gimp", gimp, "paint-info", paint_info, Index: app/core/gimpchannel.c =================================================================== --- app/core/gimpchannel.c (revision 27379) +++ app/core/gimpchannel.c (working copy) @@ -126,6 +126,7 @@ static void gimp_channel_transform static gboolean gimp_channel_stroke (GimpItem *item, GimpDrawable *drawable, GimpStrokeDesc *stroke_desc, + gboolean push_undo, GimpProgress *progress, GError **error); @@ -699,6 +700,7 @@ static gboolean gimp_channel_stroke (GimpItem *item, GimpDrawable *drawable, GimpStrokeDesc *stroke_desc, + gboolean push_undo, GimpProgress *progress, GError **error) @@ -728,7 +730,8 @@ gimp_channel_stroke (GimpItem *it gimp_drawable_stroke_boundary (drawable, stroke_desc->stroke_options, segs_in, n_segs_in, - offset_x, offset_y); + offset_x, offset_y, + push_undo); retval = TRUE; break; @@ -743,7 +746,7 @@ gimp_channel_stroke (GimpItem *it stroke_desc->emulate_dynamics, segs_in, n_segs_in, offset_x, offset_y, - error); + push_undo, error); g_object_unref (core); } Index: app/tools/gimppainttool.c =================================================================== --- app/tools/gimppainttool.c (revision 27379) +++ app/tools/gimppainttool.c (working copy) @@ -423,7 +423,7 @@ gimp_paint_tool_button_release (GimpTool if (release_type == GIMP_BUTTON_RELEASE_CANCEL) gimp_paint_core_cancel (core, drawable); else - gimp_paint_core_finish (core, drawable); + gimp_paint_core_finish (core, drawable, TRUE); gimp_image_flush (display->image); Index: app/tools/gimpvectortool.c =================================================================== --- app/tools/gimpvectortool.c (revision 27379) +++ app/tools/gimpvectortool.c (working copy) @@ -659,6 +659,7 @@ gimp_vector_tool_motion (GimpTool GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool); GimpCoords position = GIMP_COORDS_DEFAULT_VALUES; GimpAnchor *anchor; + GimpImage *image; if (vector_tool->function == VECTORS_FINISHED) return; @@ -757,6 +758,9 @@ gimp_vector_tool_motion (GimpTool vector_tool->last_y = coords->y; gimp_vectors_thaw (vector_tool->vectors); + + image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors)); + gimp_image_flush (image); } static gboolean Index: app/xcf/xcf-save.c =================================================================== --- app/xcf/xcf-save.c (revision 27379) +++ app/xcf/xcf-save.c (working copy) @@ -59,6 +59,8 @@ #include "vectors/gimpbezierstroke.h" #include "vectors/gimpvectors.h" #include "vectors/gimpvectors-compat.h" +#include "vectors/gimpvectorlayer.h" +#include "vectors/gimpvectorlayer-xcf.h" #include "xcf-private.h" #include "xcf-read.h" @@ -529,6 +531,12 @@ xcf_save_layer_props (XcfInfo *info, image, PROP_TEXT_LAYER_FLAGS, error, flags)); } + else if (GIMP_IS_VECTOR_LAYER (layer) && GIMP_VECTOR_LAYER (layer)->options) + { + GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (layer); + + gimp_vector_layer_xcf_save_prepare (vector_layer); + } if (gimp_parasite_list_length (GIMP_ITEM (layer)->parasites) > 0) { Index: app/xcf/xcf-load.c =================================================================== --- app/xcf/xcf-load.c (revision 27379) +++ app/xcf/xcf-load.c (working copy) @@ -60,6 +60,8 @@ #include "vectors/gimpbezierstroke.h" #include "vectors/gimpvectors.h" #include "vectors/gimpvectors-compat.h" +#include "vectors/gimpvectorlayer.h" +#include "vectors/gimpvectorlayer-xcf.h" #include "xcf-private.h" #include "xcf-load.h" @@ -976,7 +978,7 @@ xcf_load_layer (XcfInfo *info, xcf_progress_update (info); - /* call the evil text layer hack that might change our layer pointer */ + /* call the evil text and vector layer hacks that might change our layer pointer */ active = (info->active_layer == layer); floating = (info->floating_sel == layer); @@ -990,6 +992,13 @@ xcf_load_layer (XcfInfo *info, if (floating) info->floating_sel = layer; } + else if (gimp_vector_layer_xcf_load_hack (&layer)) + { + if (active) + info->active_layer = layer; + if (floating) + info->floating_sel = layer; + } /* read the hierarchy and layer mask offsets */ info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1); Index: app/dialogs/stroke-dialog.c =================================================================== --- app/dialogs/stroke-dialog.c (revision 27379) +++ app/dialogs/stroke-dialog.c (working copy) @@ -316,8 +316,8 @@ stroke_dialog_response (GtkWidget *widg saved_desc, (GDestroyNotify) g_object_unref); - if (! gimp_item_stroke (item, drawable, context, desc, FALSE, NULL, - &error)) + if (! gimp_item_stroke (item, drawable, context, desc, FALSE, TRUE, + NULL, &error)) { gimp_message (context->gimp, G_OBJECT (widget), GIMP_MESSAGE_WARNING, Index: app/dialogs/vector-layer-options-dialog.c =================================================================== --- app/dialogs/vector-layer-options-dialog.c (revision 0) +++ app/dialogs/vector-layer-options-dialog.c (revision 0) @@ -0,0 +1,292 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * Copyright (C) 2006 Henk Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include + +#include "libgimpconfig/gimpconfig.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "dialogs-types.h" + +#include "core/gimp.h" +#include "core/gimpdrawable.h" +#include "core/gimpimage.h" +#include "core/gimppaintinfo.h" +#include "core/gimpstrokedesc.h" +#include "core/gimpstrokeoptions.h" +#include "core/gimptoolinfo.h" + +#include "widgets/gimpcontainercombobox.h" +#include "widgets/gimpcontainerview.h" +#include "widgets/gimpviewabledialog.h" +#include "widgets/gimpstrokeeditor.h" + +#include "vectors/gimpvectorlayer.h" + +#include "vector-layer-options-dialog.h" + +#include "gimp-intl.h" + + +#define RESPONSE_RESET 1 + + +/* local functions */ + +static void vector_layer_options_dialog_response (GtkWidget *widget, + gint response_id, + GtkWidget *dialog); + + +/* public function */ + +GtkWidget * +vector_layer_options_dialog_new (GimpItem *item, + GimpContext *context, + const gchar *title, + const gchar *stock_id, + const gchar *help_id, + GtkWidget *parent) +{ + GtkWidget *dialog; + GtkWidget *main_vbox; + GimpVectorLayerOptions *vector_layer_options; + + g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (item), NULL); + g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); + g_return_val_if_fail (stock_id != NULL, NULL); + /*g_return_val_if_fail (help_id != NULL, NULL);*/ + g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL); + + g_object_get (item, "vector-layer-options", &vector_layer_options, NULL); + + dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (item), + context, + title, "gimp-vectorlayer-options", + stock_id, + _("Choose vector layer options"), + parent, + gimp_standard_help_func, + help_id, + + GIMP_STOCK_RESET, RESPONSE_RESET, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, + stock_id, GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + RESPONSE_RESET, + GTK_RESPONSE_OK, + GTK_RESPONSE_APPLY, + GTK_RESPONSE_CANCEL, + -1); + + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + + g_signal_connect (dialog, "response", + G_CALLBACK (vector_layer_options_dialog_response), + dialog); + + g_object_set_data (G_OBJECT (dialog), "gimp-item", item); + + main_vbox = gtk_vbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), main_vbox); + gtk_widget_show (main_vbox); + + /* The fill color */ + { + GtkWidget *fill_label = NULL; + GimpColorButton *fill_entry = NULL; + GimpFillOptions *fill_options = NULL; + GimpRGB *fill_color = NULL; + + fill_label = gtk_label_new ("Fill"); + gtk_misc_set_alignment (GTK_MISC (fill_label), 0.0, 0.0); + + gtk_container_add (GTK_CONTAINER(main_vbox), GTK_WIDGET (fill_label)); + gtk_widget_show (GTK_WIDGET (fill_label)); + + g_object_get (G_OBJECT(vector_layer_options), "fill-options", &fill_options, NULL); + g_object_get (G_OBJECT(fill_options), "foreground", &fill_color, NULL); + + fill_entry = GIMP_COLOR_BUTTON (gimp_color_button_new ("Fill Color", + 32, 32, + fill_color, + GIMP_COLOR_AREA_FLAT)); + + gtk_container_add (GTK_CONTAINER(main_vbox), GTK_WIDGET (fill_entry)); + gtk_widget_show (GTK_WIDGET (fill_entry)); + + g_object_set_data_full (G_OBJECT (dialog), "gimp-fill-entry", g_object_ref (fill_entry), + (GDestroyNotify) g_object_unref); + + g_object_unref (fill_options); + } + + /* The stroke color and editor */ + { + GtkWidget *stroke_label = NULL; + GimpColorButton *stroke_entry = NULL; + GimpStrokeEditor *stroke_editor = NULL; + GimpStrokeDesc *stroke_desc = NULL; + GimpStrokeOptions *stroke_options = NULL; + GimpStrokeOptions *stroke_options_copy = NULL; + GimpRGB *stroke_color = NULL; + + stroke_label = gtk_label_new ("Stroke"); + gtk_misc_set_alignment (GTK_MISC (stroke_label), 0.0, 0.0); + + gtk_container_add (GTK_CONTAINER(main_vbox), GTK_WIDGET (stroke_label)); + gtk_widget_show (GTK_WIDGET (stroke_label)); + + g_object_get (G_OBJECT(vector_layer_options), "stroke-desc", &stroke_desc, NULL); + g_object_get (G_OBJECT(stroke_desc), "stroke-options", &stroke_options, NULL); + g_object_get (G_OBJECT(stroke_options), "foreground", &stroke_color, NULL); + + /* stroke color */ + stroke_entry = GIMP_COLOR_BUTTON (gimp_color_button_new ("Stroke Color", + 32, 32, + stroke_color, + GIMP_COLOR_AREA_FLAT)); + + gtk_container_add (GTK_CONTAINER(main_vbox), GTK_WIDGET (stroke_entry)); + gtk_widget_show (GTK_WIDGET (stroke_entry)); + + /* stroke editor */ + stroke_options_copy = gimp_config_duplicate (GIMP_CONFIG (stroke_options)); + stroke_editor = GIMP_STROKE_EDITOR (gimp_stroke_editor_new (stroke_options_copy, 72.0)); /* TODO: put in real resolution */ + + gtk_container_add (GTK_CONTAINER(main_vbox), GTK_WIDGET (stroke_editor)); + gtk_widget_show (GTK_WIDGET (stroke_editor)); + + g_object_set_data_full (G_OBJECT (dialog), "gimp-stroke-entry", g_object_ref (stroke_entry), + (GDestroyNotify) g_object_unref); + g_object_set_data_full (G_OBJECT (dialog), "gimp-stroke-editor", g_object_ref (stroke_editor), + (GDestroyNotify) g_object_unref); + + g_object_unref (stroke_desc); + g_object_unref (stroke_options); + g_object_unref (stroke_options_copy); + } + + return dialog; +} + +static void +vector_layer_options_dialog_response (GtkWidget *widget, + gint response_id, + GtkWidget *dialog) +{ + GimpImage *image; + GimpColorButton *fill_entry; + GimpColorButton *stroke_entry; + GimpStrokeEditor *stroke_editor; + GimpItem *item; + GimpVectorLayerOptions *vector_layer_options; + GimpFillOptions *fill_options; + GimpStrokeDesc *stroke_desc; + GimpStrokeOptions *stroke_options; + + item = g_object_get_data (G_OBJECT (dialog), "gimp-item"); + + g_object_get (item, + "vector-layer-options", &vector_layer_options, + NULL); + + image = gimp_item_get_image (item); + + fill_entry = g_object_get_data (G_OBJECT (dialog), "gimp-fill-entry"); + stroke_entry = g_object_get_data (G_OBJECT (dialog), "gimp-stroke-entry"); + stroke_editor = g_object_get_data (G_OBJECT (dialog), "gimp-stroke-editor"); + + g_object_get (vector_layer_options, + "fill-options", &fill_options, + NULL); + + g_object_get (vector_layer_options, + "stroke-desc", &stroke_desc, + NULL); + + g_object_get (stroke_desc, + "stroke-options", &stroke_options, + NULL); + + switch (response_id) + { + case RESPONSE_RESET: + { + GimpRGB *fill_color; + GimpRGB *stroke_color; + GimpStrokeOptions *stroke_options_copy; + + g_object_get (fill_options, + "foreground", &fill_color, + NULL); + gimp_color_button_set_color (fill_entry, fill_color); + + g_object_get (G_OBJECT (stroke_options), "foreground", &stroke_color, NULL); + gimp_color_button_set_color (stroke_entry, stroke_color); + + stroke_options_copy = gimp_config_duplicate (GIMP_CONFIG (stroke_options)); + g_object_set (stroke_editor, + "options", stroke_options_copy, + NULL); + g_object_unref (stroke_options_copy); + } + break; + + case GTK_RESPONSE_OK: + case GTK_RESPONSE_APPLY: + { + GimpRGB fill_color; + GimpRGB stroke_color; + + gimp_color_button_get_color (fill_entry, &fill_color); + g_object_set (fill_options, "foreground", &fill_color, NULL); + //g_object_set (G_OBJECT (item), "fill-options", fill_options, NULL); + + g_object_unref (stroke_options); + g_object_get (stroke_editor, "options", &stroke_options, NULL); + gimp_color_button_get_color (stroke_entry, &stroke_color); + g_object_set (stroke_options, "foreground", &stroke_color, NULL); + g_object_set (stroke_desc, "stroke-options", stroke_options, NULL); + + gimp_vector_layer_refresh (GIMP_VECTOR_LAYER (item)); + gimp_image_flush (image); + + if (response_id == GTK_RESPONSE_APPLY) + break; + } + + default: + gtk_widget_destroy (dialog); + break; + } + + g_object_unref (fill_options); + g_object_unref (stroke_desc); + g_object_unref (stroke_options); +} Index: app/dialogs/vector-layer-options-dialog.h =================================================================== --- app/dialogs/vector-layer-options-dialog.h (revision 0) +++ app/dialogs/vector-layer-options-dialog.h (revision 0) @@ -0,0 +1,33 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * Copyright (C) 2006 Henk Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __VECTOR_LAYER_OPTIONS_DIALOG_H__ +#define __VECTOR_LAYER_OPTIONS_DIALOG_H__ + + +GtkWidget * vector_layer_options_dialog_new (GimpItem *item, + GimpContext *context, + const gchar *title, + const gchar *stock_id, + const gchar *help_id, + GtkWidget *parent); + + +#endif /* __VECTOR_LAYER_OPTIONS_DIALOG_H__ */ Index: app/dialogs/Makefile.am =================================================================== --- app/dialogs/Makefile.am (revision 27379) +++ app/dialogs/Makefile.am (working copy) @@ -79,6 +79,8 @@ libappdialogs_a_sources = \ tips-parser.h \ user-install-dialog.c \ user-install-dialog.h \ + vector-layer-options-dialog.c \ + vector-layer-options-dialog.h \ vectors-export-dialog.c \ vectors-export-dialog.h \ vectors-import-dialog.c \ Index: app/vectors/gimpvectorlayeroptions-parasite.c =================================================================== --- app/vectors/gimpvectorlayeroptions-parasite.c (revision 0) +++ app/vectors/gimpvectorlayeroptions-parasite.c (revision 0) @@ -0,0 +1,93 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpText + * Copyright (C) 2003 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpconfig/gimpconfig.h" + +#include "vectors-types.h" + +#include "gimpvectorlayeroptions.h" +#include "gimpvectorlayeroptions-parasite.h" + +#include "gimp-intl.h" + + +const gchar * +gimp_vector_layer_options_parasite_name (void) +{ + return "gimp-vector-layer-options"; +} + +GimpParasite * +gimp_vector_layer_options_to_parasite (const GimpVectorLayerOptions *options) +{ + GimpParasite *parasite; + gchar *str; + + g_return_val_if_fail (GIMP_IS_VECTOR_LAYER_OPTIONS (options), NULL); + + str = gimp_config_serialize_to_string (GIMP_CONFIG (options), NULL); + g_return_val_if_fail (str != NULL, NULL); + + parasite = gimp_parasite_new (gimp_vector_layer_options_parasite_name (), + GIMP_PARASITE_PERSISTENT, + strlen (str) + 1, str); + g_free (str); + + return parasite; +} + +GimpVectorLayerOptions * +gimp_vector_layer_options_from_parasite (const GimpParasite *parasite, + GError **error, + Gimp *gimp) +{ + GimpVectorLayerOptions *options; + const gchar *str; + + g_return_val_if_fail (parasite != NULL, NULL); + g_return_val_if_fail (strcmp (gimp_parasite_name (parasite), + gimp_vector_layer_options_parasite_name ()) == 0, + NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + str = gimp_parasite_data (parasite); + g_return_val_if_fail (str != NULL, NULL); + + options = g_object_new (GIMP_TYPE_VECTOR_LAYER_OPTIONS, + "gimp", gimp, + NULL); + + gimp_config_deserialize_string (GIMP_CONFIG (options), + str, + gimp_parasite_data_size (parasite), + NULL, + error); + + return options; +} Index: app/vectors/gimpvectors.c =================================================================== --- app/vectors/gimpvectors.c (revision 27379) +++ app/vectors/gimpvectors.c (working copy) @@ -108,6 +108,7 @@ static void gimp_vectors_transform static gboolean gimp_vectors_stroke (GimpItem *item, GimpDrawable *drawable, GimpStrokeDesc *stroke_desc, + gboolean push_undo, GimpProgress *progress, GError **error); @@ -495,6 +496,7 @@ static gboolean gimp_vectors_stroke (GimpItem *item, GimpDrawable *drawable, GimpStrokeDesc *stroke_desc, + gboolean push_undo, GimpProgress *progress, GError **error) { @@ -510,7 +512,8 @@ gimp_vectors_stroke (GimpItem *it case GIMP_STROKE_METHOD_LIBART: gimp_drawable_stroke_vectors (drawable, stroke_desc->stroke_options, - vectors); + vectors, + push_undo); retval = TRUE; break; @@ -523,7 +526,7 @@ gimp_vectors_stroke (GimpItem *it retval = gimp_paint_core_stroke_vectors (core, drawable, stroke_desc->paint_options, stroke_desc->emulate_dynamics, - vectors, error); + vectors, push_undo, error); g_object_unref (core); } Index: app/vectors/gimpvectorlayeroptions-parasite.h =================================================================== --- app/vectors/gimpvectorlayeroptions-parasite.h (revision 0) +++ app/vectors/gimpvectorlayeroptions-parasite.h (revision 0) @@ -0,0 +1,33 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpVectorLayerOptions-parasite + * Copyright (C) 2006 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__ +#define __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__ + + +const gchar * gimp_vector_layer_options_parasite_name (void) G_GNUC_CONST; +GimpParasite * gimp_vector_layer_options_to_parasite (const GimpVectorLayerOptions *text); +GimpVectorLayerOptions * gimp_vector_layer_options_from_parasite (const GimpParasite *parasite, + GError **error, + Gimp *gimp); + + +#endif /* __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__ */ Index: app/vectors/gimpvectorlayer-xcf.c =================================================================== --- app/vectors/gimpvectorlayer-xcf.c (revision 0) +++ app/vectors/gimpvectorlayer-xcf.c (revision 0) @@ -0,0 +1,188 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpVectorLayer-xcf + * Copyright (C) 2003 Sven Neumann + * Copyright (C) 2006 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "vectors-types.h" + +#include "core/gimp.h" +#include "core/gimpimage.h" +#include "core/gimpparasitelist.h" + +#include "gimpvectorlayeroptions.h" +#include "gimpvectorlayeroptions-parasite.h" +#include "gimpvectorlayer.h" +#include "gimpvectorlayer-xcf.h" + +#include "gimp-intl.h" + + +static GimpLayer * gimp_vector_layer_from_layer (GimpLayer *layer, + GimpVectorLayerOptions *options); + + +gboolean +gimp_vector_layer_xcf_load_hack (GimpLayer **layer) +{ + const gchar *name; + GimpVectorLayerOptions *options = NULL; + const GimpParasite *parasite; + + g_return_val_if_fail (layer != NULL, FALSE); + g_return_val_if_fail (GIMP_IS_LAYER (*layer), FALSE); + + name = gimp_vector_layer_options_parasite_name (); + parasite = gimp_item_parasite_find (GIMP_ITEM (*layer), name); + + if (parasite) + { + GError *error = NULL; + + options = gimp_vector_layer_options_from_parasite ( + parasite, &error, GIMP_ITEM(*layer)->image->gimp); + + g_object_set (G_OBJECT (options), + "vectors", gimp_image_get_vectors_by_tattoo ( + gimp_item_get_image (GIMP_ITEM (*layer)), + options->vectors_tattoo), + NULL); + + if (error) + { + g_message (_("Problems parsing the vector layer parasite for layer '%s':\n" + "%s\n\n" + "Some vector layer properties may be wrong. "), + gimp_object_get_name (GIMP_OBJECT (*layer)), + error->message); + + g_error_free (error); + } + } + + if (options) + { + *layer = gimp_vector_layer_from_layer (*layer, options); + + /* let the text layer know what parasite was used to create it */ + GIMP_VECTOR_LAYER (*layer)->parasite = name; + } + + return (options != NULL); +} + +void +gimp_vector_layer_xcf_save_prepare (GimpVectorLayer *layer) +{ + GimpVectorLayerOptions *options; + + g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer)); + + /* If the layer has a text parasite already, it wasn't changed and we + * can simply save the original parasite back which is still attached. + */ + if (layer->parasite) + return; + + g_object_get (layer, "vector-layer-options", &options, NULL); + if (options) + { + GimpParasite *parasite = gimp_vector_layer_options_to_parasite (options); + + gimp_parasite_list_add (GIMP_ITEM (layer)->parasites, parasite); + } +} + +/** + * gimp_vector_layer_from_layer: + * @layer: a #GimpLayer object + * @options: a #GimpVectorLayerOptions object + * + * Converts a standard #GimpLayer and a #GimpVectorLayerOptions object + * into a #GimpVectorLayer. The new vector layer takes ownership of the + * @options and @layer objects. The @layer object is rendered unusable + * by this function. Don't even try to use if afterwards! + * + * This is a gross hack that is needed in order to load vector layers + * from XCF files in a backwards-compatible way. Please don't use it + * for anything else! + * + * Return value: a newly allocated #GimpVectorLayer object + **/ +static GimpLayer * +gimp_vector_layer_from_layer (GimpLayer *layer, + GimpVectorLayerOptions *options) +{ + GimpVectorLayer *vector_layer; + GimpItem *item; + GimpDrawable *drawable; + + g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL); + g_return_val_if_fail (GIMP_IS_VECTOR_LAYER_OPTIONS (options), NULL); + + vector_layer = g_object_new (GIMP_TYPE_VECTOR_LAYER, + "vector-layer-options", options, + NULL); + + item = GIMP_ITEM (vector_layer); + drawable = GIMP_DRAWABLE (vector_layer); + + gimp_object_set_name (GIMP_OBJECT (vector_layer), + gimp_object_get_name (GIMP_OBJECT (layer))); + + item->ID = gimp_item_get_ID (GIMP_ITEM (layer)); + item->tattoo = gimp_item_get_tattoo (GIMP_ITEM (layer)); + item->image = gimp_item_get_image (GIMP_ITEM (layer)); + + gimp_item_set_image (GIMP_ITEM (layer), NULL); + g_hash_table_replace (item->image->gimp->item_table, + GINT_TO_POINTER (item->ID), + item); + + item->parasites = GIMP_ITEM (layer)->parasites; + GIMP_ITEM (layer)->parasites = NULL; + + item->width = gimp_item_width (GIMP_ITEM (layer)); + item->height = gimp_item_height (GIMP_ITEM (layer)); + + gimp_item_offsets (GIMP_ITEM (layer), &item->offset_x, &item->offset_y); + + item->visible = gimp_item_get_visible (GIMP_ITEM (layer)); + item->linked = gimp_item_get_linked (GIMP_ITEM (layer)); + + drawable->tiles = GIMP_DRAWABLE (layer)->tiles; + GIMP_DRAWABLE (layer)->tiles = NULL; + + drawable->bytes = gimp_drawable_bytes (GIMP_DRAWABLE (layer)); + drawable->type = gimp_drawable_type (GIMP_DRAWABLE (layer)); + drawable->has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)); + + GIMP_LAYER (vector_layer)->opacity = gimp_layer_get_opacity (layer); + GIMP_LAYER (vector_layer)->mode = gimp_layer_get_mode (layer); + GIMP_LAYER (vector_layer)->lock_alpha = gimp_layer_get_lock_alpha (layer); + + g_object_unref (options); + g_object_unref (layer); + + return GIMP_LAYER (vector_layer); +} Index: app/vectors/gimpvectorlayer-xcf.h =================================================================== --- app/vectors/gimpvectorlayer-xcf.h (revision 0) +++ app/vectors/gimpvectorlayer-xcf.h (revision 0) @@ -0,0 +1,34 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpVectorLayer-xcf + * Copyright (C) 2003 Sven Neumann + * Copyright (C) 2006 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_VECTOR_LAYER_XCF_H__ +#define __GIMP_VECTOR_LAYER_XCF_H__ + + +const gchar * gimp_vector_layer_vector_parasite_name (void) G_GNUC_CONST; +const gchar * gimp_vector_layer_fill_parasite_name (void) G_GNUC_CONST; +const gchar * gimp_vector_layer_stroke_parasite_name (void) G_GNUC_CONST; +gboolean gimp_vector_layer_xcf_load_hack (GimpLayer **layer); +void gimp_vector_layer_xcf_save_prepare (GimpVectorLayer *layer); + + +#endif /* __GIMP_VECTOR_LAYER_XCF_H__ */ Index: app/vectors/gimpvectorlayer.c =================================================================== --- app/vectors/gimpvectorlayer.c (revision 0) +++ app/vectors/gimpvectorlayer.c (revision 0) @@ -0,0 +1,370 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpVectorLayer + * Copyright (C) 2006 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include + +#include "libgimpcolor/gimpcolor.h" +#include "libgimpconfig/gimpconfig.h" + +#include "vectors-types.h" + +#include "base/tile-manager.h" + +#include "core/gimp.h" +#include "core/gimpdrawable-stroke.h" +#include "core/gimpimage.h" +#include "core/gimpstrokedesc.h" +#include "core/gimpfilloptions.h" +#include "core/gimpparasitelist.h" + +#include "gimpvectorlayer.h" +#include "gimpvectorlayeroptions.h" +#include "gimpvectors.h" + +#include "gimp-intl.h" + + +enum +{ + PROP_0, + PROP_VECTOR_LAYER_OPTIONS +}; + + +/* local function declarations */ + +static void gimp_vector_layer_finalize (GObject *object); +static void gimp_vector_layer_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gimp_vector_layer_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + +static GimpItem * gimp_vector_layer_duplicate (GimpItem *item, + GType new_type); + +static gboolean gimp_vector_layer_render (GimpVectorLayer *layer); +static void gimp_vector_layer_render_vectors (GimpVectorLayer *layer, + GimpVectors *vectors); +static void gimp_vector_layer_refresh_name (GimpVectorLayer *layer); +static void gimp_vector_layer_changed_options (GimpVectorLayer *layer); + + +G_DEFINE_TYPE (GimpVectorLayer, gimp_vector_layer, GIMP_TYPE_LAYER) + +#define parent_class gimp_vector_layer_parent_class + + +static void +gimp_vector_layer_class_init (GimpVectorLayerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass); + GimpItemClass *item_class = GIMP_ITEM_CLASS (klass); + + object_class->finalize = gimp_vector_layer_finalize; + object_class->set_property = gimp_vector_layer_set_property; + object_class->get_property = gimp_vector_layer_get_property; + + viewable_class->default_stock_id = "gimp-vector-layer"; + + item_class->duplicate = gimp_vector_layer_duplicate; + item_class->default_name = _("Vector Layer"); + item_class->rename_desc = _("Rename Vector Layer"); + item_class->translate_desc = _("Move Vector Layer"); + item_class->scale_desc = _("Scale Vector Layer"); + item_class->resize_desc = _("Resize Vector Layer"); + item_class->flip_desc = _("Flip Vector Layer"); + item_class->rotate_desc = _("Rotate Vector Layer"); + item_class->transform_desc = _("Transform Vector Layer"); + + GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_VECTOR_LAYER_OPTIONS, + "vector-layer-options", NULL, + GIMP_TYPE_VECTOR_LAYER_OPTIONS, + GIMP_PARAM_STATIC_STRINGS); +} + +static void +gimp_vector_layer_init (GimpVectorLayer *layer) +{ + layer->options = NULL; + layer->parasite = NULL; +} + +static void +gimp_vector_layer_finalize (GObject *object) +{ + GimpVectorLayer *layer = GIMP_VECTOR_LAYER(object); + + if (layer->options) + { + g_object_unref (layer->options); + layer->options = NULL; + } + + if (layer->parasite) + { + gimp_parasite_list_remove (GIMP_ITEM (layer)->parasites, + layer->parasite); + layer->parasite = NULL; + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_vector_layer_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (object); + + switch (property_id) + { + case PROP_VECTOR_LAYER_OPTIONS: + g_value_set_object (value, vector_layer->options); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_vector_layer_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (object); + + switch (property_id) + { + case PROP_VECTOR_LAYER_OPTIONS: + if (vector_layer->options) + { + g_signal_handlers_disconnect_by_func (vector_layer->options, + G_CALLBACK (gimp_vector_layer_changed_options), + vector_layer); + g_object_unref (vector_layer->options); + } + vector_layer->options = (GimpVectorLayerOptions *) g_value_dup_object (value); + gimp_vector_layer_changed_options (vector_layer); + + if (vector_layer->options) + g_signal_connect_object (vector_layer->options, "notify", + G_CALLBACK (gimp_vector_layer_changed_options), + vector_layer, G_CONNECT_SWAPPED); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static GimpItem * +gimp_vector_layer_duplicate (GimpItem *item, + GType new_type) +{ + GimpItem *new_item; + + g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL); + + new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type); + + if (GIMP_IS_VECTOR_LAYER (new_item)) + { + GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item); + GimpVectorLayer *new_vector_layer = GIMP_VECTOR_LAYER (new_item); + + g_object_set (new_vector_layer, + "vector-layer-options", gimp_config_duplicate (GIMP_CONFIG (vector_layer->options)), + NULL); + } + + return new_item; +} + + +/* public functions */ + +/** + * gimp_vector_layer_new: + * @image: the #GimpImage the layer should belong to + * @vectors: the #GimpVectors object the layer should render + * @context: the #GimpContext from which to pull context properties + * + * Creates a new vector layer. + * + * Return value: a new #GimpVectorLayer or %NULL in case of a problem + **/ +GimpVectorLayer * +gimp_vector_layer_new (GimpImage *image, + GimpVectors *vectors, + GimpContext *context) +{ + GimpVectorLayer *layer; + GimpVectorLayerOptions *options; + + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); + + options = gimp_vector_layer_options_new (image, vectors, context); + + layer = g_object_new (GIMP_TYPE_VECTOR_LAYER, + "vector-layer-options", options, + NULL); + + gimp_drawable_configure (GIMP_DRAWABLE (layer), + image, + 0, 0, 1, 1, /* x and y offsets, x and y dimensions */ + gimp_image_base_type_with_alpha (image), + NULL); + return layer; +} + +void +gimp_vector_layer_refresh (GimpVectorLayer *layer) +{ + if (layer->options) + { + gimp_vector_layer_refresh_name (layer); + gimp_vector_layer_render (layer); + } +} + +/** + * gimp_vector_layer_discard: + * @layer: a #GimpVectorLayer + * + * Discards the vector information. This makes @layer behave like a + * normal layer. + */ +void +gimp_vector_layer_discard (GimpVectorLayer *layer) +{ + g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer)); + g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer))); + + if (! layer->options) + return; + + /* TODO: undo step here */ + + g_object_set (layer, "vector-layer-options", NULL, NULL); +} + +gboolean +gimp_drawable_is_vector_layer (GimpDrawable *drawable) +{ + return (GIMP_IS_VECTOR_LAYER (drawable) && + GIMP_VECTOR_LAYER (drawable)->options); +} + + +/* private functions */ + +static gboolean +gimp_vector_layer_render (GimpVectorLayer *layer) +{ + GimpDrawable *drawable = GIMP_DRAWABLE (layer); + GimpItem *item = GIMP_ITEM (layer); + GimpImage *image = gimp_item_get_image (item); + gint width = gimp_image_get_width (image); + gint height = gimp_image_get_height (image); + GimpRGB blank; + + g_return_val_if_fail(gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE); + + g_object_freeze_notify (G_OBJECT (drawable)); + + gimp_drawable_configure (GIMP_DRAWABLE (layer), + image, + 0, 0, width, height, + gimp_image_base_type_with_alpha (image), + NULL); + + /* make the layer background transparent */ + gimp_rgba_set (&blank, 1.0, 1.0, 1.0, 0.0); + + gimp_drawable_fill (GIMP_DRAWABLE (layer), &blank, NULL); + + /* render vectors to the layer */ + gimp_vector_layer_render_vectors (layer, layer->options->vectors); + + g_object_thaw_notify (G_OBJECT (drawable)); + + return TRUE; +} + +static void +gimp_vector_layer_render_vectors (GimpVectorLayer *layer, + GimpVectors *vectors) +{ + /* fill the vectors object onto the layer */ + gimp_drawable_fill_vectors (GIMP_DRAWABLE (layer), + GIMP_FILL_OPTIONS (layer->options->fill_options), + vectors, + FALSE); + + /* stroke the vectors object onto the layer */ + gimp_item_stroke (GIMP_ITEM (vectors), + GIMP_DRAWABLE (layer), + gimp_get_user_context (gimp_item_get_image (GIMP_ITEM (layer))->gimp), + layer->options->stroke_desc, + FALSE, FALSE, + NULL, NULL); +} + +/* sets the layer's name to be the same as the vector's name */ +static void +gimp_vector_layer_refresh_name (GimpVectorLayer *layer) +{ + gimp_object_set_name_safe (GIMP_OBJECT (layer), + gimp_object_get_name (GIMP_OBJECT(layer->options->vectors))); +} + +static void +gimp_vector_layer_changed_options (GimpVectorLayer *layer) +{ + GimpItem *item = GIMP_ITEM (layer); + + if (layer->parasite) + { + /* parasite is out of date, discard it */ + gimp_parasite_list_remove (GIMP_ITEM (layer)->parasites, + layer->parasite); + layer->parasite = NULL; + } + + if (layer->options && !layer->options->vectors) + gimp_vector_layer_discard (layer); + else if (gimp_item_is_attached (item)) + gimp_vector_layer_refresh (layer); +} Index: app/vectors/gimpvectorlayer.h =================================================================== --- app/vectors/gimpvectorlayer.h (revision 0) +++ app/vectors/gimpvectorlayer.h (revision 0) @@ -0,0 +1,64 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpVectorLayer + * Copyright (C) 2006 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_VECTOR_LAYER_H__ +#define __GIMP_VECTOR_LAYER_H__ + + +#include "core/gimplayer.h" + + +#define GIMP_TYPE_VECTOR_LAYER (gimp_vector_layer_get_type ()) +#define GIMP_VECTOR_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTOR_LAYER, GimpVectorLayer)) +#define GIMP_VECTOR_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTOR_LAYER, GimpVectorLayerClass)) +#define GIMP_IS_VECTOR_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_VECTOR_LAYER)) +#define GIMP_IS_VECTOR_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_VECTOR_LAYER)) +#define GIMP_VECTOR_LAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_VECTOR_LAYER, GimpVectorLayerClass)) + + +typedef struct _GimpVectorLayerClass GimpVectorLayerClass; + +struct _GimpVectorLayer +{ + GimpLayer parent_instance; + + GimpVectorLayerOptions *options; + const gchar *parasite; +}; + +struct _GimpVectorLayerClass +{ + GimpLayerClass parent_class; +}; + + +GType gimp_vector_layer_get_type (void) G_GNUC_CONST; + +GimpVectorLayer * gimp_vector_layer_new (GimpImage *image, + GimpVectors *vectors, + GimpContext *context); +void gimp_vector_layer_refresh (GimpVectorLayer *layer); +void gimp_vector_layer_discard (GimpVectorLayer *layer); + +gboolean gimp_drawable_is_vector_layer (GimpDrawable *drawable); + + +#endif /* __GIMP_VECTOR_LAYER_H__ */ Index: app/vectors/gimpvectorlayeroptions.c =================================================================== --- app/vectors/gimpvectorlayeroptions.c (revision 0) +++ app/vectors/gimpvectorlayeroptions.c (revision 0) @@ -0,0 +1,363 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpVectorLayerOptions + * Copyright (C) 2006 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpconfig/gimpconfig.h" + +#include "libgimpcolor/gimpcolor.h" + +#include "vectors-types.h" + +#include "core/gimp.h" +#include "core/gimpimage.h" +#include "core/gimpstrokedesc.h" +#include "core/gimpfilloptions.h" + +#include "gimpvectors.h" +#include "gimpvectorlayer.h" +#include "gimpvectorlayeroptions.h" + +#include "gimp-intl.h" + + +enum +{ + PROP_0, + PROP_GIMP, + PROP_VECTORS, + PROP_VECTORS_TATTOO, + PROP_FILL_OPTIONS, + PROP_STROKE_DESC +}; + + +/* local function declarations */ + +static GObject *gimp_vector_layer_options_constructor (GType type, + guint n_params, + GObjectConstructParam *params); +static void gimp_vector_layer_options_finalize (GObject *object); + +static void gimp_vector_layer_options_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gimp_vector_layer_options_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_vector_layer_options_emit_vectors_changed + (GimpVectorLayerOptions *options); +static void gimp_vector_layer_options_vectors_removed + (GimpVectorLayerOptions *options); + + +G_DEFINE_TYPE_WITH_CODE (GimpVectorLayerOptions, + gimp_vector_layer_options, + GIMP_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL)) + +#define parent_class gimp_vector_layer_options_parent_class + + +static void +gimp_vector_layer_options_class_init (GimpVectorLayerOptionsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructor = gimp_vector_layer_options_constructor; + object_class->finalize = gimp_vector_layer_options_finalize; + object_class->set_property = gimp_vector_layer_options_set_property; + object_class->get_property = gimp_vector_layer_options_get_property; + + g_object_class_install_property (object_class, PROP_GIMP, + g_param_spec_object ("gimp", + NULL, NULL, + GIMP_TYPE_GIMP, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_VECTORS, + g_param_spec_object ("vectors", + NULL, NULL, + GIMP_TYPE_VECTORS, + G_PARAM_CONSTRUCT | + GIMP_PARAM_READWRITE | + GIMP_PARAM_STATIC_STRINGS)); + +#if 0 + g_object_class_install_property (object_class, PROP_VECTORS_TATTOO, + g_param_spec_uint ("vectors-tattoo", + NULL, NULL, + 0, G_MAXUINT32, 0, + GIMP_PARAM_READABLE | + GIMP_CONFIG_PARAM_SERIALIZE | + GIMP_PARAM_STATIC_STRINGS)); +#endif + + GIMP_CONFIG_INSTALL_PROP_UINT (object_class, PROP_VECTORS_TATTOO, + "vectors-tattoo", NULL, 0, G_MAXUINT32, 0, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_FILL_OPTIONS, + "fill-options", NULL, + GIMP_TYPE_FILL_OPTIONS, + GIMP_PARAM_STATIC_STRINGS | + GIMP_CONFIG_PARAM_AGGREGATE); + + GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_STROKE_DESC, + "stroke-desc", NULL, + GIMP_TYPE_STROKE_DESC, + GIMP_PARAM_STATIC_STRINGS | + GIMP_CONFIG_PARAM_AGGREGATE); +} + +static void +gimp_vector_layer_options_init (GimpVectorLayerOptions *options) +{ + options->vectors = NULL; + options->vectors_tattoo = 0; +} + +static GObject * +gimp_vector_layer_options_constructor (GType type, + guint n_params, + GObjectConstructParam *params) +{ + GObject *object; + GimpVectorLayerOptions *options; + + object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params); + + options = GIMP_VECTOR_LAYER_OPTIONS (object); + g_assert (GIMP_IS_GIMP (options->gimp)); + + options->fill_options = g_object_new (GIMP_TYPE_FILL_OPTIONS, + "gimp", options->gimp, + NULL); + + options->stroke_desc = gimp_stroke_desc_new (options->gimp, NULL); + + return object; +} + +static void +gimp_vector_layer_options_finalize (GObject *object) +{ + GimpVectorLayerOptions *options = GIMP_VECTOR_LAYER_OPTIONS (object); + + if (options->vectors) + { + g_object_unref (options->vectors); + options->vectors = NULL; + } + + if (options->fill_options) + { + g_object_unref (options->fill_options); + options->fill_options = NULL; + } + + if (options->stroke_desc) + { + g_object_unref (options->stroke_desc); + options->stroke_desc = NULL; + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_vector_layer_options_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpVectorLayerOptions *options = GIMP_VECTOR_LAYER_OPTIONS (object); + + switch (property_id) + { + case PROP_GIMP: + g_value_set_object (value, options->gimp); + break; + case PROP_VECTORS: + g_value_set_object (value, options->vectors); + break; + case PROP_VECTORS_TATTOO: + g_value_set_uint (value, options->vectors_tattoo); + break; + case PROP_FILL_OPTIONS: + g_value_set_object (value, options->fill_options); + break; + case PROP_STROKE_DESC: + g_value_set_object (value, options->stroke_desc); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_vector_layer_options_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpVectorLayerOptions *options = GIMP_VECTOR_LAYER_OPTIONS (object); + + switch (property_id) + { + case PROP_GIMP: + options->gimp = g_value_get_object (value); + break; + case PROP_VECTORS: + if (options->vectors) + { + g_signal_handlers_disconnect_by_func (options->vectors, + G_CALLBACK (gimp_vector_layer_options_emit_vectors_changed), + options); + g_signal_handlers_disconnect_by_func (options->vectors, + G_CALLBACK (gimp_vector_layer_options_vectors_removed), + options); + g_object_unref (options->vectors); + } + options->vectors = (GimpVectors *) g_value_dup_object (value); + + if (options->vectors) + { + g_signal_connect_object (options->vectors, "invalidate-preview", + G_CALLBACK (gimp_vector_layer_options_emit_vectors_changed), + options, G_CONNECT_SWAPPED); + g_signal_connect_object (options->vectors, "name-changed", + G_CALLBACK (gimp_vector_layer_options_emit_vectors_changed), + options, G_CONNECT_SWAPPED); + g_signal_connect_object (options->vectors, "removed", + G_CALLBACK (gimp_vector_layer_options_vectors_removed), + options, G_CONNECT_SWAPPED); + + /* update the tattoo */ + options->vectors_tattoo = gimp_item_get_tattoo (GIMP_ITEM (options->vectors)); + } + break; + case PROP_VECTORS_TATTOO: + options->vectors_tattoo = g_value_get_uint (value); + + if (options->vectors && + gimp_item_get_tattoo (GIMP_ITEM (options->vectors)) != options->vectors_tattoo) + { + GimpImage *image = gimp_item_get_image (GIMP_ITEM (options->vectors)); + + g_object_set (options, + "vectors", gimp_image_get_vectors_by_tattoo + (image, options->vectors_tattoo), + NULL); + } + break; + case PROP_FILL_OPTIONS: + if (g_value_get_object (value)) + { + gimp_config_sync (g_value_get_object (value), + G_OBJECT (options->fill_options), 0); + } + break; + case PROP_STROKE_DESC: + if (g_value_get_object (value)) + { + if (options->stroke_desc) + g_object_unref (options->stroke_desc); + options->stroke_desc = gimp_config_duplicate (g_value_get_object (value)); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_vector_layer_options_emit_vectors_changed (GimpVectorLayerOptions *options) +{ + g_object_notify (G_OBJECT (options), "vectors"); +} + +static void +gimp_vector_layer_options_vectors_removed (GimpVectorLayerOptions *options) +{ + g_object_set (options, "vectors", NULL, NULL); +} + + +/* public functions */ + +/** + * gimp_vector_layer_options_new: + * @image: the #GimpImage the layer belongs to + * @vectors: the #GimpVectors object for the layer to render + * @context: the #GimpContext from which to pull context properties + * + * Creates a new vector layer options. + * + * Return value: a new #GimpVectorLayerOptions or %NULL in case of a problem + **/ +GimpVectorLayerOptions * +gimp_vector_layer_options_new (GimpImage *image, + GimpVectors *vectors, + GimpContext *context) +{ + GimpVectorLayerOptions *options; + GimpPattern *pattern; + GimpRGB stroke_color; + GimpRGB fill_color; + + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); + + options = g_object_new (GIMP_TYPE_VECTOR_LAYER_OPTIONS, + "gimp", image->gimp, + NULL); + + gimp_context_get_foreground (context, &stroke_color); + gimp_context_get_background (context, &fill_color); + pattern = gimp_context_get_pattern (context); + + g_object_set (options->fill_options, + "foreground", &fill_color, + NULL); + gimp_context_set_pattern (GIMP_CONTEXT (options->fill_options), pattern); + + g_object_set (options->stroke_desc->stroke_options, + "foreground", &stroke_color, + "width", 3.0, + NULL); + gimp_context_set_pattern (GIMP_CONTEXT (options->stroke_desc->stroke_options), pattern); + + g_object_set (options, + "vectors", vectors, + NULL); + + return options; +} Index: app/vectors/Makefile.am =================================================================== --- app/vectors/Makefile.am (revision 27379) +++ app/vectors/Makefile.am (working copy) @@ -26,6 +26,14 @@ libappvectors_a_SOURCES = \ gimpstroke.c \ gimpstroke-new.h \ gimpstroke-new.c \ + gimpvectorlayer.h \ + gimpvectorlayer.c \ + gimpvectorlayer-xcf.h \ + gimpvectorlayer-xcf.c \ + gimpvectorlayeroptions.h \ + gimpvectorlayeroptions.c \ + gimpvectorlayeroptions-parasite.h \ + gimpvectorlayeroptions-parasite.c \ gimpvectors.c \ gimpvectors.h \ gimpvectors-compat.c \ Index: app/vectors/vectors-types.h =================================================================== --- app/vectors/vectors-types.h (revision 27379) +++ app/vectors/vectors-types.h (working copy) @@ -26,14 +26,17 @@ #include "vectors/vectors-enums.h" -typedef struct _GimpAnchor GimpAnchor; +typedef struct _GimpAnchor GimpAnchor; -typedef struct _GimpVectors GimpVectors; -typedef struct _GimpVectorsUndo GimpVectorsUndo; -typedef struct _GimpVectorsModUndo GimpVectorsModUndo; -typedef struct _GimpVectorsPropUndo GimpVectorsPropUndo; -typedef struct _GimpStroke GimpStroke; -typedef struct _GimpBezierStroke GimpBezierStroke; +typedef struct _GimpVectors GimpVectors; +typedef struct _GimpVectorsUndo GimpVectorsUndo; +typedef struct _GimpVectorsModUndo GimpVectorsModUndo; +typedef struct _GimpVectorsPropUndo GimpVectorsPropUndo; +typedef struct _GimpStroke GimpStroke; +typedef struct _GimpBezierStroke GimpBezierStroke; + +typedef struct _GimpVectorLayer GimpVectorLayer; +typedef struct _GimpVectorLayerOptions GimpVectorLayerOptions; /* * The following hack is made so that we can reuse the definition Index: app/vectors/gimpvectorlayeroptions.h =================================================================== --- app/vectors/gimpvectorlayeroptions.h (revision 0) +++ app/vectors/gimpvectorlayeroptions.h (revision 0) @@ -0,0 +1,62 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * GimpVectorLayerOptions + * Copyright (C) 2006 Hendrik Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_VECTOR_LAYER_OPTIONS_H__ +#define __GIMP_VECTOR_LAYER_OPTIONS_H__ + + +#include "core/gimpobject.h" + + +#define GIMP_TYPE_VECTOR_LAYER_OPTIONS (gimp_vector_layer_options_get_type ()) +#define GIMP_VECTOR_LAYER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTOR_LAYER_OPTIONS, GimpVectorLayerOptions)) +#define GIMP_VECTOR_LAYER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTOR_LAYER_OPTIONS, GimpVectorLayerOptionsClass)) +#define GIMP_IS_VECTOR_LAYER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_VECTOR_LAYER_OPTIONS)) +#define GIMP_IS_VECTOR_LAYER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_VECTOR_LAYER_OPTIONS)) +#define GIMP_VECTOR_LAYER_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_VECTOR_LAYER_OPTIONS, GimpVectorLayerOptionsClass)) + + +typedef struct _GimpVectorLayerOptionsClass GimpVectorLayerOptionsClass; + +struct _GimpVectorLayerOptions +{ + GimpObject parent_instance; + + Gimp *gimp; + GimpTattoo vectors_tattoo; + GimpVectors *vectors; + GimpFillOptions *fill_options; + GimpStrokeDesc *stroke_desc; +}; + +struct _GimpVectorLayerOptionsClass +{ + GimpObjectClass parent_class; +}; + +GType gimp_vector_layer_options_get_type (void) G_GNUC_CONST; + +GimpVectorLayerOptions * gimp_vector_layer_options_new (GimpImage *image, + GimpVectors *vectors, + GimpContext *context); + + +#endif /* __GIMP_VECTOR_LAYER_OPTIONS_H__ */ Index: app/actions/layers-actions.c =================================================================== --- app/actions/layers-actions.c (revision 27379) +++ app/actions/layers-actions.c (working copy) @@ -32,6 +32,8 @@ #include "text/gimptextlayer.h" +#include "vectors/gimpvectorlayer.h" + #include "widgets/gimphelp-ids.h" #include "widgets/gimpactiongroup.h" @@ -64,6 +66,12 @@ static const GimpActionEntry layers_acti N_("Activate the text tool on this text layer"), G_CALLBACK (layers_text_tool_cmd_callback), GIMP_HELP_TOOL_TEXT }, + + { "layers-vector-tool", GIMP_STOCK_TOOL_PATH, + N_("Path Tool"), NULL, + N_("Activate the path tool on this vector layer's path"), + G_CALLBACK (layers_vector_tool_cmd_callback), + GIMP_HELP_TOOL_PATH }, { "layers-edit-attributes", GTK_STOCK_EDIT, N_("_Edit Layer Attributes..."), NULL, @@ -167,6 +175,18 @@ static const GimpActionEntry layers_acti G_CALLBACK (layers_text_along_vectors_cmd_callback), GIMP_HELP_LAYER_TEXT_ALONG_PATH }, + { "layers-vector-fill-stroke", NULL, + N_("Fill / Stroke"), NULL, + N_("Edit the fill and stroke of this vector layer"), + G_CALLBACK (layers_vector_fill_stroke_cmd_callback), + NULL }, + + { "layers-vector-discard", NULL, + N_("Discard Vector Information"), NULL, + N_("Turn this vector layer into a normal layer"), + G_CALLBACK (layers_vector_discard_cmd_callback), + NULL }, + { "layers-resize", GIMP_STOCK_RESIZE, N_("Layer B_oundary Size..."), NULL, N_("Adjust the layer dimensions"), @@ -467,18 +487,19 @@ void layers_actions_update (GimpActionGroup *group, gpointer data) { - GimpImage *image = action_data_get_image (data); - GimpLayer *layer = NULL; - GimpLayerMask *mask = NULL; /* layer mask */ - gboolean fs = FALSE; /* floating sel */ - gboolean ac = FALSE; /* active channel */ - gboolean sel = FALSE; - gboolean alpha = FALSE; /* alpha channel present */ - gboolean indexed = FALSE; /* is indexed */ - gboolean lock_alpha = FALSE; - gboolean text_layer = FALSE; - GList *next = NULL; - GList *prev = NULL; + GimpImage *image = action_data_get_image (data); + GimpLayer *layer = NULL; + GimpLayerMask *mask = NULL; /* layer mask */ + gboolean fs = FALSE; /* floating sel */ + gboolean ac = FALSE; /* active channel */ + gboolean sel = FALSE; + gboolean alpha = FALSE; /* alpha channel present */ + gboolean indexed = FALSE; /* is indexed */ + gboolean lock_alpha = FALSE; + gboolean text_layer = FALSE; + gboolean vector_layer = FALSE; + GList *next = NULL; + GList *prev = NULL; if (image) { @@ -506,7 +527,10 @@ layers_actions_update (GimpActionGroup * } if (layer) + { text_layer = gimp_drawable_is_text_layer (GIMP_DRAWABLE (layer)); + vector_layer = gimp_drawable_is_vector_layer (GIMP_DRAWABLE (layer)); + } } } @@ -518,6 +542,7 @@ layers_actions_update (GimpActionGroup * gimp_action_group_set_action_active (group, action, (condition) != 0) SET_VISIBLE ("layers-text-tool", text_layer && !ac); + SET_VISIBLE ("layers-vector-tool", vector_layer && !ac); SET_SENSITIVE ("layers-edit-attributes", layer && !fs && !ac); SET_SENSITIVE ("layers-new", image); @@ -549,6 +574,9 @@ layers_actions_update (GimpActionGroup * SET_VISIBLE ("layers-text-selection-subtract", text_layer && !ac); SET_VISIBLE ("layers-text-selection-intersect", text_layer && !ac); + SET_VISIBLE ("layers-vector-fill-stroke", vector_layer && !ac); + SET_VISIBLE ("layers-vector-discard", vector_layer && !ac); + SET_SENSITIVE ("layers-resize", layer && !ac); SET_SENSITIVE ("layers-resize-to-image", layer && !ac); SET_SENSITIVE ("layers-scale", layer && !ac); Index: app/actions/vectors-commands.c =================================================================== --- app/actions/vectors-commands.c (revision 27379) +++ app/actions/vectors-commands.c (working copy) @@ -36,6 +36,7 @@ #include "core/gimpimage-merge.h" #include "core/gimpimage-undo.h" #include "core/gimpitemundo.h" +#include "core/gimplayer.h" #include "core/gimpparamspecs.h" #include "core/gimpprogress.h" #include "core/gimpstrokedesc.h" @@ -47,6 +48,7 @@ #include "vectors/gimpvectors.h" #include "vectors/gimpvectors-export.h" #include "vectors/gimpvectors-import.h" +#include "vectors/gimpvectorlayer.h" #include "widgets/gimpaction.h" #include "widgets/gimpclipboard.h" @@ -291,6 +293,23 @@ vectors_merge_visible_cmd_callback (GtkA } void +vectors_to_vector_layer_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpImage *image; + GimpVectors *vectors; + GimpVectorLayer *layer; + return_if_no_vectors (image, vectors, data); + + layer = gimp_vector_layer_new (image, vectors, + gimp_get_user_context (image->gimp)); + gimp_image_add_layer (image, GIMP_LAYER (layer), -1, TRUE); + gimp_vector_layer_refresh (layer); + + gimp_image_flush (image); +} + +void vectors_to_selection_cmd_callback (GtkAction *action, gint value, gpointer data) @@ -423,7 +442,7 @@ vectors_stroke_last_vals_cmd_callback (G desc = gimp_stroke_desc_new (image->gimp, context); if (! gimp_item_stroke (GIMP_ITEM (vectors), drawable, context, desc, FALSE, - NULL, &error)) + TRUE, NULL, &error)) { gimp_message (image->gimp, G_OBJECT (widget), GIMP_MESSAGE_WARNING, error->message); Index: app/actions/vectors-commands.h =================================================================== --- app/actions/vectors-commands.h (revision 27379) +++ app/actions/vectors-commands.h (working copy) @@ -44,6 +44,8 @@ void vectors_delete_cmd_callback gpointer data); void vectors_merge_visible_cmd_callback (GtkAction *action, gpointer data); +void vectors_to_vector_layer_cmd_callback (GtkAction *action, + gpointer data); void vectors_to_selection_cmd_callback (GtkAction *action, gint value, gpointer data); Index: app/actions/select-commands.c =================================================================== --- app/actions/select-commands.c (revision 27379) +++ app/actions/select-commands.c (working copy) @@ -372,7 +372,7 @@ select_stroke_last_vals_cmd_callback (Gt desc = gimp_stroke_desc_new (image->gimp, context); if (! gimp_item_stroke (GIMP_ITEM (gimp_image_get_mask (image)), - drawable, context, desc, FALSE, NULL, &error)) + drawable, context, desc, FALSE, TRUE, NULL, &error)) { gimp_message (image->gimp, G_OBJECT (widget), GIMP_MESSAGE_WARNING, error->message); Index: app/actions/layers-commands.c =================================================================== --- app/actions/layers-commands.c (revision 27379) +++ app/actions/layers-commands.c (working copy) @@ -34,6 +34,7 @@ #include "core/gimp.h" #include "core/gimpchannel-select.h" #include "core/gimpcontext.h" +#include "core/gimpcontainer.h" #include "core/gimpimage.h" #include "core/gimpimage-merge.h" #include "core/gimpimage-undo.h" @@ -51,6 +52,8 @@ #include "text/gimptext-vectors.h" #include "text/gimptextlayer.h" +#include "vectors/gimpvectorlayer.h" +#include "vectors/gimpvectorlayeroptions.h" #include "vectors/gimpvectors-warp.h" #include "widgets/gimpaction.h" @@ -62,12 +65,14 @@ #include "display/gimpdisplayshell.h" #include "tools/gimptexttool.h" +#include "tools/gimpvectortool.h" #include "tools/tool_manager.h" #include "dialogs/layer-add-mask-dialog.h" #include "dialogs/layer-options-dialog.h" #include "dialogs/resize-dialog.h" #include "dialogs/scale-dialog.h" +#include "dialogs/vector-layer-options-dialog.h" #include "actions.h" #include "layers-commands.h" @@ -185,6 +190,45 @@ layers_text_tool_cmd_callback (GtkAction } void +layers_vector_tool_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpImage *image; + GimpLayer *layer; + GtkWidget *widget; + GimpTool *active_tool; + return_if_no_layer (image, layer, data); + return_if_no_widget (widget, data); + + if (! gimp_drawable_is_vector_layer (GIMP_DRAWABLE (layer))) + { + layers_edit_attributes_cmd_callback (action, data); + return; + } + + active_tool = tool_manager_get_active (image->gimp); + + if (! GIMP_IS_VECTOR_TOOL (active_tool)) + { + GimpToolInfo *tool_info; + + tool_info = (GimpToolInfo *) + gimp_container_get_child_by_name (image->gimp->tool_info_list, + "gimp-vector-tool"); + + if (GIMP_IS_TOOL_INFO (tool_info)) + { + gimp_context_set_tool (action_data_get_context (data), tool_info); + active_tool = tool_manager_get_active (image->gimp); + } + } + + if (GIMP_IS_VECTOR_TOOL (active_tool)) + gimp_vector_tool_set_vectors (GIMP_VECTOR_TOOL (active_tool), + GIMP_VECTOR_LAYER (layer)->options->vectors); +} + +void layers_edit_attributes_cmd_callback (GtkAction *action, gpointer data) { @@ -554,6 +598,38 @@ layers_text_along_vectors_cmd_callback ( } void +layers_vector_fill_stroke_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpImage *image; + GimpLayer *layer; + GtkWidget *widget; + GtkWidget *dialog; + return_if_no_layer (image, layer, data); + return_if_no_widget (widget, data); + + dialog = vector_layer_options_dialog_new (GIMP_ITEM (layer), + action_data_get_context (data), + _("Fill / Stroke"), + GTK_STOCK_OK, + NULL, + widget); + gtk_widget_show (dialog); +} + +void +layers_vector_discard_cmd_callback (GtkAction *action, + gpointer data) +{ + GimpImage *image; + GimpLayer *layer; + return_if_no_layer (image, layer, data); + + if (GIMP_IS_VECTOR_LAYER (layer)) + gimp_vector_layer_discard (GIMP_VECTOR_LAYER (layer)); +} + +void layers_resize_cmd_callback (GtkAction *action, gpointer data) { Index: app/actions/layers-commands.h =================================================================== --- app/actions/layers-commands.h (revision 27379) +++ app/actions/layers-commands.h (working copy) @@ -22,6 +22,8 @@ void layers_text_tool_cmd_callback (GtkAction *action, gpointer data); +void layers_vector_tool_cmd_callback (GtkAction *action, + gpointer data); void layers_edit_attributes_cmd_callback (GtkAction *action, gpointer data); @@ -60,6 +62,11 @@ void layers_text_to_vectors_cmd_callba void layers_text_along_vectors_cmd_callback (GtkAction *action, gpointer data); +void layers_vector_fill_stroke_cmd_callback (GtkAction *action, + gpointer data); +void layers_vector_discard_cmd_callback (GtkAction *action, + gpointer data); + void layers_resize_cmd_callback (GtkAction *action, gpointer data); void layers_resize_to_image_cmd_callback (GtkAction *action, Index: app/actions/vectors-actions.c =================================================================== --- app/actions/vectors-actions.c (revision 27379) +++ app/actions/vectors-actions.c (working copy) @@ -139,7 +139,12 @@ static const GimpActionEntry vectors_act { "vectors-import", GTK_STOCK_OPEN, N_("I_mport Path..."), "", NULL, G_CALLBACK (vectors_import_cmd_callback), - GIMP_HELP_PATH_IMPORT } + GIMP_HELP_PATH_IMPORT }, + + { "vectors-to-vector-layer", NULL, + N_("Path to Vector Layer"), "", NULL, + G_CALLBACK (vectors_to_vector_layer_cmd_callback), + NULL } }; static const GimpToggleActionEntry vectors_toggle_actions[] = @@ -296,6 +301,8 @@ vectors_actions_update (GimpActionGroup SET_SENSITIVE ("vectors-paste", image); SET_SENSITIVE ("vectors-export", vectors); SET_SENSITIVE ("vectors-import", image); + + SET_SENSITIVE ("vectors-to-vector-layer", vectors); SET_SENSITIVE ("vectors-visible", vectors); SET_SENSITIVE ("vectors-linked", vectors); Index: app/pdb/paths-cmds.c =================================================================== --- app/pdb/paths-cmds.c (revision 27379) +++ app/pdb/paths-cmds.c (working copy) @@ -338,8 +338,8 @@ path_stroke_current_invoker (GimpProcedu g_object_set (desc, "method", GIMP_STROKE_METHOD_PAINT_CORE, NULL); success = gimp_item_stroke (GIMP_ITEM (vectors), - drawable, context, desc, TRUE, progress, - error); + drawable, context, desc, TRUE, TRUE, + progress, error); g_object_unref (desc); } Index: app/pdb/paint-tools-cmds.c =================================================================== --- app/pdb/paint-tools-cmds.c (revision 27379) +++ app/pdb/paint-tools-cmds.c (working copy) @@ -83,7 +83,7 @@ paint_tools_stroke (Gimp *g } retval = gimp_paint_core_stroke (core, drawable, options, - coords, n_strokes, + coords, n_strokes, TRUE, error); g_free (coords); Index: app/pdb/edit-cmds.c =================================================================== --- app/pdb/edit-cmds.c (revision 27379) +++ app/pdb/edit-cmds.c (working copy) @@ -752,8 +752,8 @@ edit_stroke_invoker (GimpProcedure g_object_set (desc, "method", GIMP_STROKE_METHOD_PAINT_CORE, NULL); success = gimp_item_stroke (GIMP_ITEM (gimp_image_get_mask (image)), - drawable, context, desc, TRUE, progress, - error); + drawable, context, desc, TRUE, TRUE, + progress, error); g_object_unref (desc); } @@ -790,8 +790,8 @@ edit_stroke_vectors_invoker (GimpProcedu g_object_set (desc, "method", GIMP_STROKE_METHOD_PAINT_CORE, NULL); success = gimp_item_stroke (GIMP_ITEM (vectors), - drawable, context, desc, TRUE, progress, - error); + drawable, context, desc, TRUE, TRUE, + progress, error); g_object_unref (desc); } Index: app/paint/gimppaintcore-stroke.c =================================================================== --- app/paint/gimppaintcore-stroke.c (revision 27379) +++ app/paint/gimppaintcore-stroke.c (working copy) @@ -46,6 +46,7 @@ gimp_paint_core_stroke (GimpPaintCore GimpPaintOptions *paint_options, GimpCoords *strokes, gint n_strokes, + gboolean push_undo, GError **error) { g_return_val_if_fail (GIMP_IS_PAINT_CORE (core), FALSE); @@ -80,7 +81,7 @@ gimp_paint_core_stroke (GimpPaintCore gimp_paint_core_paint (core, drawable, paint_options, GIMP_PAINT_STATE_FINISH, 0); - gimp_paint_core_finish (core, drawable); + gimp_paint_core_finish (core, drawable, push_undo); gimp_paint_core_cleanup (core); @@ -99,6 +100,7 @@ gimp_paint_core_stroke_boundary (GimpPai gint n_bound_segs, gint offset_x, gint offset_y, + gboolean push_undo, GError **error) { GimpImage *image; @@ -212,7 +214,7 @@ gimp_paint_core_stroke_boundary (GimpPai if (initialized) { - gimp_paint_core_finish (core, drawable); + gimp_paint_core_finish (core, drawable, push_undo); gimp_paint_core_cleanup (core); } @@ -229,6 +231,7 @@ gimp_paint_core_stroke_vectors (GimpPain GimpPaintOptions *paint_options, gboolean emulate_dynamics, GimpVectors *vectors, + gboolean push_undo, GError **error) { GList *stroke; @@ -313,7 +316,7 @@ gimp_paint_core_stroke_vectors (GimpPain if (initialized) { - gimp_paint_core_finish (core, drawable); + gimp_paint_core_finish (core, drawable, push_undo); gimp_paint_core_cleanup (core); } Index: app/paint/gimppaintcore-stroke.h =================================================================== --- app/paint/gimppaintcore-stroke.h (revision 27379) +++ app/paint/gimppaintcore-stroke.h (working copy) @@ -25,6 +25,7 @@ gboolean gimp_paint_core_stroke GimpPaintOptions *paint_options, GimpCoords *strokes, gint n_strokes, + gboolean push_undo, GError **error); gboolean gimp_paint_core_stroke_boundary (GimpPaintCore *core, GimpDrawable *drawable, @@ -34,12 +35,14 @@ gboolean gimp_paint_core_stroke_bounda gint n_bound_segs, gint offset_x, gint offset_y, + gboolean push_undo, GError **error); gboolean gimp_paint_core_stroke_vectors (GimpPaintCore *core, GimpDrawable *drawable, GimpPaintOptions *paint_options, gboolean emulate_dynamics, GimpVectors *vectors, + gboolean push_undo, GError **error); Index: app/paint/gimppaintcore.c =================================================================== --- app/paint/gimppaintcore.c (revision 27379) +++ app/paint/gimppaintcore.c (working copy) @@ -402,7 +402,8 @@ gimp_paint_core_start (GimpPaintCore void gimp_paint_core_finish (GimpPaintCore *core, - GimpDrawable *drawable) + GimpDrawable *drawable, + gboolean push_undo) { GimpImage *image; @@ -418,21 +419,25 @@ gimp_paint_core_finish (GimpPaintCore *c if ((core->x2 == core->x1) || (core->y2 == core->y1)) return; - gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT, core->undo_desc); + 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_PAINT_CORE_GET_CLASS (core)->push_undo (core, image, NULL); - gimp_drawable_push_undo (drawable, NULL, - core->x1, core->y1, - core->x2, core->y2, - core->undo_tiles, - TRUE); + gimp_drawable_push_undo (drawable, NULL, + core->x1, core->y1, + core->x2, core->y2, + core->undo_tiles, + TRUE); + + gimp_image_undo_group_end (image); + } tile_manager_unref (core->undo_tiles); core->undo_tiles = NULL; - gimp_image_undo_group_end (image); - if (core->saved_proj_tiles) { tile_manager_unref (core->saved_proj_tiles); Index: app/paint/gimppaintcore.h =================================================================== --- app/paint/gimppaintcore.h (revision 27379) +++ app/paint/gimppaintcore.h (working copy) @@ -122,7 +122,8 @@ gboolean gimp_paint_core_start GimpCoords *coords, GError **error); void gimp_paint_core_finish (GimpPaintCore *core, - GimpDrawable *drawable); + GimpDrawable *drawable, + gboolean push_undo); void gimp_paint_core_cancel (GimpPaintCore *core, GimpDrawable *drawable); void gimp_paint_core_cleanup (GimpPaintCore *core); Index: tools/pdbgen/pdb/edit.pdb =================================================================== --- tools/pdbgen/pdb/edit.pdb (revision 27379) +++ tools/pdbgen/pdb/edit.pdb (working copy) @@ -838,8 +838,8 @@ HELP g_object_set (desc, "method", GIMP_STROKE_METHOD_PAINT_CORE, NULL); success = gimp_item_stroke (GIMP_ITEM (gimp_image_get_mask (image)), - drawable, context, desc, TRUE, progress, - error); + drawable, context, desc, TRUE, TRUE, + progress, error); g_object_unref (desc); } @@ -879,8 +879,8 @@ HELP g_object_set (desc, "method", GIMP_STROKE_METHOD_PAINT_CORE, NULL); success = gimp_item_stroke (GIMP_ITEM (vectors), - drawable, context, desc, TRUE, progress, - error); + drawable, context, desc, TRUE, TRUE, + progress, error); g_object_unref (desc); } Index: tools/pdbgen/pdb/paths.pdb =================================================================== --- tools/pdbgen/pdb/paths.pdb (revision 27379) +++ tools/pdbgen/pdb/paths.pdb (working copy) @@ -273,8 +273,8 @@ sub path_stroke_current { g_object_set (desc, "method", GIMP_STROKE_METHOD_PAINT_CORE, NULL); success = gimp_item_stroke (GIMP_ITEM (vectors), - drawable, context, desc, TRUE, progress, - error); + drawable, context, desc, TRUE, TRUE, + progress, error); g_object_unref (desc); } @@ -285,7 +285,7 @@ CODE ); } -sub path_get_point_at_dist { +sub path_get_point_at_dist { &std_pdb_deprecated('gimp-vectors-stroke-get-point-at-dist'); @inargs = ( Index: tools/pdbgen/pdb/paint_tools.pdb =================================================================== --- tools/pdbgen/pdb/paint_tools.pdb (revision 27379) +++ tools/pdbgen/pdb/paint_tools.pdb (working copy) @@ -928,7 +928,7 @@ paint_tools_stroke (Gimp *g } retval = gimp_paint_core_stroke (core, drawable, options, - coords, n_strokes, + coords, n_strokes, TRUE, error); g_free (coords); Index: menus/vectors-menu.xml =================================================================== --- menus/vectors-menu.xml (revision 27379) +++ menus/vectors-menu.xml (working copy) @@ -13,6 +13,7 @@ + Index: menus/layers-menu.xml =================================================================== --- menus/layers-menu.xml (revision 27379) +++ menus/layers-menu.xml (working copy) @@ -4,6 +4,7 @@ + @@ -24,6 +25,9 @@ + + + Index: menus/image-menu.xml.in =================================================================== --- menus/image-menu.xml.in (revision 27379) +++ menus/image-menu.xml.in (working copy) @@ -370,6 +370,10 @@ + + + +