app: implement brush saving in the core

and enable duplicating the clipboard brush, like for patterns.

(cherry picked from commit 1e6b26e83a)
This commit is contained in:
Michael Natterer
2019-02-12 18:51:47 +01:00
parent 3dc01393eb
commit cf76b7f73c
7 changed files with 170 additions and 11 deletions

View File

@ -111,6 +111,8 @@ libappcore_a_sources = \
gimpbrush-load.c \ gimpbrush-load.c \
gimpbrush-load.h \ gimpbrush-load.h \
gimpbrush-private.h \ gimpbrush-private.h \
gimpbrush-save.c \
gimpbrush-save.h \
gimpbrush-transform.cc \ gimpbrush-transform.cc \
gimpbrush-transform.h \ gimpbrush-transform.h \
gimpbrushcache.c \ gimpbrushcache.c \

View File

@ -77,7 +77,7 @@ gimp_data_factories_init (Gimp *gimp)
"GIMP Brush", "GIMP Brush",
gimp_brush_load, gimp_brush_load,
GIMP_BRUSH_FILE_EXTENSION, GIMP_BRUSH_FILE_EXTENSION,
FALSE); TRUE);
gimp_data_loader_factory_add_loader (gimp->brush_factory, gimp_data_loader_factory_add_loader (gimp->brush_factory,
"GIMP Brush Pixmap", "GIMP Brush Pixmap",
gimp_brush_load, gimp_brush_load,

103
app/core/gimpbrush-save.c Normal file
View File

@ -0,0 +1,103 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 "core-types.h"
#include "gimpbrush.h"
#include "gimpbrush-header.h"
#include "gimpbrush-save.h"
#include "gimptempbuf.h"
gboolean
gimp_brush_save (GimpData *data,
GOutputStream *output,
GError **error)
{
GimpBrush *brush = GIMP_BRUSH (data);
GimpTempBuf *mask = gimp_brush_get_mask (brush);
GimpTempBuf *pixmap = gimp_brush_get_pixmap (brush);
GimpBrushHeader header;
const gchar *name;
gint width;
gint height;
name = gimp_object_get_name (brush);
width = gimp_temp_buf_get_width (mask);
height = gimp_temp_buf_get_height (mask);
header.header_size = g_htonl (sizeof (GimpBrushHeader) +
strlen (name) + 1);
header.version = g_htonl (2);
header.width = g_htonl (width);
header.height = g_htonl (height);
header.bytes = g_htonl (pixmap ? 4 : 1);
header.magic_number = g_htonl (GIMP_BRUSH_MAGIC);
header.spacing = g_htonl (gimp_brush_get_spacing (brush));
if (! g_output_stream_write_all (output, &header, sizeof (header),
NULL, NULL, error))
{
return FALSE;
}
if (! g_output_stream_write_all (output, name, strlen (name) + 1,
NULL, NULL, error))
{
return FALSE;
}
if (pixmap)
{
gsize size = width * height * 4;
guchar *data = g_alloca (size);
guchar *p = gimp_temp_buf_get_data (pixmap);
guchar *m = gimp_temp_buf_get_data (mask);
guchar *d = data;
gint i;
for (i = 0; i < width * height; i++)
{
*d++ = *p++;
*d++ = *p++;
*d++ = *p++;
*d++ = *m++;
}
if (! g_output_stream_write_all (output, data, size,
NULL, NULL, error))
{
return FALSE;
}
}
else
{
if (! g_output_stream_write_all (output,
gimp_temp_buf_get_data (mask),
gimp_temp_buf_get_data_size (mask),
NULL, NULL, error))
{
return FALSE;
}
}
return TRUE;
}

28
app/core/gimpbrush-save.h Normal file
View File

@ -0,0 +1,28 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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_BRUSH_SAVE_H__
#define __GIMP_BRUSH_SAVE_H__
/* don't call this function directly, use gimp_data_save() instead */
gboolean gimp_brush_save (GimpData *data,
GOutputStream *output,
GError **error);
#endif /* __GIMP_BRUSH_SAVE_H__ */

View File

@ -31,6 +31,7 @@
#include "gimpbrush-boundary.h" #include "gimpbrush-boundary.h"
#include "gimpbrush-load.h" #include "gimpbrush-load.h"
#include "gimpbrush-private.h" #include "gimpbrush-private.h"
#include "gimpbrush-save.h"
#include "gimpbrush-transform.h" #include "gimpbrush-transform.h"
#include "gimpbrushcache.h" #include "gimpbrushcache.h"
#include "gimpbrushgenerated.h" #include "gimpbrushgenerated.h"
@ -82,6 +83,8 @@ static gchar * gimp_brush_get_description (GimpViewable *vie
static void gimp_brush_dirty (GimpData *data); static void gimp_brush_dirty (GimpData *data);
static const gchar * gimp_brush_get_extension (GimpData *data); static const gchar * gimp_brush_get_extension (GimpData *data);
static void gimp_brush_copy (GimpData *data,
GimpData *src_data);
static void gimp_brush_real_begin_use (GimpBrush *brush); static void gimp_brush_real_begin_use (GimpBrush *brush);
static void gimp_brush_real_end_use (GimpBrush *brush); static void gimp_brush_real_end_use (GimpBrush *brush);
@ -134,7 +137,9 @@ gimp_brush_class_init (GimpBrushClass *klass)
viewable_class->get_description = gimp_brush_get_description; viewable_class->get_description = gimp_brush_get_description;
data_class->dirty = gimp_brush_dirty; data_class->dirty = gimp_brush_dirty;
data_class->save = gimp_brush_save;
data_class->get_extension = gimp_brush_get_extension; data_class->get_extension = gimp_brush_get_extension;
data_class->copy = gimp_brush_copy;
klass->begin_use = gimp_brush_real_begin_use; klass->begin_use = gimp_brush_real_begin_use;
klass->end_use = gimp_brush_real_end_use; klass->end_use = gimp_brush_real_end_use;
@ -417,6 +422,28 @@ gimp_brush_get_extension (GimpData *data)
return GIMP_BRUSH_FILE_EXTENSION; return GIMP_BRUSH_FILE_EXTENSION;
} }
static void
gimp_brush_copy (GimpData *data,
GimpData *src_data)
{
GimpBrush *brush = GIMP_BRUSH (data);
GimpBrush *src_brush = GIMP_BRUSH (src_data);
g_clear_pointer (&brush->priv->mask, gimp_temp_buf_unref);
if (src_brush->priv->mask)
brush->priv->mask = gimp_temp_buf_copy (src_brush->priv->mask);
g_clear_pointer (&brush->priv->pixmap, gimp_temp_buf_unref);
if (src_brush->priv->pixmap)
brush->priv->pixmap = gimp_temp_buf_copy (src_brush->priv->pixmap);
brush->priv->spacing = src_brush->priv->spacing;
brush->priv->x_axis = src_brush->priv->x_axis;
brush->priv->y_axis = src_brush->priv->y_axis;
gimp_data_dirty (data);
}
static void static void
gimp_brush_real_begin_use (GimpBrush *brush) gimp_brush_real_begin_use (GimpBrush *brush)
{ {

View File

@ -57,9 +57,8 @@ static void gimp_brush_clipboard_get_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
#if 0
static GimpData * gimp_brush_clipboard_duplicate (GimpData *data); static GimpData * gimp_brush_clipboard_duplicate (GimpData *data);
#endif
static void gimp_brush_clipboard_changed (Gimp *gimp, static void gimp_brush_clipboard_changed (Gimp *gimp,
GimpBrush *brush); GimpBrush *brush);
@ -74,17 +73,13 @@ static void
gimp_brush_clipboard_class_init (GimpBrushClipboardClass *klass) gimp_brush_clipboard_class_init (GimpBrushClipboardClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
#if 0
GimpDataClass *data_class = GIMP_DATA_CLASS (klass); GimpDataClass *data_class = GIMP_DATA_CLASS (klass);
#endif
object_class->constructed = gimp_brush_clipboard_constructed; object_class->constructed = gimp_brush_clipboard_constructed;
object_class->set_property = gimp_brush_clipboard_set_property; object_class->set_property = gimp_brush_clipboard_set_property;
object_class->get_property = gimp_brush_clipboard_get_property; object_class->get_property = gimp_brush_clipboard_get_property;
#if 0
data_class->duplicate = gimp_brush_clipboard_duplicate; data_class->duplicate = gimp_brush_clipboard_duplicate;
#endif
g_object_class_install_property (object_class, PROP_GIMP, g_object_class_install_property (object_class, PROP_GIMP,
g_param_spec_object ("gimp", NULL, NULL, g_param_spec_object ("gimp", NULL, NULL,
@ -168,15 +163,15 @@ gimp_brush_clipboard_get_property (GObject *object,
} }
} }
#if 0
static GimpData * static GimpData *
gimp_brush_clipboard_duplicate (GimpData *data) gimp_brush_clipboard_duplicate (GimpData *data)
{ {
GimpBrushClipboard *brush = GIMP_BRUSH_CLIPBOARD (data); GimpData *new = g_object_new (GIMP_TYPE_BRUSH, NULL);
return gimp_brush_clipboard_new (brush->gimp); gimp_data_copy (new, data);
return new;
} }
#endif
GimpData * GimpData *
gimp_brush_clipboard_new (Gimp *gimp, gimp_brush_clipboard_new (Gimp *gimp,

View File

@ -63,6 +63,7 @@ gimp_brush_pipe_class_init (GimpBrushPipeClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass); GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass); GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
GimpDataClass *data_class = GIMP_DATA_CLASS (klass);
GimpBrushClass *brush_class = GIMP_BRUSH_CLASS (klass); GimpBrushClass *brush_class = GIMP_BRUSH_CLASS (klass);
object_class->finalize = gimp_brush_pipe_finalize; object_class->finalize = gimp_brush_pipe_finalize;
@ -71,6 +72,9 @@ gimp_brush_pipe_class_init (GimpBrushPipeClass *klass)
viewable_class->get_popup_size = gimp_brush_pipe_get_popup_size; viewable_class->get_popup_size = gimp_brush_pipe_get_popup_size;
data_class->save = NULL; /* don't inherit */
data_class->copy = NULL; /* don't inherit */
brush_class->begin_use = gimp_brush_pipe_begin_use; brush_class->begin_use = gimp_brush_pipe_begin_use;
brush_class->end_use = gimp_brush_pipe_end_use; brush_class->end_use = gimp_brush_pipe_end_use;
brush_class->select_brush = gimp_brush_pipe_select_brush; brush_class->select_brush = gimp_brush_pipe_select_brush;