vectors: Implement vector layers from GSoC 2006

Ports the work done by Hendrik Boom, Martin Nordholts, Gilles Rochefort,
and Jacob Boerema to Gimp 2.99/3.0.
This commit is contained in:
Henk Boom 2025-03-24 22:39:49 -04:00 committed by Alx Sa
parent 03443ffcc1
commit 60ed90e10a
15 changed files with 495 additions and 6 deletions

View file

@ -33,6 +33,8 @@
#include "text/gimptextlayer.h"
#include "vectors/gimpvectorlayer.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimpwidgets-utils.h"
@ -60,6 +62,12 @@ static const GimpActionEntry layers_actions[] =
layers_edit_text_cmd_callback,
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,
NC_("layers-action", "_Edit Layer Attributes..."), NULL, { NULL },
NC_("layers-action", "Edit the layer's name"),
@ -191,6 +199,18 @@ static const GimpActionEntry layers_actions[] =
layers_text_along_path_cmd_callback,
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,
NC_("layers-action", "Layer B_oundary Size..."), NULL, { NULL },
NC_("layers-action", "Adjust the layer dimensions"),
@ -757,6 +777,7 @@ layers_actions_update (GimpActionGroup *group,
gboolean lock_alpha = TRUE;
gboolean can_lock_alpha = FALSE;
gboolean text_layer = FALSE;
gboolean vector_layer = FALSE;
gboolean bs_mutable = FALSE; /* At least 1 selected layers' blend space is mutable. */
gboolean cs_mutable = FALSE; /* At least 1 selected layers' composite space is mutable. */
gboolean cm_mutable = FALSE; /* At least 1 selected layers' composite mode is mutable. */
@ -977,7 +998,8 @@ layers_actions_update (GimpActionGroup *group,
gimp_action_group_set_action_active (group, action, TRUE);
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
vector_layer = gimp_drawable_is_vector_layer (GIMP_DRAWABLE (layer));
}
}
@ -993,6 +1015,7 @@ layers_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer));
SET_VISIBLE ("layers-edit-text", text_layer && !ac);
SET_SENSITIVE ("layers-edit-text", text_layer && !ac);
SET_VISIBLE ("layers-edit-vector", vector_layer && !ac);
SET_SENSITIVE ("layers-edit-attributes", layer && !fs && !ac);
if (layer && gimp_layer_is_floating_sel (layer))
@ -1042,6 +1065,9 @@ layers_actions_update (GimpActionGroup *group,
SET_VISIBLE ("layers-text-to-path", n_text_layers > 0 && !ac);
SET_VISIBLE ("layers-text-along-path", text_layer && !ac);
SET_VISIBLE ("layers-vector-fill-stroke", vector_layer && !ac);
SET_VISIBLE ("layers-vector-discard", vector_layer && !ac);
SET_SENSITIVE ("layers-resize", n_selected_layers == 1 && all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-resize-to-image", all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-scale", n_selected_layers == 1 && all_writable && all_movable && !ac);

View file

@ -58,6 +58,8 @@
#include "path/gimppath.h"
#include "path/gimppath-warp.h"
#include "path/gimpstroke.h"
#include "path/gimpvectorlayer.h"
#include "path/gimpvectorlayeroptions.h"
#include "text/gimptext.h"
#include "text/gimptext-path.h"
@ -73,6 +75,7 @@
#include "display/gimpimagewindow.h"
#include "tools/gimptexttool.h"
#include "tools/gimpvectortool.h"
#include "tools/tool_manager.h"
#include "dialogs/dialogs.h"
@ -80,6 +83,7 @@
#include "dialogs/layer-options-dialog.h"
#include "dialogs/resize-dialog.h"
#include "dialogs/scale-dialog.h"
#include "dialogs/vector-layer-options-dialog.h"
#include "actions.h"
#include "items-commands.h"
@ -251,6 +255,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_drawable_is_vector_layer (GIMP_DRAWABLE (layer)))
{
layers_edit_attributes_cmd_callback (action, value, data);
return;
}
active_tool = tool_manager_get_active (image->gimp);
if (! GIMP_IS_VECTOR_TOOL (active_tool))
{
GimpToolInfo *tool_info;
tool_info = (GimpToolInfo *)
gimp_container_get_child_by_name (image->gimp->tool_info_list,
"gimp-vector-tool");
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
layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
@ -2591,6 +2641,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
layers_resize_callback (GtkWidget *dialog,
GimpViewable *viewable,

View file

@ -24,6 +24,9 @@ void layers_edit_cmd_callback (GimpAction *action,
void layers_edit_text_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_edit_vector_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
@ -83,6 +86,12 @@ void layers_text_to_path_cmd_callback (GimpAction *action,
void layers_text_along_path_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_vector_fill_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_vector_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_resize_cmd_callback (GimpAction *action,
GVariant *value,

View file

@ -149,7 +149,12 @@ static const GimpActionEntry paths_actions[] =
{ "paths-import", GIMP_ICON_DOCUMENT_OPEN,
NC_("paths-action", "I_mport Path..."), NULL, { NULL }, NULL,
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[] =
@ -429,6 +434,8 @@ paths_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("paths-export", n_selected_paths > 0);
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-advanced", image && !mask_empty);
SET_SENSITIVE ("paths-fill", n_selected_paths > 0 &&

View file

@ -47,6 +47,7 @@
#include "path/gimppath.h"
#include "path/gimppath-export.h"
#include "path/gimppath-import.h"
#include "path/gimpvectorlayer.h"
#include "widgets/gimpaction.h"
#include "widgets/gimpclipboard.h"
@ -509,6 +510,28 @@ paths_merge_visible_cmd_callback (GimpAction *action,
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
paths_to_selection_cmd_callback (GimpAction *action,
GVariant *value,

View file

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

View file

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

View file

@ -0,0 +1,248 @@
/* 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/gimppropwidgets.h"
#include "widgets/gimpviewabledialog.h"
#include "widgets/gimpstrokeeditor.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayeroptions.h"
#include "vector-layer-options-dialog.h"
#include "gimp-intl.h"
#define RESPONSE_RESET 1
/* local functions */
static void vector_layer_options_dialog_notify (GObject *options,
const GParamSpec *pspec,
GtkWidget *dialog);
static void vector_layer_options_dialog_response (GtkWidget *widget,
gint response_id,
GtkWidget *dialog);
/* public function */
GtkWidget *
vector_layer_options_dialog_new (GimpVectorLayer *layer,
GimpContext *context,
const gchar *title,
const gchar *icon_name,
const gchar *help_id,
GtkWidget *parent)
{
GimpVectorLayerOptions *saved_options;
GimpFillOptions *fill_options;
GimpStrokeOptions *stroke_options;
GtkWidget *dialog;
GtkWidget *main_vbox;
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (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);
/* 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;
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 (response_id != RESPONSE_RESET)
gtk_widget_destroy (dialog);
break;
}
}

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_path_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_set_sensitive (button, FALSE);
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);
@ -202,7 +202,7 @@ gimp_path_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_set_sensitive (button, FALSE);
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;
@ -210,9 +210,17 @@ gimp_path_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_set_sensitive (button, FALSE);
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;
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;
}

View file

@ -73,6 +73,8 @@
#include "path/gimpbezierstroke.h"
#include "path/gimppath.h"
#include "path/gimppath-compat.h"
#include "path/gimpvectorlayer.h"
#include "path/gimpvectorlayer-xcf.h"
#include "text/gimptextlayer.h"
#include "text/gimptextlayer-xcf.h"
@ -3149,7 +3151,7 @@ xcf_load_layer (XcfInfo *info,
xcf_progress_update (info);
/* call the evil text layer hack that might change our layer pointer */
/* call the evil text and vector layer hack that might change our layer pointer */
selected = g_list_find (info->selected_layers, layer);
linked = g_list_find (info->linked_layers, layer);
floating = (info->floating_sel == layer);
@ -3172,6 +3174,16 @@ xcf_load_layer (XcfInfo *info,
if (floating)
info->floating_sel = layer;
}
else if (gimp_vector_layer_xcf_load_hack (&layer))
{
if (selected)
{
info->selected_layers = g_list_delete_link (info->selected_layers, selected);
info->selected_layers = g_list_prepend (info->selected_layers, layer);
}
if (floating)
info->floating_sel = layer;
}
/* if this is not the floating selection, we can fix the layer's
* space already now, the function will do nothing if we already

View file

@ -67,6 +67,8 @@
#include "path/gimppath.h"
#include "path/gimpstroke.h"
#include "path/gimppath-compat.h"
#include "path/gimpvectorlayer.h"
#include "path/gimpvectorlayer-xcf.h"
#include "text/gimptextlayer.h"
#include "text/gimptextlayer-xcf.h"
@ -720,6 +722,12 @@ xcf_save_layer_props (XcfInfo *info,
image, PROP_TEXT_LAYER_FLAGS, error,
flags), ;);
}
else if (GIMP_IS_VECTOR_LAYER (layer) && GIMP_VECTOR_LAYER (layer)->options)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (layer);
gimp_vector_layer_xcf_save_prepare (vector_layer);
}
if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{

View file

@ -433,6 +433,10 @@
<item><attribute name="action">app.layers-text-to-path</attribute></item>
<item><attribute name="action">app.layers-text-along-path</attribute></item>
</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>
<submenu>
<attribute name="label" translatable="yes" context="layers-action">Stac_k</attribute>

View file

@ -7,6 +7,7 @@
<attribute name="icon">gimp-layers</attribute>
<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>
<submenu>
<attribute name="label" translatable="yes" context="layers-action">Blend Space</attribute>
@ -63,6 +64,10 @@
<item><attribute name="action">app.layers-text-to-path</attribute></item>
<item><attribute name="action">app.layers-text-along-path</attribute></item>
</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>
<item><attribute name="action">app.layers-resize</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>
</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-add</attribute></item>
<item><attribute name="action">app.paths-selection-subtract</attribute></item>