Merge branch 'alxsa-vector-layers-2006' into 'master'

Draft: Issue #282: Implement vector layers from GSoC 2006

See merge request GNOME/gimp!773
This commit is contained in:
Alx Sa 2025-07-02 20:35:01 +00:00
commit ed96b0b090
34 changed files with 2609 additions and 6 deletions

View file

@ -33,6 +33,8 @@
#include "text/gimptextlayer.h" #include "text/gimptextlayer.h"
#include "vectors/gimpvectorlayer.h"
#include "widgets/gimphelp-ids.h" #include "widgets/gimphelp-ids.h"
#include "widgets/gimpactiongroup.h" #include "widgets/gimpactiongroup.h"
#include "widgets/gimpwidgets-utils.h" #include "widgets/gimpwidgets-utils.h"
@ -60,6 +62,12 @@ static const GimpActionEntry layers_actions[] =
layers_edit_text_cmd_callback, layers_edit_text_cmd_callback,
GIMP_HELP_LAYER_EDIT }, GIMP_HELP_LAYER_EDIT },
{ "layers-edit-vector", GIMP_ICON_TOOL_PATH,
N_("Path Tool"), NULL, { NULL },
N_("Activate the path tool on this vector layer's path"),
layers_edit_vector_cmd_callback,
GIMP_HELP_TOOL_PATH },
{ "layers-edit-attributes", GIMP_ICON_EDIT, { "layers-edit-attributes", GIMP_ICON_EDIT,
NC_("layers-action", "_Edit Layer Attributes..."), NULL, { NULL }, NC_("layers-action", "_Edit Layer Attributes..."), NULL, { NULL },
NC_("layers-action", "Edit the layer's name"), NC_("layers-action", "Edit the layer's name"),
@ -191,6 +199,18 @@ static const GimpActionEntry layers_actions[] =
layers_text_along_vectors_cmd_callback, layers_text_along_vectors_cmd_callback,
GIMP_HELP_LAYER_TEXT_ALONG_PATH }, GIMP_HELP_LAYER_TEXT_ALONG_PATH },
{ "layers-vector-fill-stroke", NULL,
NC_("layers-action", "Fill / Stroke"), NULL, { NULL },
NC_("layers-action", "Edit the fill and stroke of this vector layer"),
layers_vector_fill_stroke_cmd_callback,
NULL },
{ "layers-vector-discard", NULL,
NC_("layers-action", "Discard Vector Information"), NULL, { NULL },
NC_("layers-action", "Turn this vector layer into a normal layer"),
layers_vector_discard_cmd_callback,
NULL },
{ "layers-resize", GIMP_ICON_OBJECT_RESIZE, { "layers-resize", GIMP_ICON_OBJECT_RESIZE,
NC_("layers-action", "Layer B_oundary Size..."), NULL, { NULL }, NC_("layers-action", "Layer B_oundary Size..."), NULL, { NULL },
NC_("layers-action", "Adjust the layer dimensions"), NC_("layers-action", "Adjust the layer dimensions"),
@ -757,6 +777,7 @@ layers_actions_update (GimpActionGroup *group,
gboolean lock_alpha = TRUE; gboolean lock_alpha = TRUE;
gboolean can_lock_alpha = FALSE; gboolean can_lock_alpha = FALSE;
gboolean text_layer = FALSE; gboolean text_layer = FALSE;
gboolean vector_layer = FALSE;
gboolean bs_mutable = FALSE; /* At least 1 selected layers' blend space is mutable. */ 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 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. */ gboolean cm_mutable = FALSE; /* At least 1 selected layers' composite mode is mutable. */
@ -977,7 +998,8 @@ layers_actions_update (GimpActionGroup *group,
gimp_action_group_set_action_active (group, action, TRUE); 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));
} }
} }
@ -993,6 +1015,7 @@ layers_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer)); SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer));
SET_VISIBLE ("layers-edit-text", text_layer && !ac); SET_VISIBLE ("layers-edit-text", text_layer && !ac);
SET_SENSITIVE ("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-attributes", layer && !fs && !ac); SET_SENSITIVE ("layers-edit-attributes", layer && !fs && !ac);
if (layer && gimp_layer_is_floating_sel (layer)) if (layer && gimp_layer_is_floating_sel (layer))
@ -1042,6 +1065,9 @@ layers_actions_update (GimpActionGroup *group,
SET_VISIBLE ("layers-text-to-vectors", n_text_layers > 0 && !ac); SET_VISIBLE ("layers-text-to-vectors", n_text_layers > 0 && !ac);
SET_VISIBLE ("layers-text-along-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", n_selected_layers == 1 && all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-resize-to-image", 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); SET_SENSITIVE ("layers-scale", n_selected_layers == 1 && all_writable && all_movable && !ac);

View file

@ -62,6 +62,8 @@
#include "vectors/gimppath.h" #include "vectors/gimppath.h"
#include "vectors/gimppath-warp.h" #include "vectors/gimppath-warp.h"
#include "vectors/gimpstroke.h" #include "vectors/gimpstroke.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayeroptions.h"
#include "widgets/gimpaction.h" #include "widgets/gimpaction.h"
#include "widgets/gimpdock.h" #include "widgets/gimpdock.h"
@ -73,6 +75,7 @@
#include "display/gimpimagewindow.h" #include "display/gimpimagewindow.h"
#include "tools/gimptexttool.h" #include "tools/gimptexttool.h"
#include "tools/gimpvectortool.h"
#include "tools/tool_manager.h" #include "tools/tool_manager.h"
#include "dialogs/dialogs.h" #include "dialogs/dialogs.h"
@ -80,6 +83,7 @@
#include "dialogs/layer-options-dialog.h" #include "dialogs/layer-options-dialog.h"
#include "dialogs/resize-dialog.h" #include "dialogs/resize-dialog.h"
#include "dialogs/scale-dialog.h" #include "dialogs/scale-dialog.h"
#include "dialogs/vector-layer-options-dialog.h"
#include "actions.h" #include "actions.h"
#include "items-commands.h" #include "items-commands.h"
@ -200,6 +204,10 @@ layers_edit_cmd_callback (GimpAction *action,
{ {
layers_edit_text_cmd_callback (action, value, data); layers_edit_text_cmd_callback (action, value, data);
} }
else if (gimp_item_is_vector_layer (GIMP_ITEM (layers->data)))
{
layers_vector_fill_stroke_cmd_callback (action, value, data);
}
else else
{ {
layers_edit_attributes_cmd_callback (action, value, data); layers_edit_attributes_cmd_callback (action, value, data);
@ -251,6 +259,52 @@ layers_edit_text_cmd_callback (GimpAction *action,
} }
} }
void
layers_edit_vector_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GList *layers;
GtkWidget *widget;
GimpTool *active_tool;
return_if_no_layers (image, layers, data);
return_if_no_widget (widget, data);
if (g_list_length (layers) != 1)
return;
layer = layers->data;
if (! gimp_item_is_vector_layer (GIMP_ITEM (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");
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->path);
}
void void
layers_edit_attributes_cmd_callback (GimpAction *action, layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,
@ -2591,6 +2645,56 @@ layers_scale_callback (GtkWidget *dialog,
} }
} }
void
layers_vector_fill_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GList *layers;
GtkWidget *widget;
return_if_no_layers (image, layers, data);
return_if_no_widget (widget, data);
if (g_list_length (layers) != 1)
return;
layer = layers->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"),
"gimp-vector-layer-stroke",
NULL,
widget);
gtk_widget_show (dialog);
}
}
void
layers_vector_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GList *layers;
return_if_no_layers (image, layers, data);
if (g_list_length (layers) != 1)
return;
layer = layers->data;
if (GIMP_IS_VECTOR_LAYER (layer))
gimp_vector_layer_discard (GIMP_VECTOR_LAYER (layer));
}
static void static void
layers_resize_callback (GtkWidget *dialog, layers_resize_callback (GtkWidget *dialog,
GimpViewable *viewable, GimpViewable *viewable,

View file

@ -25,6 +25,9 @@ void layers_edit_cmd_callback (GimpAction *action,
void layers_edit_text_cmd_callback (GimpAction *action, void layers_edit_text_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,
gpointer data); gpointer data);
void layers_edit_vector_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_edit_attributes_cmd_callback (GimpAction *action, void layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,
gpointer data); gpointer data);
@ -84,6 +87,12 @@ void layers_text_to_vectors_cmd_callback (GimpAction *action,
void layers_text_along_vectors_cmd_callback (GimpAction *action, void layers_text_along_vectors_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,
gpointer data); 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, void layers_resize_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,

View file

@ -149,7 +149,12 @@ static const GimpActionEntry paths_actions[] =
{ "paths-import", GIMP_ICON_DOCUMENT_OPEN, { "paths-import", GIMP_ICON_DOCUMENT_OPEN,
NC_("paths-action", "I_mport Path..."), NULL, { NULL }, NULL, NC_("paths-action", "I_mport Path..."), NULL, { NULL }, NULL,
paths_import_cmd_callback, paths_import_cmd_callback,
GIMP_HELP_PATH_IMPORT } GIMP_HELP_PATH_IMPORT },
{ "paths-to-vector-layer", NULL,
NC_("paths-action", "Path to Vector Layer"), NULL, { NULL }, NULL,
path_to_vector_layer_cmd_callback,
NULL },
}; };
static const GimpToggleActionEntry paths_toggle_actions[] = static const GimpToggleActionEntry paths_toggle_actions[] =
@ -429,6 +434,8 @@ paths_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("paths-export", n_selected_paths > 0); SET_SENSITIVE ("paths-export", n_selected_paths > 0);
SET_SENSITIVE ("paths-import", image); SET_SENSITIVE ("paths-import", image);
SET_SENSITIVE ("paths-to-vector-layer", n_selected_paths > 0);
SET_SENSITIVE ("paths-selection-to-path", image && !mask_empty); SET_SENSITIVE ("paths-selection-to-path", image && !mask_empty);
SET_SENSITIVE ("paths-selection-to-path-advanced", image && !mask_empty); SET_SENSITIVE ("paths-selection-to-path-advanced", image && !mask_empty);
SET_SENSITIVE ("paths-fill", n_selected_paths > 0 && SET_SENSITIVE ("paths-fill", n_selected_paths > 0 &&

View file

@ -47,6 +47,7 @@
#include "vectors/gimppath.h" #include "vectors/gimppath.h"
#include "vectors/gimppath-export.h" #include "vectors/gimppath-export.h"
#include "vectors/gimppath-import.h" #include "vectors/gimppath-import.h"
#include "vectors/gimpvectorlayer.h"
#include "widgets/gimpaction.h" #include "widgets/gimpaction.h"
#include "widgets/gimpclipboard.h" #include "widgets/gimpclipboard.h"
@ -509,6 +510,28 @@ paths_merge_visible_cmd_callback (GimpAction *action,
gimp_image_flush (image); gimp_image_flush (image);
} }
void
path_to_vector_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GList *paths;
GimpVectorLayer *layer;
return_if_no_paths (image, paths, data);
layer = gimp_vector_layer_new (image, paths->data,
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 void
paths_to_selection_cmd_callback (GimpAction *action, paths_to_selection_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,

View file

@ -51,6 +51,9 @@ void paths_duplicate_cmd_callback (GimpAction *action,
void paths_delete_cmd_callback (GimpAction *action, void paths_delete_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,
gpointer data); gpointer data);
void path_to_vector_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void paths_merge_visible_cmd_callback (GimpAction *action, void paths_merge_visible_cmd_callback (GimpAction *action,
GVariant *value, GVariant *value,
gpointer data); gpointer data);

View file

@ -1267,6 +1267,8 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_TEXT_LAYER, "GIMP_UNDO_TEXT_LAYER", "text-layer" }, { GIMP_UNDO_TEXT_LAYER, "GIMP_UNDO_TEXT_LAYER", "text-layer" },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" }, { GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" },
{ GIMP_UNDO_TEXT_LAYER_CONVERT, "GIMP_UNDO_TEXT_LAYER_CONVERT", "text-layer-convert" }, { GIMP_UNDO_TEXT_LAYER_CONVERT, "GIMP_UNDO_TEXT_LAYER_CONVERT", "text-layer-convert" },
{ GIMP_UNDO_VECTOR_LAYER, "GIMP_UNDO_VECTOR_LAYER", "vector-layer" },
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, "GIMP_UNDO_VECTOR_LAYER_MODIFIED", "vector-layer-modified" },
{ GIMP_UNDO_LAYER_MASK_ADD, "GIMP_UNDO_LAYER_MASK_ADD", "layer-mask-add" }, { GIMP_UNDO_LAYER_MASK_ADD, "GIMP_UNDO_LAYER_MASK_ADD", "layer-mask-add" },
{ GIMP_UNDO_LAYER_MASK_REMOVE, "GIMP_UNDO_LAYER_MASK_REMOVE", "layer-mask-remove" }, { GIMP_UNDO_LAYER_MASK_REMOVE, "GIMP_UNDO_LAYER_MASK_REMOVE", "layer-mask-remove" },
{ GIMP_UNDO_LAYER_MASK_APPLY, "GIMP_UNDO_LAYER_MASK_APPLY", "layer-mask-apply" }, { GIMP_UNDO_LAYER_MASK_APPLY, "GIMP_UNDO_LAYER_MASK_APPLY", "layer-mask-apply" },
@ -1380,6 +1382,8 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text layer"), NULL }, { GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text layer"), NULL },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, NC_("undo-type", "Text layer modification"), NULL }, { GIMP_UNDO_TEXT_LAYER_MODIFIED, NC_("undo-type", "Text layer modification"), NULL },
{ GIMP_UNDO_TEXT_LAYER_CONVERT, NC_("undo-type", "Convert text layer"), NULL }, { GIMP_UNDO_TEXT_LAYER_CONVERT, NC_("undo-type", "Convert text layer"), NULL },
{ GIMP_UNDO_VECTOR_LAYER, NC_("undo-type", "Vector layer"), NULL },
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, NC_("undo-type", "Vector layer modification"), NULL },
{ GIMP_UNDO_LAYER_MASK_ADD, NC_("undo-type", "Add layer masks"), NULL }, { GIMP_UNDO_LAYER_MASK_ADD, NC_("undo-type", "Add layer masks"), NULL },
{ GIMP_UNDO_LAYER_MASK_REMOVE, NC_("undo-type", "Delete layer masks"), NULL }, { GIMP_UNDO_LAYER_MASK_REMOVE, NC_("undo-type", "Delete layer masks"), NULL },
{ GIMP_UNDO_LAYER_MASK_APPLY, NC_("undo-type", "Apply layer masks"), NULL }, { GIMP_UNDO_LAYER_MASK_APPLY, NC_("undo-type", "Apply layer masks"), NULL },

