app: add saving/loading of link layers.
This commit is contained in:
parent
20083bcabe
commit
6e91826865
6 changed files with 168 additions and 2 deletions
|
|
@ -71,6 +71,7 @@
|
|||
#include "gimplayer-floating-selection.h"
|
||||
#include "gimplayermask.h"
|
||||
#include "gimplayerstack.h"
|
||||
#include "gimplinklayer.h"
|
||||
#include "gimpmarshal.h"
|
||||
#include "gimppalette.h"
|
||||
#include "gimpparasitelist.h"
|
||||
|
|
@ -3024,6 +3025,14 @@ gimp_image_get_xcf_version (GimpImage *image,
|
|||
"GIMP 3.2"));
|
||||
version = MAX (24, version);
|
||||
}
|
||||
|
||||
/* Need version 25 for link layers. */
|
||||
if (GIMP_IS_LINK_LAYER (layer))
|
||||
{
|
||||
ADD_REASON (g_strdup_printf (_("Link layers were added in %s"),
|
||||
"GIMP 3.2"));
|
||||
version = MAX (25, version);
|
||||
}
|
||||
}
|
||||
g_list_free (items);
|
||||
|
||||
|
|
@ -3204,6 +3213,7 @@ gimp_image_get_xcf_version (GimpImage *image,
|
|||
if (version_string) *version_string = "GIMP 3.0";
|
||||
break;
|
||||
case 24:
|
||||
case 25:
|
||||
if (gimp_version) *gimp_version = 320;
|
||||
if (version_string) *version_string = "GIMP 3.2";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,13 @@
|
|||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
LINK_LAYER_XCF_NONE = 0,
|
||||
LINK_LAYER_XCF_DONT_AUTO_RENAME = 1 << 0,
|
||||
LINK_LAYER_XCF_MODIFIED = 1 << 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
|
@ -112,6 +119,8 @@ static gboolean gimp_link_layer_render (GimpLinkLayer *layer);
|
|||
static void gimp_link_layer_render_buffer (GimpLinkLayer *layer,
|
||||
GeglBuffer *buffer);
|
||||
|
||||
static void gimp_link_layer_set_xcf_flags (GimpLinkLayer *layer,
|
||||
guint32 flags);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpLinkLayer, gimp_link_layer, GIMP_TYPE_LAYER)
|
||||
|
||||
|
|
@ -523,6 +532,80 @@ gimp_item_is_link_layer (GimpItem *item)
|
|||
! GIMP_LINK_LAYER (item)->p->modified);
|
||||
}
|
||||
|
||||
guint32
|
||||
gimp_link_layer_get_xcf_flags (GimpLinkLayer *link_layer)
|
||||
{
|
||||
guint flags = 0;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_LINK_LAYER (link_layer), 0);
|
||||
|
||||
if (! link_layer->p->auto_rename)
|
||||
flags |= LINK_LAYER_XCF_DONT_AUTO_RENAME;
|
||||
|
||||
if (link_layer->p->modified)
|
||||
flags |= LINK_LAYER_XCF_MODIFIED;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_link_layer_from_layer:
|
||||
* @layer: a #GimpLayer object
|
||||
* @link: a #GimpLink object
|
||||
* @flags: flags as retrieved from the XCF file.
|
||||
*
|
||||
* Converts a standard #GimpLayer into a #GimpLinkLayer.
|
||||
* The new link layer takes ownership of the @link.
|
||||
* The old @layer object is freed and replaced in-place by the new
|
||||
* #GimpLinkLayer.
|
||||
*
|
||||
* This is a hack similar to the one used to load text layers from XCF,
|
||||
* since at first they are loaded as normal layers, and only later
|
||||
* promoted to link layers when the corresponding property is read from
|
||||
* the file.
|
||||
**/
|
||||
void
|
||||
gimp_link_layer_from_layer (GimpLayer **layer,
|
||||
GimpLink *link,
|
||||
guint32 flags)
|
||||
{
|
||||
GimpLinkLayer *link_layer;
|
||||
GimpDrawable *drawable;
|
||||
|
||||
g_return_if_fail (GIMP_IS_LAYER (*layer));
|
||||
g_return_if_fail (GIMP_IS_LINK (link));
|
||||
|
||||
link_layer = g_object_new (GIMP_TYPE_LINK_LAYER,
|
||||
"image", gimp_item_get_image (GIMP_ITEM (*layer)),
|
||||
NULL);
|
||||
|
||||
gimp_item_replace_item (GIMP_ITEM (link_layer), GIMP_ITEM (*layer));
|
||||
|
||||
drawable = GIMP_DRAWABLE (link_layer);
|
||||
gimp_drawable_steal_buffer (drawable, GIMP_DRAWABLE (*layer));
|
||||
|
||||
gimp_layer_set_opacity (GIMP_LAYER (link_layer),
|
||||
gimp_layer_get_opacity (*layer), FALSE);
|
||||
gimp_layer_set_mode (GIMP_LAYER (link_layer),
|
||||
gimp_layer_get_mode (*layer), FALSE);
|
||||
gimp_layer_set_blend_space (GIMP_LAYER (link_layer),
|
||||
gimp_layer_get_blend_space (*layer), FALSE);
|
||||
gimp_layer_set_composite_space (GIMP_LAYER (link_layer),
|
||||
gimp_layer_get_composite_space (*layer), FALSE);
|
||||
gimp_layer_set_composite_mode (GIMP_LAYER (link_layer),
|
||||
gimp_layer_get_composite_mode (*layer), FALSE);
|
||||
gimp_layer_set_lock_alpha (GIMP_LAYER (link_layer),
|
||||
gimp_layer_get_lock_alpha (*layer), FALSE);
|
||||
|
||||
gimp_link_layer_set_link (link_layer, link, FALSE);
|
||||
gimp_link_layer_set_xcf_flags (link_layer, flags);
|
||||
|
||||
g_object_unref (link);
|
||||
g_object_unref (*layer);
|
||||
|
||||
*layer = GIMP_LAYER (link_layer);
|
||||
}
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
|
|
@ -649,3 +732,15 @@ gimp_link_layer_render_buffer (GimpLinkLayer *layer,
|
|||
gimp_gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE,
|
||||
gimp_drawable_get_buffer (drawable), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_link_layer_set_xcf_flags (GimpLinkLayer *layer,
|
||||
guint32 flags)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_LINK_LAYER (layer));
|
||||
|
||||
g_object_set (layer,
|
||||
"auto-rename", (flags & LINK_LAYER_XCF_DONT_AUTO_RENAME) == 0,
|
||||
"modified", (flags & LINK_LAYER_XCF_MODIFIED) != 0,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,4 +63,12 @@ void gimp_link_layer_discard (GimpLinkLayer *layer);
|
|||
void gimp_link_layer_monitor (GimpLinkLayer *layer);
|
||||
gboolean gimp_item_is_link_layer (GimpItem *item);
|
||||
|
||||
|
||||
/* Only to be used for XCF loading/saving. */
|
||||
|
||||
guint32 gimp_link_layer_get_xcf_flags (GimpLinkLayer *layer);
|
||||
void gimp_link_layer_from_layer (GimpLayer **layer,
|
||||
GimpLink *link,
|
||||
guint32 flags);
|
||||
|
||||
#endif /* __GIMP_LINK_LAYER_H__ */
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@
|
|||
#include "core/gimplayer-new.h"
|
||||
#include "core/gimplayer-xcf.h"
|
||||
#include "core/gimplayermask.h"
|
||||
#include "core/gimplink.h"
|
||||
#include "core/gimplinklayer.h"
|
||||
#include "core/gimpparasitelist.h"
|
||||
#include "core/gimppattern.h"
|
||||
#include "core/gimpprogress.h"
|
||||
|
|
@ -163,7 +165,8 @@ static gboolean xcf_load_layer_props (XcfInfo *info,
|
|||
static gboolean xcf_check_layer_props (XcfInfo *info,
|
||||
GList **item_path,
|
||||
gboolean *is_group_layer,
|
||||
gboolean *is_text_layer);
|
||||
gboolean *is_text_layer,
|
||||
gboolean *is_link_layer);
|
||||
static gboolean xcf_load_channel_props (XcfInfo *info,
|
||||
GimpImage *image,
|
||||
GimpChannel **channel,
|
||||
|
|
@ -2172,6 +2175,29 @@ xcf_load_layer_props (XcfInfo *info,
|
|||
"gimp-vector-layer-data", data,
|
||||
(GDestroyNotify) xcf_load_free_vector_data);
|
||||
}
|
||||
|
||||
case PROP_LINK_LAYER_DATA:
|
||||
{
|
||||
GimpLink *link;
|
||||
gchar *path;
|
||||
guint32 flags;
|
||||
gboolean is_selected_layer;
|
||||
|
||||
xcf_read_int32 (info, &flags, 1);
|
||||
xcf_read_string (info, &path, 1);
|
||||
|
||||
link = gimp_link_new (info->gimp, g_file_new_for_path (path));
|
||||
g_free (path);
|
||||
|
||||
is_selected_layer = (g_list_find (info->selected_layers, *layer ) != NULL);
|
||||
if (is_selected_layer)
|
||||
info->selected_layers = g_list_remove (info->selected_layers, *layer);
|
||||
|
||||
gimp_link_layer_from_layer (layer, link, flags);
|
||||
|
||||
if (is_selected_layer)
|
||||
info->selected_layers = g_list_prepend (info->selected_layers, *layer);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_GROUP_ITEM:
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ typedef enum
|
|||
PROP_FILTER_REGION = 44,
|
||||
PROP_FILTER_ARGUMENT = 45,
|
||||
PROP_FILTER_CLIP = 46,
|
||||
PROP_VECTOR_LAYER = 47
|
||||
PROP_VECTOR_LAYER = 47,
|
||||
PROP_LINK_LAYER_DATA = 48,
|
||||
} PropType;
|
||||
|
||||
typedef enum
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@
|
|||
#include "core/gimpitemlist.h"
|
||||
#include "core/gimplayer.h"
|
||||
#include "core/gimplayermask.h"
|
||||
#include "core/gimplink.h"
|
||||
#include "core/gimplinklayer.h"
|
||||
#include "core/gimplist.h"
|
||||
#include "core/gimpparasitelist.h"
|
||||
#include "core/gimpprogress.h"
|
||||
|
|
@ -740,6 +742,9 @@ xcf_save_layer_props (XcfInfo *info,
|
|||
xcf_check_error (xcf_save_prop (info, image, PROP_VECTOR_LAYER, error, layer), ;);
|
||||
}
|
||||
|
||||
if (GIMP_IS_LINK_LAYER (layer))
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_LINK_LAYER_DATA, error, layer));
|
||||
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
|
||||
{
|
||||
gint32 flags = 0;
|
||||
|
|
@ -1722,6 +1727,27 @@ xcf_save_prop (XcfInfo *info,
|
|||
xcf_write_int32_check_error (info, &size, 1, va_end (args));
|
||||
xcf_check_error (xcf_seek_pos (info, base + size, error), va_end (args));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_LINK_LAYER_DATA:
|
||||
{
|
||||
GimpLinkLayer *layer = va_arg (args, GimpLinkLayer *);
|
||||
GFile *file;
|
||||
const gchar *path;
|
||||
guint32 flags;
|
||||
|
||||
flags = gimp_link_layer_get_xcf_flags (layer);
|
||||
file = gimp_link_get_file (gimp_link_layer_get_link (layer));
|
||||
path = g_file_peek_path (file);
|
||||
|
||||
size = 4 + strlen (path) ? strlen (path) + 5 : 4;
|
||||
|
||||
xcf_write_prop_type_check_error (info, prop_type);
|
||||
xcf_write_int32_check_error (info, &size, 1);
|
||||
|
||||
xcf_write_int32_check_error (info, &flags, 1);
|
||||
xcf_write_string_check_error (info, (gchar **) &path, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ITEM_PATH:
|
||||
|
|
|
|||
Loading…
Reference in a new issue