[gimp/wip/wormnest/vector-layers] Vector Layers from GSoC 2006 by Hendrik Boom
- From: Jacob Boerema <jboerema src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/wormnest/vector-layers] Vector Layers from GSoC 2006 by Hendrik Boom
- Date: Wed, 12 Jan 2022 17:45:25 +0000 (UTC)
commit fb0a8b6163fa4fabc4d98154e4e0981baca75d3f
Author: Jacob Boerema <jgboerema gmail com>
Date: Mon Aug 30 19:25:02 2021 -0400
Vector Layers from GSoC 2006 by Hendrik Boom
Adaption of patch 1 from issue #282.
Author according to patch: Martin Nordholts <martinn src gnome org>
A whole lot of changes needed to be made to make it build on master.
Several assumptions have been made, parts have been disabled, just
to make it compile - Wormnest.
January 2022:
There's a large #if 0 part in app/tools/gimpvectortool.c. I think most of
that code was already integrated into GIMP in app/display/gimptoolpath.c,
but I didn't get around to checking if that is true for all of it.
app/actions/layers-actions.c | 34 +-
app/actions/layers-commands.c | 91 ++-
app/actions/layers-commands.h | 9 +
app/actions/vectors-actions.c | 10 +-
app/actions/vectors-commands.c | 25 +-
app/actions/vectors-commands.h | 9 +
app/dialogs/Makefile.am | 2 +
app/dialogs/meson.build | 2 +
app/dialogs/vector-layer-options-dialog.c | 237 +++++++
app/dialogs/vector-layer-options-dialog.h | 33 +
app/tools/gimpvectoroptions.c | 33 +-
app/tools/gimpvectoroptions.h | 1 +
app/tools/gimpvectortool.c | 938 ++++++++++++++++++++++++++
app/vectors/Makefile.am | 62 +-
app/vectors/gimpvectorlayer-xcf.c | 255 +++++++
app/vectors/gimpvectorlayer-xcf.h | 34 +
app/vectors/gimpvectorlayer.c | 442 ++++++++++++
app/vectors/gimpvectorlayer.h | 63 ++
app/vectors/gimpvectorlayeroptions-parasite.c | 95 +++
app/vectors/gimpvectorlayeroptions-parasite.h | 33 +
app/vectors/gimpvectorlayeroptions.c | 367 ++++++++++
app/vectors/gimpvectorlayeroptions.h | 64 ++
app/vectors/meson.build | 4 +
app/vectors/vectors-types.h | 11 +-
app/xcf/xcf-load.c | 14 +-
app/xcf/xcf-save.c | 8 +
menus/image-menu.xml.in | 4 +
menus/layers-menu.xml | 5 +
menus/vectors-menu.xml | 1 +
29 files changed, 2837 insertions(+), 49 deletions(-)
---
diff --git a/app/actions/layers-actions.c b/app/actions/layers-actions.c
index 6e491cc634..443ab3142e 100644
--- a/app/actions/layers-actions.c
+++ b/app/actions/layers-actions.c
@@ -33,6 +33,8 @@
#include "text/gimptextlayer.h"
+#include "vectors/gimpvectorlayer.h"
+
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimpwidgets-utils.h"
@@ -97,6 +99,13 @@ static const GimpActionEntry layers_actions[] =
layers_edit_text_cmd_callback,
GIMP_HELP_LAYER_EDIT },
+ { "layers-edit-vector", GIMP_ICON_TOOL_PATH,
+ NC_("layers-action", "Edit Vector layer"), NULL,
+ NC_("layers-action",
+ "Activate the path tool to edit this vector layer's path"),
+ layers_edit_vector_cmd_callback,
+ GIMP_HELP_TOOL_PATH },
+
{ "layers-edit-attributes", GIMP_ICON_EDIT,
NC_("layers-action", "_Edit Layer Attributes..."), NULL,
NC_("layers-action", "Edit the layer's name"),
@@ -228,6 +237,18 @@ static const GimpActionEntry layers_actions[] =
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"),
+ 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"),
+ layers_vector_discard_cmd_callback,
+ NULL },
+
{ "layers-resize", GIMP_ICON_OBJECT_RESIZE,
NC_("layers-action", "Layer B_oundary Size..."), NULL,
NC_("layers-action", "Adjust the layer dimensions"),
@@ -766,6 +787,7 @@ layers_actions_update (GimpActionGroup *group,
gboolean lock_alpha = TRUE;
gboolean can_lock_alpha = FALSE;
gboolean text_layer = FALSE;
+ gboolean vector_layer = FALSE;
gboolean bs_mutable = FALSE; /* At least 1 selected layers' blend space is mutable. */
gboolean cs_mutable = FALSE; /* At least 1 selected layers' composite space is mutable. */
gboolean cm_mutable = FALSE; /* At least 1 selected layers' composite mode is mutable. */
@@ -983,8 +1005,9 @@ layers_actions_update (GimpActionGroup *group,
gimp_action_group_set_action_active (group, action, TRUE);
- text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
- }
+ text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
+ vector_layer = gimp_item_is_vector_layer (GIMP_ITEM (layer));
+ }
}
#define SET_VISIBLE(action,condition) \
@@ -996,9 +1019,11 @@ layers_actions_update (GimpActionGroup *group,
#define SET_LABEL(action,label) \
gimp_action_group_set_action_label (group, action, label)
- SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer));
+ SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer || vector_layer));
SET_VISIBLE ("layers-edit-text", text_layer && !ac);
SET_SENSITIVE ("layers-edit-text", text_layer && !ac);
+ SET_VISIBLE ("layers-edit-vector", vector_layer && !ac);
+ SET_SENSITIVE ("layers-edit-vector", vector_layer && !ac);
SET_SENSITIVE ("layers-edit-attributes", layer && !fs && !ac);
if (layer && gimp_layer_is_floating_sel (layer))
@@ -1048,6 +1073,9 @@ layers_actions_update (GimpActionGroup *group,
SET_VISIBLE ("layers-text-to-vectors", text_layer && !ac);
SET_VISIBLE ("layers-text-along-vectors", text_layer && !ac);
+ SET_VISIBLE ("layers-vector-fill-stroke", vector_layer && !ac);
+ SET_VISIBLE ("layers-vector-discard", vector_layer && !ac);
+
SET_SENSITIVE ("layers-resize", n_selected_layers == 1 && all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-resize-to-image", all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-scale", n_selected_layers == 1 && all_writable && all_movable && !ac);
diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c
index 29da45f223..6a7b6153cb 100644
--- a/app/actions/layers-commands.c
+++ b/app/actions/layers-commands.c
@@ -59,6 +59,8 @@
#include "text/gimptextlayer.h"
#include "vectors/gimpstroke.h"
+#include "vectors/gimpvectorlayer.h"
+#include "vectors/gimpvectorlayeroptions.h"
#include "vectors/gimpvectors.h"
#include "vectors/gimpvectors-warp.h"
@@ -72,6 +74,7 @@
#include "display/gimpimagewindow.h"
#include "tools/gimptexttool.h"
+#include "tools/gimpvectortool.h"
#include "tools/tool_manager.h"
#include "dialogs/dialogs.h"
@@ -79,6 +82,7 @@
#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 "items-commands.h"
@@ -240,10 +244,55 @@ layers_edit_text_cmd_callback (GimpAction *action,
}
}
+void
+layers_edit_vector_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data)
+{
+ GimpImage *image;
+ GimpLayer *layer;
+ GtkWidget *widget;
+ GimpTool *active_tool;
+ return_if_no_layer (image, layer, data);
+ return_if_no_widget (widget, data);
+
+ g_return_if_fail (gimp_item_is_vector_layer (GIMP_ITEM (layer)));
+
+ /*if (! gimp_drawable_is_vector_layer (GIMP_DRAWABLE (layer)))
+ {
+ layers_edit_attributes_cmd_callback (action, value, 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");*/
+ GimpToolInfo *tool_info = gimp_get_tool_info (image->gimp,
+ "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);
+// layer->options->vectors);
+}
+
void
layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
- gpointer data)
+ gpointer data)
{
GimpImage *image;
GimpLayer *layer;
@@ -1058,10 +1107,48 @@ layers_text_along_vectors_cmd_callback (GimpAction *action,
}
}
+void
+layers_vector_fill_stroke_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data)
+{
+ GimpImage *image;
+ GimpLayer *layer;
+ GtkWidget *widget;
+ return_if_no_layer (image, layer, data);
+ return_if_no_widget (widget, data);
+
+ if (GIMP_IS_VECTOR_LAYER (layer))
+ {
+ GtkWidget *dialog;
+
+ dialog = vector_layer_options_dialog_new (GIMP_VECTOR_LAYER (layer),
+ action_data_get_context (data),
+ _("Fill / Stroke"),
+ _("_OK"),
+ NULL, /* FIXME: help id */
+ widget);
+ gtk_widget_show (dialog);
+ }
+}
+
+void
+layers_vector_discard_cmd_callback (GimpAction *action,
+ GVariant *value,
+ 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 (GimpAction *action,
GVariant *value,
- gpointer data)
+ gpointer data)
{
GimpImage *image;
GimpLayer *layer;
diff --git a/app/actions/layers-commands.h b/app/actions/layers-commands.h
index 6e28d641e5..f29fd7b3e3 100644
--- a/app/actions/layers-commands.h
+++ b/app/actions/layers-commands.h
@@ -25,6 +25,9 @@ void layers_edit_cmd_callback (GimpAction *action,
void layers_edit_text_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
+void layers_edit_vector_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data);
void layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
@@ -84,6 +87,12 @@ void layers_text_to_vectors_cmd_callback (GimpAction *action,
void layers_text_along_vectors_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
+void layers_vector_fill_stroke_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data);
+void layers_vector_discard_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data);
void layers_resize_cmd_callback (GimpAction *action,
GVariant *value,
diff --git a/app/actions/vectors-actions.c b/app/actions/vectors-actions.c
index c3bf9bb205..27519b8042 100644
--- a/app/actions/vectors-actions.c
+++ b/app/actions/vectors-actions.c
@@ -157,7 +157,12 @@ static const GimpActionEntry vectors_actions[] =
{ "vectors-import", GIMP_ICON_DOCUMENT_OPEN,
NC_("vectors-action", "I_mport Path..."), "", NULL,
vectors_import_cmd_callback,
- GIMP_HELP_PATH_IMPORT }
+ GIMP_HELP_PATH_IMPORT },
+
+ { "vectors-to-vector-layer", NULL,
+ N_("Path to Vector Layer"), "", NULL,
+ vectors_to_vector_layer_cmd_callback,
+ NULL }
};
static const GimpToggleActionEntry vectors_toggle_actions[] =
@@ -427,6 +432,9 @@ vectors_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("vectors-export", n_selected_vectors == 1);
SET_SENSITIVE ("vectors-import", image);
+ /* Wormnest: not sure if the condition here is correct (it was vectors) */
+ SET_SENSITIVE ("vectors-to-vector-layer", n_selected_vectors > 0);
+
SET_SENSITIVE ("vectors-selection-to-vectors", image && !mask_empty);
SET_SENSITIVE ("vectors-selection-to-vectors-short", image && !mask_empty);
SET_SENSITIVE ("vectors-selection-to-vectors-advanced", image && !mask_empty);
diff --git a/app/actions/vectors-commands.c b/app/actions/vectors-commands.c
index 6dd7845afa..c80749cb27 100644
--- a/app/actions/vectors-commands.c
+++ b/app/actions/vectors-commands.c
@@ -47,6 +47,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"
@@ -348,10 +349,32 @@ vectors_merge_visible_cmd_callback (GimpAction *action,
gimp_image_flush (image);
}
+void
+vectors_to_vector_layer_cmd_callback (GimpAction *action,
+ GVariant *value,
+ 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),
+ GIMP_IMAGE_ACTIVE_PARENT,
+ -1,
+ TRUE);
+ gimp_vector_layer_refresh (layer);
+
+ gimp_image_flush (image);
+}
+
void
vectors_to_selection_cmd_callback (GimpAction *action,
GVariant *value,
- gpointer data)
+ gpointer data)
{
GimpImage *image;
GimpVectors *vectors;
diff --git a/app/actions/vectors-commands.h b/app/actions/vectors-commands.h
index 25383dd8e6..293cca1172 100644
--- a/app/actions/vectors-commands.h
+++ b/app/actions/vectors-commands.h
@@ -54,12 +54,21 @@ void vectors_delete_cmd_callback (GimpAction *action,
void vectors_merge_visible_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
+void vectors_to_vector_layer_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data);
void vectors_to_selection_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void vectors_selection_to_vectors_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
+void vectors_stroke_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data);
+void vectors_stroke_last_vals_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data);
void vectors_fill_cmd_callback (GimpAction *action,
GVariant *value,
diff --git a/app/dialogs/Makefile.am b/app/dialogs/Makefile.am
index 49abd913de..801ea44cac 100644
--- a/app/dialogs/Makefile.am
+++ b/app/dialogs/Makefile.am
@@ -97,6 +97,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 \
diff --git a/app/dialogs/meson.build b/app/dialogs/meson.build
index d934dadecf..65766d03e5 100644
--- a/app/dialogs/meson.build
+++ b/app/dialogs/meson.build
@@ -40,6 +40,8 @@ libappdialogs_sources = [
'tips-dialog.c',
'tips-parser.c',
'user-install-dialog.c',
+ 'vector-layer-options-dialog.c',
+ 'vector-layer-options-dialog.h',
'vectors-export-dialog.c',
'vectors-import-dialog.c',
'vectors-options-dialog.c',
diff --git a/app/dialogs/vector-layer-options-dialog.c b/app/dialogs/vector-layer-options-dialog.c
new file mode 100644
index 0000000000..bf20ef71aa
--- /dev/null
+++ b/app/dialogs/vector-layer-options-dialog.c
@@ -0,0 +1,237 @@
+/* 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 <gegl.h>
+#include <gtk/gtk.h>
+
+#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/gimpstrokeoptions.h"
+
+#include "widgets/gimpcolorpanel.h"
+#include "widgets/gimppropwidgets.h"
+#include "widgets/gimpviewabledialog.h"
+#include "widgets/gimpstrokeeditor.h"
+
+#include "vectors/gimpvectorlayer.h"
+#include "vectors/gimpvectorlayeroptions.h"
+
+#include "vector-layer-options-dialog.h"
+
+#include "gimp-intl.h"
+
+
+#define RESPONSE_RESET 1
+
+
+/* local functions */
+
+static void vector_layer_options_dialog_notify (GObject *options,
+ const GParamSpec *pspec,
+ GtkWidget *dialog);
+static void vector_layer_options_dialog_response (GtkWidget *widget,
+ gint response_id,
+ GtkWidget *dialog);
+
+
+/* public function */
+
+GtkWidget *
+vector_layer_options_dialog_new (GimpVectorLayer *layer,
+ GimpContext *context,
+ const gchar *title,
+ const gchar *stock_id,
+ const gchar *help_id,
+ GtkWidget *parent)
+{
+ GimpVectorLayerOptions *saved_options;
+ GimpFillOptions *fill_options;
+ GimpStrokeOptions *stroke_options;
+ GtkWidget *dialog;
+ GtkWidget *main_vbox;
+
+ g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), 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_printerr ("--> vector_layer_options_dialog_new\n");
+
+ saved_options = gimp_config_duplicate (GIMP_CONFIG (layer->options));
+ fill_options = gimp_config_duplicate (GIMP_CONFIG (saved_options->fill_options));
+ stroke_options = gimp_config_duplicate (GIMP_CONFIG (saved_options->stroke_options));
+
+ dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, layer),
+ context,
+ title, "gimp-vectorlayer-options",
+ stock_id,
+ _("Choose vector layer options"),
+ parent,
+ gimp_standard_help_func,
+ help_id,
+
+ _("_Reset"), RESPONSE_RESET,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ stock_id, GTK_RESPONSE_OK,
+
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_RESET);
+ gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
+ RESPONSE_RESET,
+ GTK_RESPONSE_OK,
+ 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), "layer", layer);
+
+ g_object_set_data_full (G_OBJECT (dialog), "saved-options",
+ saved_options,
+ (GDestroyNotify) g_object_unref);
+ g_object_set_data_full (G_OBJECT (dialog), "fill-options",
+ fill_options,
+ (GDestroyNotify) g_object_unref);
+ g_object_set_data_full (G_OBJECT (dialog), "stroke-options",
+ stroke_options,
+ (GDestroyNotify) g_object_unref);
+
+ g_signal_connect_object (fill_options, "notify",
+ G_CALLBACK (vector_layer_options_dialog_notify),
+ dialog, 0);
+ g_signal_connect_object (stroke_options, "notify",
+ G_CALLBACK (vector_layer_options_dialog_notify),
+ dialog, 0);
+
+ main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
+ // Wormnest - next copied, check last 3 parameters!
+// gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+// main_vbox, TRUE, TRUE, 0);
+ //gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->box), main_vbox);
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), main_vbox);
+ gtk_widget_show (main_vbox);
+
+ /* The fill editor */
+ {
+ GtkWidget *frame;
+ GtkWidget *fill_editor;
+
+ frame = gimp_frame_new (_("Fill Style"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ fill_editor = gimp_fill_editor_new (fill_options, TRUE);
+ gtk_container_add (GTK_CONTAINER (frame), fill_editor);
+ gtk_widget_show (fill_editor);
+ }
+
+ /* The stroke editor */
+ {
+ GtkWidget *frame;
+ GtkWidget *stroke_editor;
+ gdouble xres;
+ gdouble yres;
+
+ frame = gimp_frame_new (_("Stroke Style"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ gimp_image_get_resolution (gimp_item_get_image (GIMP_ITEM (layer)),
+ &xres, &yres);
+
+ stroke_editor = gimp_stroke_editor_new (stroke_options, yres, TRUE);
+ gtk_container_add (GTK_CONTAINER (frame), stroke_editor);
+ gtk_widget_show (stroke_editor);
+ }
+
+ return dialog;
+}
+
+static void
+vector_layer_options_dialog_notify (GObject *options,
+ const GParamSpec *pspec,
+ GtkWidget *dialog)
+{
+ GimpVectorLayer *layer;
+ GimpFillOptions *fill_options;
+ GimpStrokeOptions *stroke_options;
+
+ layer = g_object_get_data (G_OBJECT (dialog), "layer");
+
+ fill_options = g_object_get_data (G_OBJECT (dialog), "fill-options");
+ stroke_options = g_object_get_data (G_OBJECT (dialog), "stroke-options");
+
+ gimp_config_sync (G_OBJECT (fill_options),
+ G_OBJECT (layer->options->fill_options), 0);
+ gimp_config_sync (G_OBJECT (stroke_options),
+ G_OBJECT (layer->options->stroke_options), 0);
+
+ gimp_vector_layer_refresh (layer);
+ gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer)));
+}
+
+static void
+vector_layer_options_dialog_response (GtkWidget *widget,
+ gint response_id,
+ GtkWidget *dialog)
+{
+ //GimpVectorLayer *layer;
+ GimpVectorLayerOptions *saved_options;
+ GimpFillOptions *fill_options;
+ GimpStrokeOptions *stroke_options;
+
+ //layer = g_object_get_data (G_OBJECT (dialog), "layer");
+
+ saved_options = g_object_get_data (G_OBJECT (dialog), "saved-options");
+ fill_options = g_object_get_data (G_OBJECT (dialog), "fill-options");
+ stroke_options = g_object_get_data (G_OBJECT (dialog), "stroke-options");
+
+ switch (response_id)
+ {
+ case GTK_RESPONSE_OK:
+ gtk_widget_destroy (dialog);
+ break;
+
+ default:
+ gimp_config_sync (G_OBJECT (saved_options->fill_options),
+ G_OBJECT (fill_options), 0);
+ gimp_config_sync (G_OBJECT (saved_options->stroke_options),
+ G_OBJECT (stroke_options), 0);
+
+ if (response_id != RESPONSE_RESET)
+ gtk_widget_destroy (dialog);
+ break;
+ }
+}
diff --git a/app/dialogs/vector-layer-options-dialog.h b/app/dialogs/vector-layer-options-dialog.h
new file mode 100644
index 0000000000..28947838cb
--- /dev/null
+++ b/app/dialogs/vector-layer-options-dialog.h
@@ -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 (GimpVectorLayer *layer,
+ GimpContext *context,
+ const gchar *title,
+ const gchar *stock_id,
+ const gchar *help_id,
+ GtkWidget *parent);
+
+
+#endif /* __VECTOR_LAYER_OPTIONS_DIALOG_H__ */
diff --git a/app/tools/gimpvectoroptions.c b/app/tools/gimpvectoroptions.c
index 01dd3f7ff5..1e8e843467 100644
--- a/app/tools/gimpvectoroptions.c
+++ b/app/tools/gimpvectoroptions.c
@@ -89,20 +89,20 @@ gimp_vector_options_init (GimpVectorOptions *options)
}
static void
-gimp_vector_options_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+gimp_vector_options_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GimpVectorOptions *options = GIMP_VECTOR_OPTIONS (object);
switch (property_id)
{
case PROP_VECTORS_EDIT_MODE:
- options->edit_mode = g_value_get_enum (value);
+ g_value_set_enum (value, options->edit_mode);
break;
case PROP_VECTORS_POLYGONAL:
- options->polygonal = g_value_get_boolean (value);
+ g_value_set_boolean (value, options->polygonal);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -110,22 +110,21 @@ gimp_vector_options_set_property (GObject *object,
}
}
-
static void
-gimp_vector_options_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+gimp_vector_options_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
GimpVectorOptions *options = GIMP_VECTOR_OPTIONS (object);
switch (property_id)
{
case PROP_VECTORS_EDIT_MODE:
- g_value_set_enum (value, options->edit_mode);
+ options->edit_mode = g_value_get_enum (value);
break;
case PROP_VECTORS_POLYGONAL:
- g_value_set_boolean (value, options->polygonal);
+ options->polygonal = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -214,5 +213,13 @@ gimp_vector_options_gui (GimpToolOptions *tool_options)
options->stroke_button = button;
+ button = gtk_button_new_with_label (_("Create Vector Layer"));
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ gtk_widget_set_sensitive (button, FALSE);
+ gimp_help_set_help_data (button, NULL, NULL /* FIXME */);
+ gtk_widget_show (button);
+
+ options->vector_layer_button = button;
+
return vbox;
}
diff --git a/app/tools/gimpvectoroptions.h b/app/tools/gimpvectoroptions.h
index e13e8f3207..a69d3a3d4c 100644
--- a/app/tools/gimpvectoroptions.h
+++ b/app/tools/gimpvectoroptions.h
@@ -44,6 +44,7 @@ struct _GimpVectorOptions
GtkWidget *to_selection_button;
GtkWidget *fill_button;
GtkWidget *stroke_button;
+ GtkWidget *vector_layer_button;
};
diff --git a/app/tools/gimpvectortool.c b/app/tools/gimpvectortool.c
index baafd6e33d..f962df8db4 100644
--- a/app/tools/gimpvectortool.c
+++ b/app/tools/gimpvectortool.c
@@ -40,6 +40,7 @@
#include "paint/gimppaintoptions.h" /* GIMP_PAINT_OPTIONS_CONTEXT_MASK */
+#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectors.h"
#include "widgets/gimpdialogfactory.h"
@@ -147,6 +148,8 @@ static void gimp_vector_tool_stroke_callback (GtkWidget *dialog,
GimpStrokeOptions *options,
gpointer data);
+static void gimp_vector_tool_create_vector_layer (GimpVectorTool *vector_tool,
+ GtkWidget *button);
G_DEFINE_TYPE (GimpVectorTool, gimp_vector_tool, GIMP_TYPE_DRAW_TOOL)
@@ -558,6 +561,897 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
if (vectors == vector_tool->vectors)
return;
+#if 0
+ if (!vector_tool->modifier_lock)
+ {
+ if (state & TOGGLE_MASK)
+ {
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
+ }
+ else
+ {
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
+ }
+ }
+
+ switch (vector_tool->function)
+ {
+ case VECTORS_MOVE_ANCHOR:
+ case VECTORS_MOVE_HANDLE:
+ anchor = vector_tool->cur_anchor;
+
+ if (anchor)
+ {
+ gimp_stroke_anchor_move_absolute (vector_tool->cur_stroke,
+ vector_tool->cur_anchor,
+ &position,
+ vector_tool->restriction);
+ vector_tool->undo_motion = TRUE;
+ }
+ break;
+
+ case VECTORS_MOVE_CURVE:
+ if (options->polygonal)
+ {
+ gimp_vector_tool_move_selected_anchors (vector_tool,
+ coords->x - vector_tool->last_x,
+ coords->y - vector_tool->last_y);
+ vector_tool->undo_motion = TRUE;
+ }
+ else
+ {
+ gimp_stroke_point_move_absolute (vector_tool->cur_stroke,
+ vector_tool->cur_anchor,
+ vector_tool->cur_position,
+ &position,
+ vector_tool->restriction);
+ vector_tool->undo_motion = TRUE;
+ }
+ break;
+
+ case VECTORS_MOVE_ANCHORSET:
+ gimp_vector_tool_move_selected_anchors (vector_tool,
+ coords->x - vector_tool->last_x,
+ coords->y - vector_tool->last_y);
+ vector_tool->undo_motion = TRUE;
+ break;
+
+ case VECTORS_MOVE_STROKE:
+ if (vector_tool->cur_stroke)
+ {
+ gimp_stroke_translate (vector_tool->cur_stroke,
+ coords->x - vector_tool->last_x,
+ coords->y - vector_tool->last_y);
+ vector_tool->undo_motion = TRUE;
+ }
+ else if (vector_tool->sel_stroke)
+ {
+ gimp_stroke_translate (vector_tool->sel_stroke,
+ coords->x - vector_tool->last_x,
+ coords->y - vector_tool->last_y);
+ vector_tool->undo_motion = TRUE;
+ }
+ break;
+
+ case VECTORS_MOVE_VECTORS:
+ gimp_item_translate (GIMP_ITEM (vector_tool->vectors),
+ coords->x - vector_tool->last_x,
+ coords->y - vector_tool->last_y, FALSE);
+ vector_tool->undo_motion = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ vector_tool->last_x = coords->x;
+ 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
+gimp_vector_tool_key_press (GimpTool *tool,
+ GdkEventKey *kevent,
+ GimpDisplay *display)
+{
+ GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+ GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
+ GimpDisplayShell *shell;
+ gdouble xdist, ydist;
+ gdouble pixels = 1.0;
+
+ if (! vector_tool->vectors)
+ return FALSE;
+
+ if (display != draw_tool->display)
+ return FALSE;
+
+ shell = GIMP_DISPLAY_SHELL (draw_tool->display->shell);
+
+ if (kevent->state & GDK_SHIFT_MASK)
+ pixels = 10.0;
+
+ if (kevent->state & GDK_CONTROL_MASK)
+ pixels = 50.0;
+
+ switch (kevent->keyval)
+ {
+ case GDK_Return:
+ case GDK_KP_Enter:
+ case GDK_ISO_Enter:
+ gimp_vector_tool_to_selection_extended (vector_tool, kevent->state);
+ break;
+
+ case GDK_BackSpace:
+ case GDK_Delete:
+ gimp_vector_tool_delete_selected_anchors (vector_tool);
+ break;
+
+ case GDK_Left:
+ case GDK_Right:
+ case GDK_Up:
+ case GDK_Down:
+ xdist = FUNSCALEX (shell, pixels);
+ ydist = FUNSCALEY (shell, pixels);
+
+ gimp_vector_tool_undo_push (vector_tool, _("Move Anchors"));
+
+ gimp_vectors_freeze (vector_tool->vectors);
+
+ switch (kevent->keyval)
+ {
+ case GDK_Left:
+ gimp_vector_tool_move_selected_anchors (vector_tool, -xdist, 0);
+ break;
+
+ case GDK_Right:
+ gimp_vector_tool_move_selected_anchors (vector_tool, xdist, 0);
+ break;
+
+ case GDK_Up:
+ gimp_vector_tool_move_selected_anchors (vector_tool, 0, -ydist);
+ break;
+
+ case GDK_Down:
+ gimp_vector_tool_move_selected_anchors (vector_tool, 0, ydist);
+ break;
+
+ default:
+ break;
+ }
+
+ gimp_vectors_thaw (vector_tool->vectors);
+ vector_tool->have_undo = FALSE;
+ break;
+
+ case GDK_Escape:
+ if (options->edit_mode != GIMP_VECTOR_MODE_DESIGN)
+ g_object_set (options, "vectors-edit-mode",
+ GIMP_VECTOR_MODE_DESIGN, NULL);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ gimp_image_flush (display->image);
+
+ return TRUE;
+}
+
+static void
+gimp_vector_tool_modifier_key (GimpTool *tool,
+ GdkModifierType key,
+ gboolean press,
+ GdkModifierType state,
+ GimpDisplay *display)
+{
+ GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
+ GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
+
+ if (key == TOGGLE_MASK)
+ return;
+
+ if (key == INSDEL_MASK || key == MOVE_MASK)
+ {
+ GimpVectorMode button_mode = options->edit_mode;
+
+ if (press)
+ {
+ if (key == (state & (INSDEL_MASK | MOVE_MASK)))
+ {
+ /* first modifier pressed */
+
+ vector_tool->saved_mode = options->edit_mode;
+ }
+ }
+ else
+ {
+ if (! (state & (INSDEL_MASK | MOVE_MASK)))
+ {
+ /* last modifier released */
+
+ button_mode = vector_tool->saved_mode;
+ }
+ }
+
+ if (state & MOVE_MASK)
+ {
+ button_mode = GIMP_VECTOR_MODE_MOVE;
+ }
+ else if (state & INSDEL_MASK)
+ {
+ button_mode = GIMP_VECTOR_MODE_EDIT;
+ }
+
+ if (button_mode != options->edit_mode)
+ {
+ g_object_set (options, "vectors-edit-mode", button_mode, NULL);
+ }
+ }
+}
+
+static void
+gimp_vector_tool_oper_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ gboolean proximity,
+ GimpDisplay *display)
+{
+ GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+ GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
+ GimpAnchor *anchor = NULL;
+ GimpAnchor *anchor2 = NULL;
+ GimpStroke *stroke = NULL;
+ gdouble position = -1;
+ gboolean on_handle = FALSE;
+ gboolean on_curve = FALSE;
+ gboolean on_vectors = FALSE;
+
+ vector_tool->modifier_lock = FALSE;
+
+ /* are we hovering the current vectors on the current display? */
+ if (vector_tool->vectors && GIMP_DRAW_TOOL (tool)->display == display)
+ {
+ on_handle = gimp_draw_tool_on_vectors_handle (GIMP_DRAW_TOOL (tool),
+ display,
+ vector_tool->vectors,
+ coords,
+ TARGET, TARGET,
+ GIMP_ANCHOR_ANCHOR,
+ vector_tool->sel_count > 2,
+ &anchor, &stroke);
+
+ if (! on_handle)
+ on_curve = gimp_draw_tool_on_vectors_curve (GIMP_DRAW_TOOL (tool),
+ display,
+ vector_tool->vectors,
+ coords,
+ TARGET, TARGET,
+ NULL,
+ &position, &anchor,
+ &anchor2, &stroke);
+ }
+
+ if (on_handle || on_curve)
+ {
+ vector_tool->cur_vectors = NULL;
+ }
+ else
+ {
+ on_vectors = gimp_draw_tool_on_vectors (draw_tool, display, coords,
+ TARGET, TARGET,
+ NULL, NULL, NULL, NULL, NULL,
+ &(vector_tool->cur_vectors));
+ }
+
+ vector_tool->cur_position = position;
+ vector_tool->cur_anchor = anchor;
+ vector_tool->cur_anchor2 = anchor2;
+ vector_tool->cur_stroke = stroke;
+
+ switch (options->edit_mode)
+ {
+ case GIMP_VECTOR_MODE_DESIGN:
+ if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->display != display)
+ {
+ if (on_vectors)
+ {
+ vector_tool->function = VECTORS_SELECT_VECTOR;
+ }
+ else
+ {
+ vector_tool->function = VECTORS_CREATE_VECTOR;
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
+ vector_tool->modifier_lock = TRUE;
+ }
+ }
+ else if (on_handle)
+ {
+ if (anchor->type == GIMP_ANCHOR_ANCHOR)
+ {
+ if (state & TOGGLE_MASK)
+ {
+ vector_tool->function = VECTORS_MOVE_ANCHORSET;
+ }
+ else
+ {
+ if (vector_tool->sel_count >= 2 && anchor->selected)
+ vector_tool->function = VECTORS_MOVE_ANCHORSET;
+ else
+ vector_tool->function = VECTORS_MOVE_ANCHOR;
+ }
+ }
+ else
+ {
+ vector_tool->function = VECTORS_MOVE_HANDLE;
+
+ if (state & TOGGLE_MASK)
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
+ else
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
+ }
+ }
+ else if (on_curve)
+ {
+ if (gimp_stroke_point_is_movable (stroke, anchor, position))
+ {
+ vector_tool->function = VECTORS_MOVE_CURVE;
+
+ if (state & TOGGLE_MASK)
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
+ else
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
+ }
+ else
+ {
+ vector_tool->function = VECTORS_FINISHED;
+ }
+ }
+ else
+ {
+ if (vector_tool->sel_stroke && vector_tool->sel_anchor &&
+ gimp_stroke_is_extendable (vector_tool->sel_stroke,
+ vector_tool->sel_anchor) &&
+ !(state & TOGGLE_MASK))
+ vector_tool->function = VECTORS_ADD_ANCHOR;
+ else
+ vector_tool->function = VECTORS_CREATE_STROKE;
+
+ vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
+ vector_tool->modifier_lock = TRUE;
+ }
+
+ break;
+
+ case GIMP_VECTOR_MODE_EDIT:
+ if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->display != display)
+ {
+ if (on_vectors)
+ {
+ vector_tool->function = VECTORS_SELECT_VECTOR;
+ }
+ else
+ {
+ vector_tool->function = VECTORS_FINISHED;
+ }
+ }
+ else if (on_handle)
+ {
+ if (anchor->type == GIMP_ANCHOR_ANCHOR)
+ {
+ if (!(state & TOGGLE_MASK) && vector_tool->sel_anchor &&
+ vector_tool->sel_anchor != anchor &&
+ gimp_stroke_is_extendable (vector_tool->sel_stroke,
+ vector_tool->sel_anchor) &&
+ gimp_stroke_is_extendable (stroke, anchor))
+ {
+ vector_tool->function = VECTORS_CONNECT_STROKES;
+ }
+ else
+ {
+ if (state & TOGGLE_MASK)
+ {
+ vector_tool->function = VECTORS_DELETE_ANCHOR;
+ }
+ else
+ {
+ if (options->polygonal)
+ vector_tool->function = VECTORS_MOVE_ANCHOR;
+ else
+ vector_tool->function = VECTORS_MOVE_HANDLE;
+ }
+ }
+ }
+ else
+ {
+ if (state & TOGGLE_MASK)
+ vector_tool->function = VECTORS_CONVERT_EDGE;
+ else
+ vector_tool->function = VECTORS_MOVE_HANDLE;
+ }
+ }
+ else if (on_curve)
+ {
+ if (state & TOGGLE_MASK)
+ {
+ vector_tool->function = VECTORS_DELETE_SEGMENT;
+ }
+ else if (gimp_stroke_anchor_is_insertable (stroke, anchor, position))
+ {
+ vector_tool->function = VECTORS_INSERT_ANCHOR;
+ }
+ else
+ {
+ vector_tool->function = VECTORS_FINISHED;
+ }
+ }
+ else
+ {
+ vector_tool->function = VECTORS_FINISHED;
+ }
+
+ break;
+
+ case GIMP_VECTOR_MODE_MOVE:
+ if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->display != display)
+ {
+ if (on_vectors)
+ {
+ vector_tool->function = VECTORS_SELECT_VECTOR;
+ }
+ else
+ {
+ vector_tool->function = VECTORS_FINISHED;
+ }
+ }
+ else if (on_handle || on_curve)
+ {
+ if (state & TOGGLE_MASK)
+ {
+ vector_tool->function = VECTORS_MOVE_VECTORS;
+ }
+ else
+ {
+ vector_tool->function = VECTORS_MOVE_STROKE;
+ }
+ }
+ else
+ {
+ if (on_vectors)
+ {
+ vector_tool->function = VECTORS_SELECT_VECTOR;
+ }
+ else
+ {
+ vector_tool->function = VECTORS_MOVE_VECTORS;
+ }
+ }
+ break;
+ }
+
+ gimp_vector_tool_status_update (tool, display, state, proximity);
+}
+
+
+static void
+gimp_vector_tool_status_update (GimpTool *tool,
+ GimpDisplay *display,
+ GdkModifierType state,
+ gboolean proximity)
+{
+ GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
+ GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
+
+ gimp_tool_pop_status (tool, display);
+
+ if (proximity)
+ {
+ const gchar *status = NULL;
+ gboolean free_status = FALSE;
+
+ switch (vector_tool->function)
+ {
+ case VECTORS_SELECT_VECTOR:
+ status = _("Click to pick path to edit");
+ break;
+
+ case VECTORS_CREATE_VECTOR:
+ status = _("Click to create a new path");
+ break;
+
+ case VECTORS_CREATE_STROKE:
+ status = _("Click to create a new component of the path");
+ break;
+
+ case VECTORS_ADD_ANCHOR:
+ status = gimp_suggest_modifiers (_("Click or Click-Drag to create "
+ "a new anchor"),
+ GDK_SHIFT_MASK & ~state,
+ NULL, NULL, NULL);
+ free_status = TRUE;
+ break;
+
+ case VECTORS_MOVE_ANCHOR:
+ if (options->edit_mode != GIMP_VECTOR_MODE_EDIT)
+ {
+ status = gimp_suggest_modifiers (_("Click-Drag to move the "
+ "anchor around"),
+ GDK_CONTROL_MASK & ~state,
+ NULL, NULL, NULL);
+ free_status = TRUE;
+ }
+ else
+ status = _("Click-Drag to move the anchor around");
+ break;
+
+ case VECTORS_MOVE_ANCHORSET:
+ status = _("Click-Drag to move the anchors around");
+ break;
+
+ case VECTORS_MOVE_HANDLE:
+ status = gimp_suggest_modifiers (_("Click-Drag to move the handle "
+ "around"),
+ GDK_SHIFT_MASK & ~state,
+ NULL, NULL, NULL);
+ free_status = TRUE;
+ break;
+
+ case VECTORS_MOVE_CURVE:
+ if (GIMP_VECTOR_TOOL_GET_OPTIONS (tool)->polygonal)
+ status = gimp_suggest_modifiers (_("Click-Drag to move the "
+ "anchors around"),
+ GDK_SHIFT_MASK & ~state,
+ NULL, NULL, NULL);
+ else
+ status = gimp_suggest_modifiers (_("Click-Drag to change the "
+ "shape of the curve"),
+ GDK_SHIFT_MASK & ~state,
+ _("%s: symmetrical"), NULL, NULL);
+ free_status = TRUE;
+ break;
+
+ case VECTORS_MOVE_STROKE:
+ status = gimp_suggest_modifiers (_("Click-Drag to move the "
+ "component around"),
+ GDK_SHIFT_MASK & ~state,
+ NULL, NULL, NULL);
+ free_status = TRUE;
+ break;
+
+ case VECTORS_MOVE_VECTORS:
+ status = _("Click-Drag to move the path around");
+ break;
+
+ case VECTORS_INSERT_ANCHOR:
+ status = gimp_suggest_modifiers (_("Click-Drag to insert an anchor "
+ "on the path"),
+ GDK_SHIFT_MASK & ~state,
+ NULL, NULL, NULL);
+ free_status = TRUE;
+ break;
+
+ case VECTORS_DELETE_ANCHOR:
+ status = _("Click to delete this anchor");
+ break;
+
+ case VECTORS_CONNECT_STROKES:
+ status = _("Click to connect this anchor "
+ "with the selected endpoint");
+ break;
+
+ case VECTORS_DELETE_SEGMENT:
+ status = _("Click to open up the path");
+ break;
+
+ case VECTORS_CONVERT_EDGE:
+ status = _("Click to make this node angular");
+ break;
+
+ case VECTORS_FINISHED:
+ status = NULL;
+ break;
+ }
+
+ if (status)
+ gimp_tool_push_status (tool, display, "%s", status);
+
+ if (free_status)
+ g_free ((gchar *) status);
+ }
+}
+
+static void
+gimp_vector_tool_cursor_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ GimpDisplay *display)
+{
+ GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
+ GimpToolCursorType tool_cursor = GIMP_TOOL_CURSOR_PATHS;
+ GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
+
+ switch (vector_tool->function)
+ {
+ case VECTORS_SELECT_VECTOR:
+ tool_cursor = GIMP_TOOL_CURSOR_HAND;
+ break;
+
+ case VECTORS_CREATE_VECTOR:
+ case VECTORS_CREATE_STROKE:
+ modifier = GIMP_CURSOR_MODIFIER_CONTROL;
+ break;
+
+ case VECTORS_ADD_ANCHOR:
+ case VECTORS_INSERT_ANCHOR:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
+ modifier = GIMP_CURSOR_MODIFIER_PLUS;
+ break;
+
+ case VECTORS_DELETE_ANCHOR:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
+ modifier = GIMP_CURSOR_MODIFIER_MINUS;
+ break;
+
+ case VECTORS_DELETE_SEGMENT:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_SEGMENT;
+ modifier = GIMP_CURSOR_MODIFIER_MINUS;
+ break;
+
+ case VECTORS_MOVE_HANDLE:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_CONTROL;
+ modifier = GIMP_CURSOR_MODIFIER_MOVE;
+ break;
+
+ case VECTORS_CONVERT_EDGE:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_CONTROL;
+ modifier = GIMP_CURSOR_MODIFIER_MINUS;
+ break;
+
+ case VECTORS_MOVE_ANCHOR:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
+ modifier = GIMP_CURSOR_MODIFIER_MOVE;
+ break;
+
+ case VECTORS_MOVE_CURVE:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_SEGMENT;
+ modifier = GIMP_CURSOR_MODIFIER_MOVE;
+ break;
+
+ case VECTORS_MOVE_STROKE:
+ case VECTORS_MOVE_VECTORS:
+ modifier = GIMP_CURSOR_MODIFIER_MOVE;
+ break;
+
+ case VECTORS_MOVE_ANCHORSET:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
+ modifier = GIMP_CURSOR_MODIFIER_MOVE;
+ break;
+
+ case VECTORS_CONNECT_STROKES:
+ tool_cursor = GIMP_TOOL_CURSOR_PATHS_SEGMENT;
+ modifier = GIMP_CURSOR_MODIFIER_JOIN;
+ break;
+
+ default:
+ modifier = GIMP_CURSOR_MODIFIER_BAD;
+ break;
+ }
+
+ gimp_tool_control_set_tool_cursor (tool->control, tool_cursor);
+ gimp_tool_control_set_cursor_modifier (tool->control, modifier);
+
+ GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
+}
+
+static void
+gimp_vector_tool_draw (GimpDrawTool *draw_tool)
+{
+ GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (draw_tool);
+ GimpAnchor *cur_anchor = NULL;
+ GimpStroke *cur_stroke = NULL;
+ GimpVectors *vectors;
+ GArray *coords;
+ gboolean closed;
+ GList *draw_anchors;
+ GList *list;
+
+ vectors = vector_tool->vectors;
+
+ if (!vectors)
+ return;
+
+ while ((cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke)))
+ {
+ /* anchor handles */
+ draw_anchors = gimp_stroke_get_draw_anchors (cur_stroke);
+
+ for (list = draw_anchors; list; list = g_list_next (list))
+ {
+ cur_anchor = GIMP_ANCHOR (list->data);
+
+ if (cur_anchor->type == GIMP_ANCHOR_ANCHOR)
+ {
+ gimp_draw_tool_draw_handle (draw_tool,
+ cur_anchor->selected ?
+ GIMP_HANDLE_CIRCLE :
+ GIMP_HANDLE_FILLED_CIRCLE,
+ cur_anchor->position.x,
+ cur_anchor->position.y,
+ TARGET,
+ TARGET,
+ GTK_ANCHOR_CENTER,
+ FALSE);
+ }
+ }
+
+ g_list_free (draw_anchors);
+
+ if (vector_tool->sel_count <= 2)
+ {
+ /* control handles */
+ draw_anchors = gimp_stroke_get_draw_controls (cur_stroke);
+
+ for (list = draw_anchors; list; list = g_list_next (list))
+ {
+ cur_anchor = GIMP_ANCHOR (list->data);
+
+ gimp_draw_tool_draw_handle (draw_tool,
+ GIMP_HANDLE_SQUARE,
+ cur_anchor->position.x,
+ cur_anchor->position.y,
+ TARGET - 3,
+ TARGET - 3,
+ GTK_ANCHOR_CENTER,
+ FALSE);
+ }
+
+ g_list_free (draw_anchors);
+
+ /* the lines to the control handles */
+ coords = gimp_stroke_get_draw_lines (cur_stroke);
+
+ if (coords)
+ {
+ if (coords->len % 2 == 0)
+ {
+ gint i;
+
+ for (i = 0; i < coords->len; i += 2)
+ {
+ gimp_draw_tool_draw_dashed_line (draw_tool,
+ g_array_index (coords, GimpCoords, i).x,
+ g_array_index (coords, GimpCoords, i).y,
+ g_array_index (coords, GimpCoords, i + 1).x,
+ g_array_index (coords, GimpCoords, i + 1).y,
+ FALSE);
+ }
+ }
+
+ g_array_free (coords, TRUE);
+ }
+ }
+
+ /* the stroke itself */
+ if (! gimp_item_get_visible (GIMP_ITEM (vectors)))
+ {
+ coords = gimp_stroke_interpolate (cur_stroke, 1.0, &closed);
+
+ if (coords)
+ {
+ if (coords->len)
+ gimp_draw_tool_draw_strokes (draw_tool,
+ &g_array_index (coords,
+ GimpCoords, 0),
+ coords->len, FALSE, FALSE);
+
+ g_array_free (coords, TRUE);
+ }
+ }
+ }
+}
+
+static void
+gimp_vector_tool_vectors_changed (GimpImage *image,
+ GimpVectorTool *vector_tool)
+{
+ gimp_vector_tool_set_vectors (vector_tool,
+ gimp_image_get_active_vectors (image));
+}
+
+static void
+gimp_vector_tool_vectors_removed (GimpVectors *vectors,
+ GimpVectorTool *vector_tool)
+{
+ gimp_vector_tool_set_vectors (vector_tool, NULL);
+}
+
+static void
+gimp_vector_tool_vectors_visible (GimpVectors *vectors,
+ GimpVectorTool *vector_tool)
+{
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (vector_tool);
+
+ if (gimp_draw_tool_is_active (draw_tool) && draw_tool->paused_count == 0)
+ {
+ GimpStroke *stroke = NULL;
+
+ while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke)))
+ {
+ GArray *coords;
+ gboolean closed;
+
+ coords = gimp_stroke_interpolate (stroke, 1.0, &closed);
+
+ if (coords)
+ {
+ if (coords->len)
+ gimp_draw_tool_draw_strokes (draw_tool,
+ &g_array_index (coords,
+ GimpCoords, 0),
+ coords->len, FALSE, FALSE);
+
+ g_array_free (coords, TRUE);
+ }
+ }
+ }
+}
+
+static void
+gimp_vector_tool_vectors_freeze (GimpVectors *vectors,
+ GimpVectorTool *vector_tool)
+{
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
+}
+
+static void
+gimp_vector_tool_vectors_thaw (GimpVectors *vectors,
+ GimpVectorTool *vector_tool)
+{
+ /* Ok, the vector might have changed externally (e.g. Undo)
+ * we need to validate our internal state. */
+ gimp_vector_tool_verify_state (vector_tool);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (vector_tool));
+}
+
+void
+gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
+ GimpVectors *vectors)
+{
+ GimpDrawTool *draw_tool;
+ GimpTool *tool;
+ GimpItem *item = NULL;
+ GimpVectorOptions *options;
+
+ g_return_if_fail (GIMP_IS_VECTOR_TOOL (vector_tool));
+ g_return_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors));
+
+ draw_tool = GIMP_DRAW_TOOL (vector_tool);
+ tool = GIMP_TOOL (vector_tool);
+ options = GIMP_VECTOR_TOOL_GET_OPTIONS (vector_tool);
+
+ if (vectors)
+ item = GIMP_ITEM (vectors);
+
+ if (vectors == vector_tool->vectors)
+ return;
+
+ gimp_draw_tool_pause (draw_tool);
+
+ if (gimp_draw_tool_is_active (draw_tool) &&
+ (! vectors || draw_tool->display->image != gimp_item_get_image (item)))
+ {
+ gimp_draw_tool_stop (draw_tool);
+ }
+#endif
+
if (vector_tool->vectors)
{
GimpImage *old_image;
@@ -599,6 +1493,14 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
gimp_vector_tool_stroke_vectors,
tool);
}
+
+ if (options->vector_layer_button)
+ {
+ gtk_widget_set_sensitive (options->vector_layer_button, FALSE);
+ g_signal_handlers_disconnect_by_func (options->vector_layer_button,
+ gimp_vector_tool_create_vector_layer,
+ tool);
+ }
}
if (! vectors ||
@@ -647,6 +1549,15 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
gtk_widget_set_sensitive (options->stroke_button, TRUE);
}
+ if (options->vector_layer_button)
+ {
+ g_signal_connect_swapped (options->vector_layer_button, "clicked",
+ G_CALLBACK (gimp_vector_tool_create_vector_layer),
+ tool);
+
+ gtk_widget_set_sensitive (options->vector_layer_button, TRUE);
+ }
+
if (tool->display)
{
gimp_tool_path_set_vectors (GIMP_TOOL_PATH (vector_tool->widget), vectors);
@@ -857,3 +1768,30 @@ gimp_vector_tool_stroke_callback (GtkWidget *dialog,
gtk_widget_destroy (dialog);
}
+
+static void
+gimp_vector_tool_create_vector_layer (GimpVectorTool *vector_tool,
+ GtkWidget *button)
+{
+ GimpImage *image;
+ //GtkWidget *dialog;
+ GimpVectorLayer *layer;
+
+ if (! vector_tool->vectors)
+ return;
+
+ image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
+
+ layer = gimp_vector_layer_new (image, vector_tool->vectors,
+ gimp_get_user_context (image->gimp));
+
+ gimp_image_add_layer (image,
+ GIMP_LAYER (layer),
+ GIMP_IMAGE_ACTIVE_PARENT,
+ -1,
+ TRUE);
+
+ gimp_vector_layer_refresh (layer);
+
+ gimp_image_flush (image);
+}
diff --git a/app/vectors/Makefile.am b/app/vectors/Makefile.am
index aa6e10d9e1..66cfd0e7c6 100644
--- a/app/vectors/Makefile.am
+++ b/app/vectors/Makefile.am
@@ -14,31 +14,39 @@ AM_CPPFLAGS = \
noinst_LIBRARIES = libappvectors.a
libappvectors_a_SOURCES = \
- vectors-enums.h \
- vectors-types.h \
- gimpanchor.c \
- gimpanchor.h \
- gimpbezierstroke.h \
- gimpbezierstroke.c \
- gimpstroke.h \
- gimpstroke.c \
- gimpstroke-new.h \
- gimpstroke-new.c \
- gimpvectors.c \
- gimpvectors.h \
- gimpvectors-compat.c \
- gimpvectors-compat.h \
- gimpvectors-export.c \
- gimpvectors-export.h \
- gimpvectors-import.c \
- gimpvectors-import.h \
- gimpvectors-preview.c \
- gimpvectors-preview.h \
- gimpvectors-warp.c \
- gimpvectors-warp.h \
- gimpvectorsmodundo.c \
- gimpvectorsmodundo.h \
- gimpvectorspropundo.c \
- gimpvectorspropundo.h \
- gimpvectorsundo.c \
+ vectors-enums.h \
+ vectors-types.h \
+ gimpanchor.c \
+ gimpanchor.h \
+ gimpbezierstroke.h \
+ gimpbezierstroke.c \
+ gimpstroke.h \
+ 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 \
+ gimpvectors-compat.h \
+ gimpvectors-export.c \
+ gimpvectors-export.h \
+ gimpvectors-import.c \
+ gimpvectors-import.h \
+ gimpvectors-preview.c \
+ gimpvectors-preview.h \
+ gimpvectors-warp.c \
+ gimpvectors-warp.h \
+ gimpvectorsmodundo.c \
+ gimpvectorsmodundo.h \
+ gimpvectorspropundo.c \
+ gimpvectorspropundo.h \
+ gimpvectorsundo.c \
gimpvectorsundo.h
diff --git a/app/vectors/gimpvectorlayer-xcf.c b/app/vectors/gimpvectorlayer-xcf.c
new file mode 100644
index 0000000000..88d050c7fc
--- /dev/null
+++ b/app/vectors/gimpvectorlayer-xcf.c
@@ -0,0 +1,255 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpVectorLayer-xcf
+ * Copyright (C) 2003 Sven Neumann <sven gimp org>
+ * 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 <gdk-pixbuf/gdk-pixbuf.h>
+#include <gio/gio.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#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"
+
+/* FIXME Maybe TextLayer and VectorLayers should have a common ancestor?
+ * There is a lot of duplicate code between the two - Wormnest.
+ */
+
+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_get_image (GIMP_ITEM (*layer))->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 vector 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 vector 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_get_parasites (GIMP_ITEM (layer)), parasite);
+ // Wormnest: changed to the way TextLayer does it, not sure of implications yet!
+ /* Don't push an undo because the parasite only exists temporarily
+ * while the text layer is saved to XCF.
+ */
+ gimp_item_parasite_attach (GIMP_ITEM (layer), parasite, FALSE);
+
+ gimp_parasite_free (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!
+ *
+ * Returns: a newly allocated #GimpVectorLayer object
+ **/
+static GimpLayer *
+gimp_vector_layer_from_layer (GimpLayer *layer,
+ GimpVectorLayerOptions *options)
+{
+ GimpVectorLayer *vector_layer;
+// GimpItem *item;
+ GimpDrawable *drawable;
+// gint offset_x, offset_y;
+
+ 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);
+// Wormnest: text layer uses the below form instead, lets follow that for now:
+ vector_layer = g_object_new (GIMP_TYPE_VECTOR_LAYER,
+ "image", gimp_item_get_image (GIMP_ITEM (layer)),
+ NULL);
+
+ gimp_item_replace_item (GIMP_ITEM (vector_layer), GIMP_ITEM (layer));
+
+// item = GIMP_ITEM (vector_layer);
+ drawable = GIMP_DRAWABLE (vector_layer);
+ gimp_drawable_steal_buffer (drawable, GIMP_DRAWABLE (layer));
+
+/* Wormnest: replacing this with what text layer does...
+ 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));
+ gimp_item_set_tattoo (GIMP_ITEM (item),
+ gimp_item_get_tattoo (GIMP_ITEM (layer)));
+ // item->image = gimp_item_get_image (GIMP_ITEM (layer));
+ gimp_item_set_image (GIMP_ITEM (item),
+ gimp_item_get_image (GIMP_ITEM (layer)));
+
+ gimp_item_set_image (GIMP_ITEM (layer), NULL);
+
+ // Wormnest: is this still necessary or does GimpItem handle this internally?
+ 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;
+ gimp_item_set_parasites (GIMP_ITEM (item),
+ gimp_item_get_parasites (GIMP_ITEM (layer)));
+ gimp_item_set_parasites (GIMP_ITEM (layer), NULL);
+
+ //item->width = gimp_item_get_width (GIMP_ITEM (layer));
+ //item->height = gimp_item_get_height (GIMP_ITEM (layer));
+ gimp_item_set_size (GIMP_ITEM (item),
+ gimp_item_get_width (GIMP_ITEM (layer)),
+ gimp_item_get_height (GIMP_ITEM (layer)));
+
+ gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y);
+ gimp_item_set_offset (GIMP_ITEM (item), offset_x, offset_y);
+
+ //item->visible = gimp_item_get_visible (GIMP_ITEM (layer));
+ //item->linked = gimp_item_get_linked (GIMP_ITEM (layer));
+ gimp_item_set_visible (GIMP_ITEM (item),
+ gimp_item_get_visible (GIMP_ITEM (layer)),
+ FALSE);
+ gimp_item_set_linked (GIMP_ITEM (item),
+ gimp_item_get_linked (GIMP_ITEM (layer)),
+ FALSE);
+
+ gimp_drawable_set_tiles (drawable,
+ FALSE,
+ NULL,
+ gimp_drawable_get_tiles (GIMP_DRAWABLE (layer)),
+ gimp_drawable_type (GIMP_DRAWABLE (layer)));
+ gimp_drawable_set_tiles (GIMP_DRAWABLE (layer),
+ FALSE,
+ NULL,
+ NULL,
+ gimp_drawable_type (GIMP_DRAWABLE (layer)));
+
+ 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);
+*/
+
+ gimp_layer_set_opacity (GIMP_LAYER (vector_layer),
+ gimp_layer_get_opacity (layer), FALSE);
+ gimp_layer_set_mode (GIMP_LAYER (vector_layer),
+ gimp_layer_get_mode (layer), FALSE);
+ gimp_layer_set_blend_space (GIMP_LAYER (vector_layer),
+ gimp_layer_get_blend_space (layer), FALSE);
+ gimp_layer_set_composite_space (GIMP_LAYER (vector_layer),
+ gimp_layer_get_composite_space (layer), FALSE);
+ gimp_layer_set_composite_mode (GIMP_LAYER (vector_layer),
+ gimp_layer_get_composite_mode (layer), FALSE);
+ gimp_layer_set_lock_alpha (GIMP_LAYER (vector_layer),
+ gimp_layer_get_lock_alpha (layer), FALSE);
+
+ /* Wormnest: FIXME below add version for vector layer
+ * Needs get/set functions in gimpvectorlayer like for gimptextlayer */
+ //gimp_text_layer_set_text (text_layer, text);
+
+ g_object_unref (options);
+ g_object_unref (layer);
+
+ return GIMP_LAYER (vector_layer);
+}
diff --git a/app/vectors/gimpvectorlayer-xcf.h b/app/vectors/gimpvectorlayer-xcf.h
new file mode 100644
index 0000000000..2e10fc4b1b
--- /dev/null
+++ b/app/vectors/gimpvectorlayer-xcf.h
@@ -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 <sven gimp org>
+ * 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__ */
diff --git a/app/vectors/gimpvectorlayer.c b/app/vectors/gimpvectorlayer.c
new file mode 100644
index 0000000000..a576198bc7
--- /dev/null
+++ b/app/vectors/gimpvectorlayer.c
@@ -0,0 +1,442 @@
+/* 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 <stdio.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gio/gio.h>
+#include <cairo.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "vectors-types.h"
+
+// #include "base/tile-manager.h"
+
+#include "core/gimp.h"
+#include "core/gimpdrawable-fill.h"
+#include "core/gimpdrawable-stroke.h"
+#include "core/gimpimage.h"
+#include "core/gimpselection.h"
+#include "core/gimpstrokeoptions.h"
+#include "core/gimpparasitelist.h"
+
+#include "gimpvectorlayer.h"
+#include "gimpvectorlayeroptions.h"
+#include "gimpvectors.h"
+#include "vectors-types.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_icon_name = "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_PROP_OBJECT (object_class, PROP_VECTOR_LAYER_OPTIONS,
+ "vector-layer-options", NULL, 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_get_parasites (GIMP_ITEM (layer)),
+ 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 = 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);
+ GimpVectorLayerOptions *new_options;
+
+ new_options = gimp_config_duplicate (GIMP_CONFIG (vector_layer->options));
+
+ g_object_set (new_vector_layer,
+ "vector-layer-options", new_options,
+ NULL);
+
+ g_object_unref (new_options);
+ }
+
+ 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.
+ *
+ * Returns: (nullable) 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);
+ g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+
+ options = gimp_vector_layer_options_new (image, vectors, context);
+
+/* Wormnest: for now mostly following gimp_text_layer_new... */
+ layer =
+ GIMP_VECTOR_LAYER (gimp_drawable_new (GIMP_TYPE_VECTOR_LAYER,
+ image, NULL,
+ 0, 0, 1, 1,
+ gimp_image_get_layer_format (image,
+ TRUE)));
+
+ gimp_layer_set_mode (GIMP_LAYER (layer),
+ gimp_image_get_default_new_layer_mode (image),
+ FALSE);
+
+ // FIXME: Add gimp_vector_layer_set_vector_options...
+/*
+ layer = g_object_new (GIMP_TYPE_VECTOR_LAYER,
+ "vector-layer-options", options,
+ NULL);
+*/
+ g_object_unref (options);
+/*
+ gimp_drawable_configure (GIMP_DRAWABLE (layer), image,
+ 0, 0, 1, 1,
+ gimp_image_base_type_with_alpha (image),
+ NULL);
+*/
+ return layer;
+}
+
+/**
+ * gimp_vector_layer_refresh:
+ * @layer: a #GimpVectorLayer
+ *
+ * Updates the display of the vector layer. Sets the layer name to the name
+ * of the vectors and re renders the vector 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);
+}
+
+/**
+ * gimp_item_is_vector_layer:
+ * @item: a #GimpItem
+ *
+ * Discards the vector information. This makes @layer behave like a
+ * normal layer.
+ *
+ * Returns: whether the item is a vector layer or not.
+ */
+gboolean
+gimp_item_is_vector_layer (GimpItem *item)
+{
+ return (GIMP_IS_VECTOR_LAYER (item) &&
+ GIMP_VECTOR_LAYER (item)->options);
+// TODO: Text layer has:
+// return gimp_item_id_is_text_layer (gimp_item_get_id (item));
+
+}
+
+
+/* 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));
+
+/* FIXME - Wormnest...
+ 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);
+
+ // Wormnest: is user context here the right thing?
+ gimp_drawable_fill (GIMP_DRAWABLE (layer),
+ gimp_get_user_context (image->gimp),
+ GIMP_FILL_TRANSPARENT);
+
+ /* 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)
+{
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
+ GimpChannel *selection = gimp_image_get_mask (image);
+ GList *drawables = g_list_prepend (NULL, GIMP_DRAWABLE (layer));
+
+ /* don't mask these fill/stroke operations */
+ //gimp_selection_push_stroking (GIMP_SELECTION (selection));
+ // Wormnest I think the above is replaced by:
+ gimp_selection_suspend (GIMP_SELECTION (selection));
+
+ /* fill the vectors object onto the layer */
+ gimp_drawable_fill_vectors (GIMP_DRAWABLE (layer),
+ layer->options->fill_options,
+ vectors,
+ FALSE, /* undo */
+ NULL); /* error */
+
+ /* stroke the vectors object onto the layer */
+ gimp_item_stroke (GIMP_ITEM (vectors),
+ drawables,
+ gimp_get_user_context (image->gimp),
+ layer->options->stroke_options,
+ FALSE, FALSE,
+ NULL, NULL);
+
+ g_list_free (drawables);
+
+ //gimp_selection_pop_stroking (GIMP_SELECTION (selection));
+ gimp_selection_resume (GIMP_SELECTION (selection));
+}
+
+/* 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_get_parasites (GIMP_ITEM (layer)),
+ 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);
+ }
+}
diff --git a/app/vectors/gimpvectorlayer.h b/app/vectors/gimpvectorlayer.h
new file mode 100644
index 0000000000..4bcb5810aa
--- /dev/null
+++ b/app/vectors/gimpvectorlayer.h
@@ -0,0 +1,63 @@
+/* GIMP - The GNU 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#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_item_is_vector_layer (GimpItem *item);
+
+
+#endif /* __GIMP_VECTOR_LAYER_H__ */
diff --git a/app/vectors/gimpvectorlayeroptions-parasite.c b/app/vectors/gimpvectorlayeroptions-parasite.c
new file mode 100644
index 0000000000..d42547f6fe
--- /dev/null
+++ b/app/vectors/gimpvectorlayeroptions-parasite.c
@@ -0,0 +1,95 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpVectorLayerOptions-parasite
+ * 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 <string.h>
+#include <stdlib.h>
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#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;
+ guint32 parasite_length;
+
+ g_return_val_if_fail (parasite != NULL, NULL);
+ g_return_val_if_fail (strcmp (gimp_parasite_get_name (parasite),
+ gimp_vector_layer_options_parasite_name ()) == 0,
+ NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ str = gimp_parasite_get_data (parasite, ¶site_length);
+ 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,
+ parasite_length,
+ NULL,
+ error);
+
+ return options;
+}
diff --git a/app/vectors/gimpvectorlayeroptions-parasite.h b/app/vectors/gimpvectorlayeroptions-parasite.h
new file mode 100644
index 0000000000..d42f776e8c
--- /dev/null
+++ b/app/vectors/gimpvectorlayeroptions-parasite.h
@@ -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__ */
diff --git a/app/vectors/gimpvectorlayeroptions.c b/app/vectors/gimpvectorlayeroptions.c
new file mode 100644
index 0000000000..b01e77e9e2
--- /dev/null
+++ b/app/vectors/gimpvectorlayeroptions.c
@@ -0,0 +1,367 @@
+/* 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 <gdk-pixbuf/gdk-pixbuf.h>
+#include <gio/gio.h>
+#include <cairo.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "libgimpcolor/gimpcolor.h"
+
+#include "vectors-types.h"
+
+#include "core/gimp.h"
+#include "core/gimpimage.h"
+#include "core/gimpstrokeoptions.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_OPTIONS
+};
+
+
+/* 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_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_PROP_UINT (object_class, PROP_VECTORS_TATTOO,
+ "vectors-tattoo", NULL, NULL,
+ 0, G_MAXUINT32, 0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_FILL_OPTIONS,
+ "fill-options", NULL, NULL,
+ GIMP_TYPE_FILL_OPTIONS,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_STROKE_OPTIONS,
+ "stroke-options", NULL, NULL,
+ GIMP_TYPE_STROKE_OPTIONS,
+ 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 = gimp_fill_options_new (options->gimp, NULL, FALSE);
+ options->stroke_options = gimp_stroke_options_new (options->gimp, NULL, FALSE);
+
+ 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_options)
+ {
+ g_object_unref (options->stroke_options);
+ options->stroke_options = 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_OPTIONS:
+ g_value_set_object (value, options->stroke_options);
+ 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_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 = g_value_dup_object (value);
+
+ if (options->vectors)
+ {
+ g_signal_connect_object (options->vectors, "invalidate-preview",
+ G_CALLBACK (gimp_vector_layer_options_vectors_changed),
+ options, G_CONNECT_SWAPPED);
+ g_signal_connect_object (options->vectors, "name-changed",
+ G_CALLBACK (gimp_vector_layer_options_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_OPTIONS:
+ if (g_value_get_object (value))
+ {
+ if (options->stroke_options)
+ g_object_unref (options->stroke_options);
+ options->stroke_options = 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_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);
+ g_return_val_if_fail (GIMP_IS_CONTEXT (context), 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);
+
+ gimp_context_set_foreground (GIMP_CONTEXT (options->fill_options),
+ &fill_color);
+ gimp_context_set_pattern (GIMP_CONTEXT (options->fill_options), pattern);
+
+ gimp_context_set_foreground (GIMP_CONTEXT (options->stroke_options),
+ &stroke_color);
+ gimp_context_set_pattern (GIMP_CONTEXT (options->stroke_options), pattern);
+
+ g_object_set (options->stroke_options,
+ "width", 3.0,
+ NULL);
+
+ g_object_set (options,
+ "vectors", vectors,
+ NULL);
+
+ return options;
+}
diff --git a/app/vectors/gimpvectorlayeroptions.h b/app/vectors/gimpvectorlayeroptions.h
new file mode 100644
index 0000000000..e600fccdfb
--- /dev/null
+++ b/app/vectors/gimpvectorlayeroptions.h
@@ -0,0 +1,64 @@
+/* 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;
+ GimpStrokeOptions *stroke_options;
+};
+
+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__ */
diff --git a/app/vectors/meson.build b/app/vectors/meson.build
index 356d88bffb..394a61827c 100644
--- a/app/vectors/meson.build
+++ b/app/vectors/meson.build
@@ -3,6 +3,10 @@ libappvectors_sources = [
'gimpbezierstroke.c',
'gimpstroke-new.c',
'gimpstroke.c',
+ 'gimpvectorlayer.c',
+ 'gimpvectorlayer-xcf.c',
+ 'gimpvectorlayeroptions.c',
+ 'gimpvectorlayeroptions-parasite.c',
'gimpvectors-compat.c',
'gimpvectors-export.c',
'gimpvectors-import.c',
diff --git a/app/vectors/vectors-types.h b/app/vectors/vectors-types.h
index 7c0d2d381a..9569a948cc 100644
--- a/app/vectors/vectors-types.h
+++ b/app/vectors/vectors-types.h
@@ -27,7 +27,16 @@
#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 _GimpVectorLayer GimpVectorLayer;
+typedef struct _GimpVectorLayerOptions GimpVectorLayerOptions;
typedef struct _GimpVectors GimpVectors;
typedef struct _GimpStroke GimpStroke;
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index 2a30ba9222..cf3acfb28a 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -69,6 +69,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"
@@ -2204,7 +2206,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 */
selected = g_list_find (info->selected_layers, layer);
linked = g_list_find (info->linked_layers, layer);
floating = (info->floating_sel == layer);
@@ -2227,6 +2229,16 @@ xcf_load_layer (XcfInfo *info,
if (floating)
info->floating_sel = layer;
}
+ else if (gimp_vector_layer_xcf_load_hack (&layer))
+ {
+ if (selected)
+ {
+ info->selected_layers = g_list_delete_link (info->selected_layers, selected);
+ info->selected_layers = g_list_prepend (info->selected_layers, layer);
+ }
+ if (floating)
+ info->floating_sel = layer;
+ }
/* if this is not the floating selection, we can fix the layer's
* space already now, the function will do nothing if we already
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index 56b773788b..2fd6b3639f 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -64,6 +64,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"
@@ -599,6 +601,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_viewable_get_children (GIMP_VIEWABLE (layer)))
{
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index 785ef2d305..53cdfaac85 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -460,6 +460,10 @@
<menuitem action="layers-text-to-vectors" />
<menuitem action="layers-text-along-vectors" />
</placeholder>
+ <placeholder name="Vector">
+ <menuitem action="layers-vector-fill-stroke" />
+ <menuitem action="layers-vector-discard" />
+ </placeholder>
<separator />
<menu action="layers-stack-menu" name="Stack">
<placeholder name="Select">
diff --git a/menus/layers-menu.xml b/menus/layers-menu.xml
index 03ecfd564d..025d4290ca 100644
--- a/menus/layers-menu.xml
+++ b/menus/layers-menu.xml
@@ -4,6 +4,8 @@
<ui>
<popup action="layers-popup">
<menuitem action="layers-edit-text" />
+ <menuitem action="layers-edit-vector" />
+
<menuitem action="layers-edit-attributes" />
<menu action="layers-blend-space-menu" name="Blend Space">
<menuitem action="layers-blend-space-auto" />
@@ -53,6 +55,9 @@
<menuitem action="layers-text-to-vectors" />
<menuitem action="layers-text-along-vectors" />
<separator />
+ <menuitem action="layers-vector-fill-stroke" />
+ <menuitem action="layers-vector-discard" />
+ <separator />
<menuitem action="layers-resize" />
<menuitem action="layers-resize-to-image" />
<menuitem action="layers-scale" />
diff --git a/menus/vectors-menu.xml b/menus/vectors-menu.xml
index e947c8fa42..ba2dcc7303 100644
--- a/menus/vectors-menu.xml
+++ b/menus/vectors-menu.xml
@@ -24,6 +24,7 @@
<menuitem action="vectors-delete" />
<menuitem action="vectors-merge-visible" />
<separator />
+ <menuitem action="vectors-to-vector-layer" />
<menuitem action="vectors-selection-replace" />
<menuitem action="vectors-selection-add" />
<menuitem action="vectors-selection-subtract" />
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]