View file

@ -621,6 +621,8 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/ GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/
GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/ GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/
GIMP_UNDO_TEXT_LAYER_CONVERT, /*< desc="Convert text layer" >*/ GIMP_UNDO_TEXT_LAYER_CONVERT, /*< desc="Convert text layer" >*/
GIMP_UNDO_VECTOR_LAYER, /*< desc="Vector layer" >*/
GIMP_UNDO_VECTOR_LAYER_MODIFIED, /*< desc="Vector layer modification" >*/
GIMP_UNDO_LAYER_MASK_ADD, /*< desc="Add layer masks" >*/ GIMP_UNDO_LAYER_MASK_ADD, /*< desc="Add layer masks" >*/
GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer masks" >*/ GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer masks" >*/
GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer masks" >*/ GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer masks" >*/

View file

@ -60,6 +60,8 @@
#include "vectors/gimppathmodundo.h" #include "vectors/gimppathmodundo.h"
#include "vectors/gimppathpropundo.h" #include "vectors/gimppathpropundo.h"
#include "vectors/gimppathundo.h" #include "vectors/gimppathundo.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayerundo.h"
#include "gimp-intl.h" #include "gimp-intl.h"
@ -877,6 +879,45 @@ gimp_image_undo_push_text_layer_convert (GimpImage *image,
} }
/************************/
/* Vector Layer Undos */
/************************/
GimpUndo *
gimp_image_undo_push_vector_layer (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer,
const GParamSpec *pspec)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_VECTOR_LAYER_UNDO,
GIMP_UNDO_VECTOR_LAYER, undo_desc,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
"item", layer,
"param", pspec,
NULL);
}
GimpUndo *
gimp_image_undo_push_vector_layer_modified (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_VECTOR_LAYER_UNDO,
GIMP_UNDO_VECTOR_LAYER_MODIFIED, undo_desc,
GIMP_DIRTY_ITEM_META,
"item", layer,
NULL);
}
/**********************/ /**********************/
/* Layer Mask Undos */ /* Layer Mask Undos */
/**********************/ /**********************/

View file

@ -216,6 +216,17 @@ GimpUndo * gimp_image_undo_push_text_layer_convert (GimpImage *image,
GimpTextLayer *layer); GimpTextLayer *layer);
/* vector layer undos */
GimpUndo * gimp_image_undo_push_vector_layer (GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer,
const GParamSpec *pspec);
GimpUndo * gimp_image_undo_push_vector_layer_modified
(GimpImage *image,
const gchar *undo_desc,
GimpVectorLayer *layer);
/* layer mask undos */ /* layer mask undos */
GimpUndo * gimp_image_undo_push_layer_mask_add (GimpImage *image, GimpUndo * gimp_image_undo_push_layer_mask_add (GimpImage *image,

View file

@ -56,6 +56,7 @@ libappdialogs_sources = [
'tips-dialog.c', 'tips-dialog.c',
'tips-parser.c', 'tips-parser.c',
'user-install-dialog.c', 'user-install-dialog.c',
'vector-layer-options-dialog.c',
'welcome-dialog.c', 'welcome-dialog.c',
gitversion_h, gitversion_h,
welcome_dialog_data_c, welcome_dialog_data_c,

View file

@ -0,0 +1,301 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* vector-layer-options-dialog.h
*
* Copyright 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 3 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/>.
*/
#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/gimpimage-undo-push.h"
#include "core/gimpstrokeoptions.h"
#include "widgets/gimpcolorpanel.h"
#include "widgets/gimpcontainercombobox.h"
#include "widgets/gimpcontainerview.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpviewabledialog.h"
#include "widgets/gimpstrokeeditor.h"
#include "vectors/gimppath.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);
static void vector_layer_options_dialog_path_selected (GtkWidget *widget,
GList *items,
GList *paths,
GtkWidget *dialog);
/* public function */
GtkWidget *
vector_layer_options_dialog_new (GimpVectorLayer *layer,
GimpContext *context,
const gchar *title,
const gchar *icon_name,
const gchar *help_id,
GtkWidget *parent)
{
GimpVectorLayerOptions *saved_options;
GimpFillOptions *fill_options;
GimpStrokeOptions *stroke_options;
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *combo;
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 (icon_name != NULL, NULL);
g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL);
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, GIMP_VIEWABLE (layer)),
context,
title, "gimp-vectorlayer-options",
icon_name,
_("Choose Vector Layer Options"),
parent,
gimp_standard_help_func,
help_id,
_("_Reset"), RESPONSE_RESET,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Apply"), GTK_RESPONSE_OK,
NULL);
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);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
main_vbox, TRUE, TRUE, 0);
gtk_widget_set_visible (main_vbox, TRUE);
combo = gimp_container_combo_box_new (gimp_image_get_paths (gimp_item_get_image (GIMP_ITEM (layer))),
context,
GIMP_VIEW_SIZE_SMALL, 1);
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (combo),
GIMP_VIEWABLE (saved_options->path));
g_signal_connect_object (combo, "select-items",
G_CALLBACK (vector_layer_options_dialog_path_selected),
dialog, 0);
gtk_box_pack_start (GTK_BOX (main_vbox), combo, FALSE, FALSE, 0);
gtk_widget_set_visible (combo, TRUE);
/* 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_set_visible (frame, TRUE);
fill_editor = gimp_fill_editor_new (fill_options, TRUE, TRUE);
gtk_container_add (GTK_CONTAINER (frame), fill_editor);
gtk_widget_set_visible (fill_editor, TRUE);
}
/* 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_set_visible (frame, TRUE);
gimp_image_get_resolution (gimp_item_get_image (GIMP_ITEM (layer)),
&xres, &yres);
stroke_editor = gimp_stroke_editor_new (stroke_options, yres, TRUE, TRUE);
gtk_container_add (GTK_CONTAINER (frame), stroke_editor);
gtk_widget_set_visible (stroke_editor, TRUE);
}
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;
GimpPath *path;
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:
if (layer && layer->options)
{
gimp_config_sync (G_OBJECT (saved_options->fill_options),
G_OBJECT (layer->options->fill_options), 0);
gimp_config_sync (G_OBJECT (saved_options->stroke_options),
G_OBJECT (layer->options->stroke_options), 0);
gimp_image_undo_push_vector_layer (gimp_item_get_image (GIMP_ITEM (layer)),
_("Fill/Stroke Vector Layer"),
layer, NULL);
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);
}
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 (layer && layer->options)
{
g_object_get (saved_options, "path", &path, NULL);
g_object_set (layer->options, "path", path, NULL);
gimp_vector_layer_refresh (layer);
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer)));
}
if (response_id != RESPONSE_RESET)
gtk_widget_destroy (dialog);
break;
}
}
static void
vector_layer_options_dialog_path_selected (GtkWidget *widget,
GList *items,
GList *paths,
GtkWidget *dialog)
{
GimpPath *path = NULL;
GimpVectorLayer *layer;
layer = g_object_get_data (G_OBJECT (dialog), "layer");
if (items)
path = items->data;
if (path && GIMP_IS_PATH (path))
{
g_object_set (layer->options, "path", path, NULL);
gimp_vector_layer_refresh (layer);
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer)));
}
}

View file

@ -0,0 +1,34 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* vector-layer-options-dialog.h
*
* Copyright 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 3 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 __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 *icon_name,
const gchar *help_id,
GtkWidget *parent);
#endif /* __VECTOR_LAYER_OPTIONS_DIALOG_H__ */

View file

@ -192,7 +192,7 @@ gimp_vector_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_set_sensitive (button, FALSE); gtk_widget_set_sensitive (button, FALSE);
gimp_help_set_help_data (button, str, GIMP_HELP_PATH_SELECTION_REPLACE); gimp_help_set_help_data (button, str, GIMP_HELP_PATH_SELECTION_REPLACE);
gtk_widget_show (button); gtk_widget_set_visible (button, TRUE);
g_free (str); g_free (str);
@ -202,7 +202,7 @@ gimp_vector_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_set_sensitive (button, FALSE); gtk_widget_set_sensitive (button, FALSE);
gimp_help_set_help_data (button, NULL, GIMP_HELP_PATH_FILL); gimp_help_set_help_data (button, NULL, GIMP_HELP_PATH_FILL);
gtk_widget_show (button); gtk_widget_set_visible (button, TRUE);
options->fill_button = button; options->fill_button = button;
@ -210,9 +210,17 @@ gimp_vector_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_set_sensitive (button, FALSE); gtk_widget_set_sensitive (button, FALSE);
gimp_help_set_help_data (button, NULL, GIMP_HELP_PATH_STROKE); gimp_help_set_help_data (button, NULL, GIMP_HELP_PATH_STROKE);
gtk_widget_show (button); gtk_widget_set_visible (button, TRUE);
options->stroke_button = button; 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);
gtk_widget_set_visible (button, TRUE);
options->vector_layer_button = button;
return vbox; return vbox;
} }

View file

@ -44,6 +44,7 @@ struct _GimpVectorOptions
GtkWidget *to_selection_button; GtkWidget *to_selection_button;
GtkWidget *fill_button; GtkWidget *fill_button;
GtkWidget *stroke_button; GtkWidget *stroke_button;
GtkWidget *vector_layer_button;
}; };

View file

@ -41,6 +41,8 @@
#include "paint/gimppaintoptions.h" /* GIMP_PAINT_OPTIONS_CONTEXT_MASK */ #include "paint/gimppaintoptions.h" /* GIMP_PAINT_OPTIONS_CONTEXT_MASK */
#include "vectors/gimppath.h" #include "vectors/gimppath.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayeroptions.h"
#include "widgets/gimpdialogfactory.h" #include "widgets/gimpdialogfactory.h"
#include "widgets/gimpdockcontainer.h" #include "widgets/gimpdockcontainer.h"
@ -70,6 +72,7 @@
/* local function prototypes */ /* local function prototypes */
static void gimp_vector_tool_constructed (GObject *object);
static void gimp_vector_tool_dispose (GObject *object); static void gimp_vector_tool_dispose (GObject *object);
static void gimp_vector_tool_control (GimpTool *tool, static void gimp_vector_tool_control (GimpTool *tool,
@ -106,6 +109,12 @@ static void gimp_vector_tool_start (GimpVectorTool *vector_
GimpDisplay *display); GimpDisplay *display);
static void gimp_vector_tool_halt (GimpVectorTool *vector_tool); static void gimp_vector_tool_halt (GimpVectorTool *vector_tool);
static void gimp_vector_tool_image_changed (GimpVectorTool *vector_tool,
GimpImage *image,
GimpContext *context);
static void gimp_vector_tool_image_selected_layers_changed
(GimpVectorTool *vector_tool);
static void gimp_vector_tool_path_changed (GimpToolWidget *path, static void gimp_vector_tool_path_changed (GimpToolWidget *path,
GimpVectorTool *vector_tool); GimpVectorTool *vector_tool);
static void gimp_vector_tool_path_begin_change static void gimp_vector_tool_path_begin_change
@ -147,6 +156,10 @@ static void gimp_vector_tool_stroke_callback (GtkWidget *dialog,
GimpStrokeOptions *options, GimpStrokeOptions *options,
gpointer data); 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) G_DEFINE_TYPE (GimpVectorTool, gimp_vector_tool, GIMP_TYPE_DRAW_TOOL)
@ -178,6 +191,7 @@ gimp_vector_tool_class_init (GimpVectorToolClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass); GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
object_class->constructed = gimp_vector_tool_constructed;
object_class->dispose = gimp_vector_tool_dispose; object_class->dispose = gimp_vector_tool_dispose;
tool_class->control = gimp_vector_tool_control; tool_class->control = gimp_vector_tool_control;
@ -202,6 +216,29 @@ gimp_vector_tool_init (GimpVectorTool *vector_tool)
vector_tool->saved_mode = GIMP_VECTOR_MODE_DESIGN; vector_tool->saved_mode = GIMP_VECTOR_MODE_DESIGN;
} }
static void
gimp_vector_tool_constructed (GObject *object)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (object);
GimpContext *context;
GimpToolInfo *tool_info;
G_OBJECT_CLASS (parent_class)->constructed (object);
tool_info = GIMP_TOOL (vector_tool)->tool_info;
context = gimp_get_user_context (tool_info->gimp);
g_signal_connect_object (context, "image-changed",
G_CALLBACK (gimp_vector_tool_image_changed),
vector_tool, G_CONNECT_SWAPPED);
gimp_vector_tool_image_changed (vector_tool,
gimp_context_get_image (context),
context);
}
static void static void
gimp_vector_tool_dispose (GObject *object) gimp_vector_tool_dispose (GObject *object)
{ {
@ -210,6 +247,8 @@ gimp_vector_tool_dispose (GObject *object)
gimp_vector_tool_set_vectors (vector_tool, NULL); gimp_vector_tool_set_vectors (vector_tool, NULL);
g_clear_object (&vector_tool->widget); g_clear_object (&vector_tool->widget);
gimp_vector_tool_image_changed (vector_tool, NULL, NULL);
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -444,6 +483,51 @@ gimp_vector_tool_halt (GimpVectorTool *vector_tool)
tool->display = NULL; tool->display = NULL;
} }
static void
gimp_vector_tool_image_changed (GimpVectorTool *vector_tool,
GimpImage *image,
GimpContext *context)
{
if (vector_tool->current_image)
g_signal_handlers_disconnect_by_func (vector_tool->current_image,
gimp_vector_tool_image_selected_layers_changed,
NULL);
g_set_weak_pointer (&vector_tool->current_image, image);
if (vector_tool->current_image)
g_signal_connect_object (vector_tool->current_image, "selected-layers-changed",
G_CALLBACK (gimp_vector_tool_image_selected_layers_changed),
vector_tool, G_CONNECT_SWAPPED);
gimp_vector_tool_image_selected_layers_changed (vector_tool);
}
static void
gimp_vector_tool_image_selected_layers_changed (GimpVectorTool *vector_tool)
{
GList *current_layers = NULL;
if (vector_tool->current_image)
current_layers =
gimp_image_get_selected_layers (vector_tool->current_image);
if (current_layers)
{
/* If we've selected a single vector layer, make its path editable */
if (g_list_length (current_layers) == 1 &&
GIMP_IS_VECTOR_LAYER (current_layers->data))
{
GimpVectorLayer *vector_layer = current_layers->data;
if (vector_layer->options && vector_layer->options->path)
gimp_vector_tool_set_vectors (vector_tool,
vector_layer->options->path);
}
}
}
static void static void
gimp_vector_tool_path_changed (GimpToolWidget *path, gimp_vector_tool_path_changed (GimpToolWidget *path,
GimpVectorTool *vector_tool) GimpVectorTool *vector_tool)
@ -609,6 +693,14 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
gimp_vector_tool_stroke_vectors, gimp_vector_tool_stroke_vectors,
tool); 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 || if (! vectors ||
@ -657,6 +749,15 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
gtk_widget_set_sensitive (options->stroke_button, TRUE); 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) if (tool->display)
{ {
gimp_tool_path_set_vectors (GIMP_TOOL_PATH (vector_tool->widget), vectors); gimp_tool_path_set_vectors (GIMP_TOOL_PATH (vector_tool->widget), vectors);
@ -898,3 +999,30 @@ gimp_vector_tool_stroke_callback (GtkWidget *dialog,
gimp_image_flush (image); gimp_image_flush (image);
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
} }
static void
gimp_vector_tool_create_vector_layer (GimpVectorTool *vector_tool,
GtkWidget *button)
{
GimpImage *image;
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);
}

View file

@ -42,6 +42,8 @@ struct _GimpVectorTool
{ {
GimpDrawTool parent_instance; GimpDrawTool parent_instance;
GimpImage *current_image;
GimpPath *vectors; /* the current Path data */ GimpPath *vectors; /* the current Path data */
GimpVectorMode saved_mode; /* used by modifier_key() */ GimpVectorMode saved_mode; /* used by modifier_key() */

View file

@ -0,0 +1,171 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayer-xcf.c
*
* Copyright 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 3 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/>.
*/
#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"
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),
"path", gimp_image_get_path_by_tattoo (
gimp_item_get_image (GIMP_ITEM (*layer)),
options->path_tattoo),
NULL);
if (error)
{
g_message (_("Problems parsing the vector layer parasite for layer '%s':\n"
"%s\n\n"
"Some vector layer properties may be wrong. "),
gimp_object_get_name (GIMP_OBJECT (*layer)),
error->message);
g_error_free (error);
}
}
if (options)
{
*layer = gimp_vector_layer_from_layer (*layer, options);
/* let the text layer know what parasite was used to create it */
GIMP_VECTOR_LAYER (*layer)->parasite = name;
}
return (options != NULL);
}
void
gimp_vector_layer_xcf_save_prepare (GimpVectorLayer *layer)
{
GimpVectorLayerOptions *options;
g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer));
/* If the layer has a text parasite already, it wasn't changed and we
* can simply save the original parasite back which is still attached.
*/
if (layer->parasite)
return;
g_object_get (layer, "vector-layer-options", &options, NULL);
if (options)
{
GimpParasite *parasite = gimp_vector_layer_options_to_parasite (options);
gimp_parasite_list_add (gimp_item_get_parasites (GIMP_ITEM (layer)), 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 it afterwards!
*
* This is a gross hack that is needed in order to load vector layers
* from XCF files in a backwards-compatible way. Please don't use it
* for anything else!
*
* Return value: a newly allocated #GimpVectorLayer object
**/
static GimpLayer *
gimp_vector_layer_from_layer (GimpLayer *layer,
GimpVectorLayerOptions *options)
{
GimpVectorLayer *vector_layer;
GimpDrawable *drawable;
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER_OPTIONS (options), NULL);
vector_layer = g_object_new (GIMP_TYPE_VECTOR_LAYER,
"image", gimp_item_get_image (GIMP_ITEM (layer)),
"vector-layer-options", options,
NULL);
gimp_item_replace_item (GIMP_ITEM (vector_layer), GIMP_ITEM (layer));
drawable = GIMP_DRAWABLE (vector_layer);
gimp_drawable_steal_buffer (drawable, GIMP_DRAWABLE (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);
g_object_unref (options);
g_object_unref (layer);
return GIMP_LAYER (vector_layer);
}

View file

@ -0,0 +1,33 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayer-xcf.h
*
* Copyright 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 3 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_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__ */

View file

@ -0,0 +1,712 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayer.c
*
* Copyright 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 3 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/>.
*/
#include "config.h"
#include <stdio.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpconfig/gimpconfig.h"
#include "vectors-types.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/gimpimage-undo.h"
#include "core/gimpimage-undo-push.h"
#include "core/gimpstrokeoptions.h"
#include "core/gimpparasitelist.h"
#include "gimpvectorlayer.h"
#include "gimpvectorlayeroptions.h"
#include "gimppath.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_VECTOR_LAYER_OPTIONS,
PROP_MODIFIED
};
/* 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 void gimp_vector_layer_set_vector_options
(GimpVectorLayer *layer,
GimpVectorLayerOptions *options);
static void gimp_vector_layer_set_buffer (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc,
GeglBuffer *buffer,
const GeglRectangle *bounds);
static void gimp_vector_layer_push_undo (GimpDrawable *drawable,
const gchar *undo_desc,
GeglBuffer *buffer,
gint x,
gint y,
gint width,
gint height);
static gint64 gimp_vector_layer_get_memsize (GimpObject *object,
gint64 *gui_size);
static GimpItem * gimp_vector_layer_duplicate (GimpItem *item,
GType new_type);
static void gimp_vector_layer_translate (GimpLayer *layer,
gint offset_x,
gint offset_y);
static void gimp_vector_layer_scale (GimpItem *item,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interp_type,
GimpProgress *progress);
static void gimp_vector_layer_flip (GimpItem *item,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result);
static void gimp_vector_layer_rotate (GimpItem *item,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result);
static void gimp_vector_layer_transform (GimpItem *item,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interp_type,
GimpTransformResize clip_result,
GimpProgress *progress);
static gboolean gimp_vector_layer_render (GimpVectorLayer *layer);
static void gimp_vector_layer_render_path (GimpVectorLayer *layer,
GimpPath *path);
static void gimp_vector_layer_changed_options (GimpVectorLayer *layer);
static void gimp_vector_layer_removed (GimpItem *item);
static void gimp_vector_layer_removed_options_path
(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);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass);
GimpLayerClass *layer_class = GIMP_LAYER_CLASS (klass);
drawable_class->set_buffer = gimp_vector_layer_set_buffer;
drawable_class->push_undo = gimp_vector_layer_push_undo;
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;
gimp_object_class->get_memsize = gimp_vector_layer_get_memsize;
viewable_class->default_icon_name = "gimp-vector-layer";
layer_class->translate = gimp_vector_layer_translate;
item_class->removed = gimp_vector_layer_removed;
item_class->duplicate = gimp_vector_layer_duplicate;
item_class->scale = gimp_vector_layer_scale;
item_class->flip = gimp_vector_layer_flip;
item_class->rotate = gimp_vector_layer_rotate;
item_class->transform = gimp_vector_layer_transform;
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,
G_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_MODIFIED,
"modified",
NULL, NULL,
FALSE,
GIMP_PARAM_STATIC_STRINGS);
}
static void
gimp_vector_layer_init (GimpVectorLayer *layer)
{
layer->options = NULL;
layer->parasite = NULL;
layer->modified = FALSE;
}
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;
case PROP_MODIFIED:
g_value_set_boolean (value, vector_layer->modified);
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);
if (vector_layer->options->path)
g_signal_handlers_disconnect_by_func (vector_layer->options->path,
G_CALLBACK (gimp_vector_layer_removed_options_path),
vector_layer);
g_object_unref (vector_layer->options);
}
vector_layer->options = g_value_dup_object (value);
if (vector_layer->options)
{
if (vector_layer->options->path)
g_signal_connect_object (vector_layer->options->path, "removed",
G_CALLBACK (gimp_vector_layer_removed_options_path),
vector_layer, G_CONNECT_SWAPPED);
g_signal_connect_object (vector_layer->options, "notify",
G_CALLBACK (gimp_vector_layer_changed_options),
vector_layer, G_CONNECT_SWAPPED);
}
break;
case PROP_MODIFIED:
vector_layer->modified = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_vector_layer_set_vector_options (GimpVectorLayer *layer,
GimpVectorLayerOptions *options)
{
if (layer->options)
{
g_signal_handlers_disconnect_by_func (layer->options,
G_CALLBACK (gimp_vector_layer_changed_options),
layer);
g_object_unref (layer->options);
}
layer->options = options;
gimp_vector_layer_changed_options (layer);
if (layer->options)
g_signal_connect_object (layer->options, "notify",
G_CALLBACK (gimp_vector_layer_changed_options),
layer, G_CONNECT_SWAPPED);
}
static void
gimp_vector_layer_set_buffer (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc,
GeglBuffer *buffer,
const GeglRectangle *bounds)
{
GimpVectorLayer *layer = GIMP_VECTOR_LAYER (drawable);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
if (push_undo && ! layer->modified)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE_MOD,
undo_desc);
GIMP_DRAWABLE_CLASS (parent_class)->set_buffer (drawable,
push_undo, undo_desc,
buffer, bounds);
if (push_undo && ! layer->modified)
{
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_image_undo_group_end (image);
}
}
static void
gimp_vector_layer_push_undo (GimpDrawable *drawable,
const gchar *undo_desc,
GeglBuffer *buffer,
gint x,
gint y,
gint width,
gint height)
{
GimpVectorLayer *layer = GIMP_VECTOR_LAYER (drawable);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
if (! layer->modified)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE, undo_desc);
GIMP_DRAWABLE_CLASS (parent_class)->push_undo (drawable, undo_desc,
buffer,
x, y, width, height);
if (! layer->modified)
{
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_image_undo_group_end (image);
}
}
static gint64
gimp_vector_layer_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (object);
gint64 memsize = 0;
memsize += gimp_object_get_memsize (GIMP_OBJECT (vector_layer->options),
gui_size);
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
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);
if (vector_layer->options)
{
GimpVectorLayerOptions *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;
}
static void
gimp_vector_layer_translate (GimpLayer *layer,
gint offset_x,
gint offset_y)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (layer);
gint x, y;
if (vector_layer->options && vector_layer->options->path)
gimp_item_translate (GIMP_ITEM (vector_layer->options->path),
offset_x, offset_y, FALSE);
/* Correct offset for vector layer after moving path */
gimp_item_get_offset (GIMP_ITEM (layer), &x, &y);
x += offset_x;
y += offset_y;
gimp_item_set_offset (GIMP_ITEM (layer), x, y);
}
static void
gimp_vector_layer_scale (GimpItem *item,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interp_type,
GimpProgress *progress)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
if (vector_layer->options && vector_layer->options->path)
{
gimp_item_scale (GIMP_ITEM (vector_layer->options->path),
new_width, new_height, new_offset_x, new_offset_y,
interp_type, progress);
}
}
static void
gimp_vector_layer_flip (GimpItem *item,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
if (vector_layer->options && vector_layer->options->path)
{
gimp_item_flip (GIMP_ITEM (vector_layer->options->path),
context, flip_type, axis, clip_result);
}
}
static void
gimp_vector_layer_rotate (GimpItem *item,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
if (vector_layer->options && vector_layer->options->path)
{
gimp_item_rotate (GIMP_ITEM (vector_layer->options->path),
context, rotate_type, center_x, center_y, clip_result);
}
}
static void
gimp_vector_layer_transform (GimpItem *item,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interp_type,
GimpTransformResize clip_result,
GimpProgress *progress)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
if (vector_layer->options && vector_layer->options->path)
{
gimp_item_transform (GIMP_ITEM (vector_layer->options->path),
context, matrix, direction, interp_type,
clip_result, progress);
}
}
static void
gimp_vector_layer_removed_options_path (GimpVectorLayer *layer)
{
if (layer->options)
{
gimp_image_undo_push_vector_layer (gimp_item_get_image (GIMP_ITEM (layer)),
_("Discard Vector Informations"),
layer, NULL);
g_object_set (layer->options, "path", NULL, NULL);
}
}
static void
gimp_vector_layer_removed (GimpItem *item)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
if (vector_layer->options && vector_layer->options->path)
g_signal_handlers_disconnect_by_func (vector_layer->options->path,
G_CALLBACK (gimp_vector_layer_removed_options_path),
vector_layer);
GIMP_ITEM_CLASS (parent_class)->removed (item);
}
/* public functions */
/**
* gimp_vector_layer_new:
* @image: the #GimpImage the layer should belong to
* @path: the #GimpPath object the layer should render
* @context: the #GimpContext from which to pull context properties
*
* Creates a new vector layer.
*
* Return value: a new #GimpVectorLayer or %NULL in case of a problem
**/
GimpVectorLayer *
gimp_vector_layer_new (GimpImage *image,
GimpPath *path,
GimpContext *context)
{
GimpVectorLayer *layer;
GimpVectorLayerOptions *options;
gint width = gimp_image_get_width (image);
gint height = gimp_image_get_height (image);
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_PATH (path), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
options = gimp_vector_layer_options_new (image, path, context);
layer =
GIMP_VECTOR_LAYER (gimp_drawable_new (GIMP_TYPE_VECTOR_LAYER,
image, NULL,
0, 0, width, height,
gimp_image_get_layer_format (image,
TRUE)));
gimp_object_set_name (GIMP_OBJECT (layer),
gimp_object_get_name (GIMP_OBJECT (path)));
gimp_layer_set_mode (GIMP_LAYER (layer),
gimp_image_get_default_new_layer_mode (image),
FALSE);
gimp_vector_layer_set_vector_options (layer, options);
return layer;
}
void
gimp_vector_layer_refresh (GimpVectorLayer *layer)
{
if (layer->options)
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;
if (layer->options->path)
gimp_image_undo_push_vector_layer (gimp_item_get_image (GIMP_ITEM (layer)),
_("Discard Vector Information"),
layer, NULL);
g_object_set (layer, "vector-layer-options", NULL, NULL);
}
gboolean
gimp_item_is_vector_layer (GimpItem *item)
{
return (GIMP_IS_VECTOR_LAYER (item) &&
GIMP_VECTOR_LAYER (item)->options);
}
/* private functions */
static gboolean
gimp_vector_layer_render (GimpVectorLayer *layer)
{
GimpDrawable *drawable = GIMP_DRAWABLE (layer);
GimpItem *item = GIMP_ITEM (layer);
GimpImage *image = gimp_item_get_image (item);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
g_object_freeze_notify (G_OBJECT (drawable));
/* make the layer background transparent */
gimp_drawable_fill (GIMP_DRAWABLE (layer),
gimp_get_user_context (image->gimp),
GIMP_FILL_TRANSPARENT);
/* render path to the layer */
gimp_vector_layer_render_path (layer, layer->options->path);
g_object_thaw_notify (G_OBJECT (drawable));
return TRUE;
}
static void
gimp_vector_layer_render_path (GimpVectorLayer *layer,
GimpPath *path)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
GimpChannel *selection = gimp_image_get_mask (image);
GList *drawables;
GimpCustomStyle style;
/* Don't mask these fill/stroke operations */
gimp_selection_suspend (GIMP_SELECTION (selection));
/* Convert from custom to standard styles */
style = gimp_fill_options_get_custom_style (layer->options->fill_options);
if (style == GIMP_CUSTOM_STYLE_SOLID_COLOR ||
! gimp_context_get_pattern (GIMP_CONTEXT (layer->options->fill_options)))
gimp_fill_options_set_style (layer->options->fill_options,
GIMP_FILL_STYLE_FG_COLOR);
else
gimp_fill_options_set_style (layer->options->fill_options,
GIMP_FILL_STYLE_PATTERN);
style =
gimp_fill_options_get_custom_style (GIMP_FILL_OPTIONS (layer->options->stroke_options));
if (style == GIMP_CUSTOM_STYLE_SOLID_COLOR ||
! gimp_context_get_pattern (GIMP_CONTEXT (layer->options->stroke_options)))
gimp_fill_options_set_style (GIMP_FILL_OPTIONS (layer->options->stroke_options),
GIMP_FILL_STYLE_FG_COLOR);
else
gimp_fill_options_set_style (GIMP_FILL_OPTIONS (layer->options->stroke_options),
GIMP_FILL_STYLE_PATTERN);
/* Fill the path object onto the layer */
gimp_drawable_fill_path (GIMP_DRAWABLE (layer),
layer->options->fill_options,
path, FALSE, NULL);
drawables = g_list_prepend (NULL, GIMP_DRAWABLE (layer));
/* stroke the path object onto the layer */
gimp_item_stroke (GIMP_ITEM (path),
drawables,
gimp_get_user_context (gimp_item_get_image (GIMP_ITEM (layer))->gimp),
layer->options->stroke_options,
FALSE, FALSE,
NULL, NULL);
g_list_free (drawables);
gimp_selection_resume (GIMP_SELECTION (selection));
}
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->path)
gimp_vector_layer_discard (layer);
else if (gimp_item_is_attached (item))
gimp_vector_layer_refresh (layer);
}

View file

@ -0,0 +1,66 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayer.h
*
* Copyright 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 3 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;
gboolean modified;
};
struct _GimpVectorLayerClass
{
GimpLayerClass parent_class;
};
GType gimp_vector_layer_get_type (void) G_GNUC_CONST;
GimpVectorLayer * gimp_vector_layer_new (GimpImage *image,
GimpPath *path,
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__ */

View file

@ -0,0 +1,95 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayeroptions-parasite.c
*
* Copyright 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 3 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/>.
*/
#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 (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, &parasite_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;
}

View file

@ -0,0 +1,33 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayeroptions-parasite.h
*
* Copyright 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 3 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_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 (GimpVectorLayerOptions *text);
GimpVectorLayerOptions * gimp_vector_layer_options_from_parasite (const GimpParasite *parasite,
GError **error,
Gimp *gimp);
#endif /* __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__ */

View file

@ -0,0 +1,339 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayers.c
*
* Copyright 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 3 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/>.
*/
#include "config.h"
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.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 "gimppath.h"
#include "gimpvectorlayer.h"
#include "gimpvectorlayeroptions.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_GIMP,
PROP_PATH,
PROP_PATH_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_path_changed (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,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_PATH,
"path", NULL, NULL,
GIMP_TYPE_PATH,
GIMP_PARAM_READWRITE |
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_UINT (object_class, PROP_PATH_TATTOO,
"path-tattoo", NULL, NULL,
0, G_MAXUINT32, 0,
G_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_FILL_OPTIONS,
"fill-options", NULL, NULL,
GIMP_TYPE_FILL_OPTIONS,
G_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_AGGREGATE);
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_STROKE_OPTIONS,
"stroke-options", NULL, NULL,
GIMP_TYPE_STROKE_OPTIONS,
G_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_AGGREGATE);
}
static void
gimp_vector_layer_options_init (GimpVectorLayerOptions *options)
{
options->path = NULL;
options->path_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->path)
{
g_object_unref (options->path);
options->path = 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_PATH:
g_value_set_object (value, options->path);
break;
case PROP_PATH_TATTOO:
g_value_set_uint (value, options->path_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_PATH:
if (options->path)
{
g_signal_handlers_disconnect_by_func (options->path,
G_CALLBACK (gimp_vector_layer_options_path_changed),
options);
g_object_unref (options->path);
}
options->path = g_value_dup_object (value);
if (options->path)
{
g_signal_connect_object (options->path, "invalidate-preview",
G_CALLBACK (gimp_vector_layer_options_path_changed),
options, G_CONNECT_SWAPPED);
g_signal_connect_object (options->path, "name-changed",
G_CALLBACK (gimp_vector_layer_options_path_changed),
options, G_CONNECT_SWAPPED);
/* update the tattoo */
options->path_tattoo = gimp_item_get_tattoo (GIMP_ITEM (options->path));
}
break;
case PROP_PATH_TATTOO:
options->path_tattoo = g_value_get_uint (value);
if (options->path &&
gimp_item_get_tattoo (GIMP_ITEM (options->path)) != options->path_tattoo)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (options->path));
g_object_set (options,
"path", gimp_image_get_path_by_tattoo
(image, options->path_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_path_changed (GimpVectorLayerOptions *options)
{
g_object_notify (G_OBJECT (options), "path");
}
/* public functions */
/**
* gimp_vector_layer_options_new:
* @image: the #GimpImage the layer belongs to
* @path: the #GimpPath 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,
GimpPath *path,
GimpContext *context)
{
GimpVectorLayerOptions *options;
GimpPattern *pattern;
GeglColor *stroke_color;
GeglColor *fill_color;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_PATH (path), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
options = g_object_new (GIMP_TYPE_VECTOR_LAYER_OPTIONS,
"gimp", image->gimp,
NULL);
stroke_color = gimp_context_get_foreground (context);
fill_color = gimp_context_get_background (context);
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,
"path", path,
NULL);
return options;
}

View file

@ -0,0 +1,64 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayeroptions.h
*
* Copyright 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 3 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_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 path_tattoo;
GimpPath *path;
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,
GimpPath *path,
GimpContext *context);
#endif /* __GIMP_VECTOR_LAYER_OPTIONS_H__ */

View file

@ -0,0 +1,288 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayerundo.h
*
* Copyright 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 3 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/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gio/gio.h>
#include <gegl.h>
#include "libgimpconfig/gimpconfig.h"
#include "vectors-types.h"
#include "core/gimp-memsize.h"
#include "core/gimpitem.h"
#include "core/gimpitemundo.h"
#include "core/gimp-utils.h"
#include "gimpvectorlayer.h"
#include "gimpvectorlayeroptions.h"
#include "gimpvectorlayerundo.h"
enum
{
PROP_0,
PROP_PARAM
};
static void gimp_vector_layer_undo_constructed (GObject *object);
static void gimp_vector_layer_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_vector_layer_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_vector_layer_undo_get_memsize (GimpObject *object,
gint64 *gui_size);
static void gimp_vector_layer_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void gimp_vector_layer_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode);
G_DEFINE_TYPE (GimpVectorLayerUndo, gimp_vector_layer_undo, GIMP_TYPE_ITEM_UNDO)
#define parent_class gimp_vector_layer_undo_parent_class
static void
gimp_vector_layer_undo_class_init (GimpVectorLayerUndoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructed = gimp_vector_layer_undo_constructed;
object_class->set_property = gimp_vector_layer_undo_set_property;
object_class->get_property = gimp_vector_layer_undo_get_property;
gimp_object_class->get_memsize = gimp_vector_layer_undo_get_memsize;
undo_class->pop = gimp_vector_layer_undo_pop;
undo_class->free = gimp_vector_layer_undo_free;
g_object_class_install_property (object_class, PROP_PARAM,
g_param_spec_param ("param", NULL, NULL,
G_TYPE_PARAM,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_vector_layer_undo_init (GimpVectorLayerUndo *undo)
{
}
static void
gimp_vector_layer_undo_constructed (GObject *object)
{
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (object);
GimpVectorLayer *vector_layer;
G_OBJECT_CLASS (parent_class)->constructed (object);
g_assert (GIMP_IS_VECTOR_LAYER (GIMP_ITEM_UNDO (vector_undo)->item));
vector_layer = GIMP_VECTOR_LAYER (GIMP_ITEM_UNDO (vector_undo)->item);
switch (GIMP_UNDO (object)->undo_type)
{
case GIMP_UNDO_VECTOR_LAYER:
if (vector_undo->pspec)
{
g_assert (vector_undo->pspec->owner_type == GIMP_TYPE_VECTOR_LAYER_OPTIONS);
vector_undo->value = g_slice_new0 (GValue);
g_value_init (vector_undo->value, vector_undo->pspec->value_type);
g_object_get_property (G_OBJECT (vector_layer->options),
vector_undo->pspec->name, vector_undo->value);
}
else if (vector_layer->options)
{
vector_undo->vector_layer_options = gimp_config_duplicate (GIMP_CONFIG (vector_layer->options));
}
break;
case GIMP_UNDO_VECTOR_LAYER_MODIFIED:
vector_undo->modified = vector_layer->modified;
break;
default:
g_assert_not_reached ();
}
}
static void
gimp_vector_layer_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (object);
switch (property_id)
{
case PROP_PARAM:
vector_undo->pspec = g_value_get_param (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_vector_layer_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (object);
switch (property_id)
{
case PROP_PARAM:
g_value_set_param (value, (GParamSpec *) vector_undo->pspec);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gint64
gimp_vector_layer_undo_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpVectorLayerUndo *undo = GIMP_VECTOR_LAYER_UNDO (object);
gint64 memsize = 0;
memsize += gimp_g_value_get_memsize (undo->value);
memsize += gimp_object_get_memsize (GIMP_OBJECT (undo->vector_layer_options), NULL);
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
static void
gimp_vector_layer_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (undo);
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (GIMP_ITEM_UNDO (undo)->item);
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
switch (undo->undo_type)
{
case GIMP_UNDO_VECTOR_LAYER:
if (vector_undo->pspec)
{
GValue *value;
g_return_if_fail (vector_layer->options != NULL);
value = g_slice_new0 (GValue);
g_value_init (value, vector_undo->pspec->value_type);
g_object_get_property (G_OBJECT (vector_layer->options),
vector_undo->pspec->name, value);
g_object_set_property (G_OBJECT (vector_layer->options),
vector_undo->pspec->name, vector_undo->value);
g_value_unset (vector_undo->value);
g_slice_free (GValue, vector_undo->value);
vector_undo->value = value;
}
else
{
GimpVectorLayerOptions *vector_layer_options;
vector_layer_options = (vector_layer->options ?
gimp_config_duplicate (GIMP_CONFIG (vector_layer->options)) : NULL);
if (vector_layer->options && vector_undo->vector_layer_options)
gimp_config_sync (G_OBJECT (vector_undo->vector_layer_options),
G_OBJECT (vector_layer->options), 0);
else
g_object_set (vector_layer,
"vector-layer-options", vector_undo->vector_layer_options,
NULL);
if (vector_undo->vector_layer_options)
g_object_unref (vector_undo->vector_layer_options);
vector_undo->vector_layer_options = vector_layer_options;
}
break;
case GIMP_UNDO_VECTOR_LAYER_MODIFIED:
{
gboolean modified;
modified = vector_layer->modified;
g_object_set (vector_layer, "modified", vector_undo->modified, NULL);
vector_undo->modified = modified;
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (vector_layer));
}
break;
default:
g_assert_not_reached ();
}
}
static void
gimp_vector_layer_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode)
{
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (undo);
if (vector_undo->vector_layer_options)
{
g_object_unref (vector_undo->vector_layer_options);
vector_undo->vector_layer_options = NULL;
}
if (vector_undo->pspec)
{
g_value_unset (vector_undo->value);
g_slice_free (GValue, vector_undo->value);
vector_undo->value = NULL;
vector_undo->pspec = NULL;
}
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
}

View file

@ -0,0 +1,58 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpvectorlayerundo.h
*
* Copyright 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 3 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_UNDO_H__
#define __GIMP_VECTOR_LAYER_UNDO_H__
#include "core/gimpitemundo.h"
#define GIMP_TYPE_VECTOR_LAYER_UNDO (gimp_vector_layer_undo_get_type ())
#define GIMP_VECTOR_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTOR_LAYER_UNDO, GimpVectorLayerUndo))
#define GIMP_VECTOR_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTOR_LAYER_UNDO, GimpVectorLayerUndoClass))
#define GIMP_IS_VECTOR_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_VECTOR_LAYER_UNDO))
#define GIMP_IS_VECTOR_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_VECTOR_LAYER_UNDO))
#define GIMP_VECTOR_LAYER_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_VECTOR_LAYER_UNDO, GimpVectorLayerUndoClass))
typedef struct _GimpVectorLayerUndoClass GimpVectorLayerUndoClass;
struct _GimpVectorLayerUndo
{
GimpItemUndo parent_instance;
GimpVectorLayerOptions *vector_layer_options;
const GParamSpec *pspec;
GValue *value;
gboolean modified;
};
struct _GimpVectorLayerUndoClass
{
GimpItemClass parent_class;
};
GType gimp_vector_layer_undo_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_VECTOR_LAYER_UNDO_H__ */

View file

@ -12,6 +12,11 @@ libappvectors_sources = [
'gimppathundo.c', 'gimppathundo.c',
'gimpstroke-new.c', 'gimpstroke-new.c',
'gimpstroke.c', 'gimpstroke.c',
'gimpvectorlayer.c',
'gimpvectorlayer-xcf.c',
'gimpvectorlayeroptions.c',
'gimpvectorlayeroptions-parasite.c',
'gimpvectorlayerundo.c',
] ]
libappvectors = static_library('appvectors', libappvectors = static_library('appvectors',

View file

@ -33,5 +33,9 @@ typedef struct _GimpPath GimpPath;
typedef struct _GimpStroke GimpStroke; typedef struct _GimpStroke GimpStroke;
typedef struct _GimpBezierStroke GimpBezierStroke; typedef struct _GimpBezierStroke GimpBezierStroke;
typedef struct _GimpVectorLayer GimpVectorLayer;
typedef struct _GimpVectorLayerOptions GimpVectorLayerOptions;
typedef struct _GimpVectorLayerUndo GimpVectorLayerUndo;
#endif /* __VECTORS_TYPES_H__ */ #endif /* __VECTORS_TYPES_H__ */

View file

@ -76,6 +76,8 @@
#include "vectors/gimpbezierstroke.h" #include "vectors/gimpbezierstroke.h"
#include "vectors/gimppath.h" #include "vectors/gimppath.h"
#include "vectors/gimppath-compat.h" #include "vectors/gimppath-compat.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayer-xcf.h"
#include "xcf-private.h" #include "xcf-private.h"
#include "xcf-load.h" #include "xcf-load.h"
@ -3149,7 +3151,7 @@ xcf_load_layer (XcfInfo *info,
xcf_progress_update (info); xcf_progress_update (info);
/* call the evil text layer hack that might change our layer pointer */ /* call the evil text and vector layer hack that might change our layer pointer */
selected = g_list_find (info->selected_layers, layer); selected = g_list_find (info->selected_layers, layer);
linked = g_list_find (info->linked_layers, layer); linked = g_list_find (info->linked_layers, layer);
floating = (info->floating_sel == layer); floating = (info->floating_sel == layer);
@ -3172,6 +3174,16 @@ xcf_load_layer (XcfInfo *info,
if (floating) if (floating)
info->floating_sel = layer; 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 /* if this is not the floating selection, we can fix the layer's
* space already now, the function will do nothing if we already * space already now, the function will do nothing if we already

View file

@ -70,6 +70,8 @@
#include "vectors/gimppath.h" #include "vectors/gimppath.h"
#include "vectors/gimpstroke.h" #include "vectors/gimpstroke.h"
#include "vectors/gimppath-compat.h" #include "vectors/gimppath-compat.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayer-xcf.h"
#include "xcf-private.h" #include "xcf-private.h"
#include "xcf-read.h" #include "xcf-read.h"
@ -720,6 +722,12 @@ xcf_save_layer_props (XcfInfo *info,
image, PROP_TEXT_LAYER_FLAGS, error, image, PROP_TEXT_LAYER_FLAGS, error,
flags), ;); 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))) if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{ {

View file

@ -433,6 +433,10 @@
<item><attribute name="action">app.layers-text-to-vectors</attribute></item> <item><attribute name="action">app.layers-text-to-vectors</attribute></item>
<item><attribute name="action">app.layers-text-along-vectors</attribute></item> <item><attribute name="action">app.layers-text-along-vectors</attribute></item>
</section> </section>
<section>
<item><attribute name="action">app.layers-vector-fill-stroke</attribute></item>
<item><attribute name="action">app.layers-vector-discard</attribute></item>
</section>
<section> <section>
<submenu> <submenu>
<attribute name="label" translatable="yes" context="layers-action">Stac_k</attribute> <attribute name="label" translatable="yes" context="layers-action">Stac_k</attribute>

View file

@ -7,6 +7,7 @@
<attribute name="icon">gimp-layers</attribute> <attribute name="icon">gimp-layers</attribute>
<item><attribute name="action">app.layers-edit-text</attribute></item> <item><attribute name="action">app.layers-edit-text</attribute></item>
<item><attribute name="action">app.layers-edit-vector</attribute></item>
<item><attribute name="action">app.layers-edit-attributes</attribute></item> <item><attribute name="action">app.layers-edit-attributes</attribute></item>
<submenu> <submenu>
<attribute name="label" translatable="yes" context="layers-action">Blend Space</attribute> <attribute name="label" translatable="yes" context="layers-action">Blend Space</attribute>
@ -63,6 +64,10 @@
<item><attribute name="action">app.layers-text-to-vectors</attribute></item> <item><attribute name="action">app.layers-text-to-vectors</attribute></item>
<item><attribute name="action">app.layers-text-along-vectors</attribute></item> <item><attribute name="action">app.layers-text-along-vectors</attribute></item>
</section> </section>
<section>
<item><attribute name="action">app.layers-vector-fill-stroke</attribute></item>
<item><attribute name="action">app.layers-vector-discard</attribute></item>
</section>
<section> <section>
<item><attribute name="action">app.layers-resize</attribute></item> <item><attribute name="action">app.layers-resize</attribute></item>
<item><attribute name="action">app.layers-resize-to-image</attribute></item> <item><attribute name="action">app.layers-resize-to-image</attribute></item>

View file

@ -29,6 +29,7 @@
<item><attribute name="action">app.paths-merge-visible</attribute></item> <item><attribute name="action">app.paths-merge-visible</attribute></item>
</section> </section>
<section> <section>
<item><attribute name="action">app.paths-to-vector-layer</attribute></item>
<item><attribute name="action">app.paths-selection-replace</attribute></item> <item><attribute name="action">app.paths-selection-replace</attribute></item>
<item><attribute name="action">app.paths-selection-add</attribute></item> <item><attribute name="action">app.paths-selection-add</attribute></item>
<item><attribute name="action">app.paths-selection-subtract</attribute></item> <item><attribute name="action">app.paths-selection-subtract</attribute></item>