Jens Lautenbacher <jtl@gimp.org>

2000-12-18  Sven Neumann  <sven@gimp.org>
	    Jens Lautenbacher <jtl@gimp.org>

	* app/Makefile.am

	* app/gimpbrushlistP.h
	* app/gimpbrushpipeP.h
	* app/gimpobjectP.h: removed these three files

	* app/parasitelistP.h
	* app/channels_dialog.c
	* app/docindex.c
	* app/gimpdrawable.c
	* app/gimpdrawableP.h
	* app/gimpimage.c
	* app/gimpimageP.h
	* app/gimplist.[ch]
	* app/gimpobject.c
	* app/gimpobject.h
	* app/gimpsetP.h: changed according to header removal

	* app/airbrush.c
	* app/brush_select.[ch]
	* app/brushes_cmds.c
	* app/gimpbrush.[ch]
	* app/gimpbrushgenerated.[ch]
	* app/gimpbrushlist.[ch]
	* app/gimpbrushpipe.[ch]
	* app/gimpcontextpreview.c
	* app/paint_core.c
	* app/paintbrush.c
	* app/pencil.c
	* tools/pdbgen/pdb/brushes.pdb: Big Brushes Cleanup.

	The GimpBrush* object hierarchy and the file formats were broken by
	"design". This made it overly difficult to read and write pixmap
	brushes and brush pipes, leading to the situation that The GIMP was
	not able to read it's very own file formats. Since the GimpBrush
	format did support arbitrary color depths, the introduction of a
	file format for pixmap brushes was unnecessary.

	The GimpBrushPixmap object is dead. GimpBrush has an additional
	pixmap temp_buf and handles pixmap brushes transparently. The file
	format of pixmap brushes is not any longer a grayscale brush plus
	a pattern, but a simple brush with RGBA data. The old brushes can
	still be loaded, but the .gpb format is deprecated.

	GimpBrushPipe derives from GimpBrush. The fileformat is still a text
	header, followed by a number of brushes, but those brushes are stored
	in the new GimpBrush format (no pattern anymore). The pipe does not
	care about the depth of the contained GimpBrushes, so we get
	grayscale BrushPipes for free. Since the brush loader still loads the
	old format, old .gih files can also still be loaded.

	Since the brushes in the GimpBrushPipe do not any longer contain a
	pointer to the pipe object, we do only temporarily switch brushes
	in the paint_core routines. This is not very elegant, but the best
	we can do without a major redesign.

	* app/patterns.[ch]: changed the loader to work with a filedescriptor
	instead of a filehandle to make it work with the new brush loading
	code.

	* plug-ins/common/.cvsignore
	* plug-ins/common/Makefile.am
	* plug-ins/common/plugin-defs.pl
	* plug-ins/common/gih.c: new plug-in that saves GIH files in the
	new format (loader will follow soon)

	* plug-ins/common/gpb.c: removed since Pixmap Brushes are no longer
	supported as a special file format.

	* plug-ins/common/gbr.c: load and save brushes in the new brush format
	which allows RGBA brushes too.

	* plug-ins/common/pat.c: load and save grayscale patterns too
This commit is contained in:
Sven Neumann 2000-12-18 15:14:08 +00:00 committed by Sven Neumann
parent 333bfaf5b6
commit 3cff8419db
75 changed files with 2005 additions and 2175 deletions

View File

@ -1,3 +1,80 @@
2000-12-18 Sven Neumann <sven@gimp.org>
Jens Lautenbacher <jtl@gimp.org>
* app/Makefile.am
* app/gimpbrushlistP.h
* app/gimpbrushpipeP.h
* app/gimpobjectP.h: removed these three files
* app/parasitelistP.h
* app/channels_dialog.c
* app/docindex.c
* app/gimpdrawable.c
* app/gimpdrawableP.h
* app/gimpimage.c
* app/gimpimageP.h
* app/gimplist.[ch]
* app/gimpobject.c
* app/gimpobject.h
* app/gimpsetP.h: changed according to header removal
* app/airbrush.c
* app/brush_select.[ch]
* app/brushes_cmds.c
* app/gimpbrush.[ch]
* app/gimpbrushgenerated.[ch]
* app/gimpbrushlist.[ch]
* app/gimpbrushpipe.[ch]
* app/gimpcontextpreview.c
* app/paint_core.c
* app/paintbrush.c
* app/pencil.c
* tools/pdbgen/pdb/brushes.pdb: Big Brushes Cleanup.
The GimpBrush* object hierarchy and the file formats were broken by
"design". This made it overly difficult to read and write pixmap
brushes and brush pipes, leading to the situation that The GIMP was
not able to read it's very own file formats. Since the GimpBrush
format did support arbitrary color depths, the introduction of a
file format for pixmap brushes was unnecessary.
The GimpBrushPixmap object is dead. GimpBrush has an additional
pixmap temp_buf and handles pixmap brushes transparently. The file
format of pixmap brushes is not any longer a grayscale brush plus
a pattern, but a simple brush with RGBA data. The old brushes can
still be loaded, but the .gpb format is deprecated.
GimpBrushPipe derives from GimpBrush. The fileformat is still a text
header, followed by a number of brushes, but those brushes are stored
in the new GimpBrush format (no pattern anymore). The pipe does not
care about the depth of the contained GimpBrushes, so we get
grayscale BrushPipes for free. Since the brush loader still loads the
old format, old .gih files can also still be loaded.
Since the brushes in the GimpBrushPipe do not any longer contain a
pointer to the pipe object, we do only temporarily switch brushes
in the paint_core routines. This is not very elegant, but the best
we can do without a major redesign.
* app/patterns.[ch]: changed the loader to work with a filedescriptor
instead of a filehandle to make it work with the new brush loading
code.
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl
* plug-ins/common/gih.c: new plug-in that saves GIH files in the
new format (loader will follow soon)
* plug-ins/common/gpb.c: removed since Pixmap Brushes are no longer
supported as a special file format.
* plug-ins/common/gbr.c: load and save brushes in the new brush format
which allows RGBA brushes too.
* plug-ins/common/pat.c: load and save grayscale patterns too
2000-12-18 Michael Natterer <mitch@gimp.org>
* plug-ins/common/gee.c: Using "env" instead of "environ" caused

View File

@ -14,7 +14,6 @@ libgimpim_a_SOURCES = \
gimpimageP.h \
gimpobject.c \
gimpobject.h \
gimpobjectP.h \
gimppreviewcache.h \
gimppreviewcache.c \
gimpset.c \
@ -180,10 +179,8 @@ gimp_SOURCES = \
gimpbrushgenerated.h \
gimpbrushlist.c \
gimpbrushlist.h \
gimpbrushlistP.h \
gimpbrushpipe.c \
gimpbrushpipe.h \
gimpbrushpipeP.h \
gimpcontext.c \
gimpcontext.h \
gimpcontextpreview.c \

View File

@ -26,7 +26,6 @@
#include "airbrush.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "gimage.h"
#include "gimpui.h"
@ -330,7 +329,7 @@ airbrush_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
mode = INCREMENTAL;
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -32,7 +32,6 @@
#include "gimpbrushgenerated.h"
#include "gimpbrushlist.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "gimpcontext.h"
#include "gimpdnd.h"
#include "gimplist.h"
@ -953,9 +952,9 @@ draw_brush_popup (GtkPreview *preview,
buf = g_new (guchar, 3 * width);
memset (buf, 255, 3 * width);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (gimp_brush_get_pixmap (brush))
{
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (brush)->pixmap_mask);
guchar *pixmap = temp_buf_data (gimp_brush_get_pixmap (brush));
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (preview, buf, 0, y, width);
@ -1070,7 +1069,7 @@ brush_popup_timeout (gpointer data)
/* decide where to put the popup */
width = brush->mask->width;
height = brush->mask->height;
if (GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
if (GIMP_IS_BRUSH_PIPE (brush))
{
GimpBrushPipe *pipe = GIMP_BRUSH_PIPE (brush);
GimpBrush *tmp_brush;
@ -1100,7 +1099,7 @@ brush_popup_timeout (gpointer data)
draw_brush_popup (GTK_PREVIEW (bsp->brush_preview), brush, width, height);
gtk_widget_queue_draw (bsp->brush_preview);
if (GIMP_IS_REALLY_A_BRUSH_PIPE (brush) && bsp->popup_anim_timeout_tag == 0)
if (GIMP_IS_BRUSH_PIPE (brush) && bsp->popup_anim_timeout_tag == 0)
{
static popup_timeout_args_t timeout_args;
@ -1222,9 +1221,8 @@ display_brush (BrushSelect *bsp,
cell_width = bsp->cell_width - 2 * MARGIN_WIDTH;
cell_height = bsp->cell_height - 2 * MARGIN_HEIGHT;
mask_buf = brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (brush))
pixmap_buf = GIMP_BRUSH_PIXMAP (brush)->pixmap_mask;
mask_buf = gimp_brush_get_mask (brush);
pixmap_buf = gimp_brush_get_pixmap (brush);
if (mask_buf->width > cell_width || mask_buf->height > cell_height)
{
@ -1234,7 +1232,7 @@ display_brush (BrushSelect *bsp,
mask_buf = brush_scale_mask (mask_buf,
(gdouble)(mask_buf->width) / MAX (ratio_x, ratio_y) + 0.5,
(gdouble)(mask_buf->height) / MAX (ratio_x, ratio_y) + 0.5);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
@ -1257,9 +1255,11 @@ display_brush (BrushSelect *bsp,
mask = temp_buf_data (mask_buf) + (ystart - offset_y) * mask_buf->width;
buf = g_new (guchar, 3 * cell_width);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
{
guchar *pixmap = temp_buf_data (pixmap_buf) + (ystart - offset_y) * mask_buf->width * 3;
guchar *pixmap =
temp_buf_data (pixmap_buf) + (ystart - offset_y) * mask_buf->width * 3;
for (i = ystart; i < yend; i++)
{
b = buf;
@ -1303,12 +1303,13 @@ display_brush (BrushSelect *bsp,
if (scale)
{
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
temp_buf_free (pixmap_buf);
for (i = 0; i < indicator_height; i++, offset_y++)
{
if (offset_y > 0 && offset_y < bsp->preview->allocation.height)
(GIMP_IS_REALLY_A_BRUSH_PIPE (brush)) ?
(GIMP_IS_BRUSH_PIPE (brush)) ?
gtk_preview_draw_row (GTK_PREVIEW (bsp->preview),
scale_pipe_indicator_bits[i][0],
offset_x, offset_y, indicator_width) :
@ -1317,7 +1318,7 @@ display_brush (BrushSelect *bsp,
offset_x, offset_y, indicator_width);
}
}
else if (GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
else if (GIMP_IS_BRUSH_PIPE (brush))
{
for (i = 0; i < indicator_height; i++, offset_y++)
{
@ -1617,7 +1618,7 @@ brush_select_events (GtkWidget *widget,
/* Show the brush popup window if the brush is too large */
if (brush->mask->width > bsp->cell_width - 2 * MARGIN_WIDTH ||
brush->mask->height > bsp->cell_height - 2 * MARGIN_HEIGHT ||
GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
GIMP_IS_BRUSH_PIPE (brush))
{
brush_popup_open (bsp, bevent->x, bevent->y, brush);
}
@ -1808,19 +1809,21 @@ static void
brush_select_new_brush_callback (GtkWidget *widget,
gpointer data)
{
GimpBrushGenerated *brush;
GimpBrush *brush;
BrushSelect *bsp;
bsp = (BrushSelect *) data;
brush = gimp_brush_generated_new (10, .5, 0.0, 1.0);
gimp_brush_list_add (brush_list, GIMP_BRUSH (brush));
if (brush)
{
gimp_brush_list_add (brush_list, brush);
gimp_context_set_brush (bsp->context, GIMP_BRUSH (brush));
gimp_context_set_brush (bsp->context, brush);
if (brush_edit_generated_dialog)
brush_edit_generated_set_brush (brush_edit_generated_dialog,
GIMP_BRUSH (brush));
brush_edit_generated_set_brush (brush_edit_generated_dialog, brush);
}
brush_select_edit_brush_callback (widget, data);
}

View File

@ -21,6 +21,7 @@
#include "gimpbrush.h"
#include "gimpcontext.h"
typedef struct _BrushSelect BrushSelect;

View File

@ -24,7 +24,7 @@
#include "apptypes.h"
#include "gimpbrush.h"
#include "gimpbrushlistP.h"
#include "gimpbrushlist.h"
#include "gimpcontext.h"
#include "gimplist.h"

View File

@ -31,6 +31,7 @@
#include "gimage.h"
#include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimppreviewcache.h"
#include "gimprc.h"
#include "gimpui.h"
#include "layers_dialogP.h"

View File

@ -22,15 +22,41 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#include <gtk/gtk.h>
#include <stdio.h>
#include "apptypes.h"
#include "libgimp/gimpvector.h"
#include "brush_header.h"
#include "pattern_header.h"
#include "gimpbrush.h"
#include "gimpbrushlist.h"
#include "gimpsignal.h"
#include "gimprc.h"
#include "brush_header.h"
#include "config.h"
#include "paint_core.h"
#include "temp_buf.h"
#include "libgimp/gimpintl.h"
enum
@ -93,12 +119,15 @@ gimp_brush_init (GimpBrush *brush)
{
brush->filename = NULL;
brush->name = NULL;
brush->spacing = 20;
brush->mask = NULL;
brush->x_axis.x = 15.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = 15.0;
brush->mask = NULL;
brush->pixmap = NULL;
}
@ -127,14 +156,32 @@ gimp_brush_get_type (void)
}
GimpBrush *
gimp_brush_new (gchar *filename)
gimp_brush_load (gchar *filename)
{
GimpBrush *brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
GimpBrush *brush;
gint fd;
if (gimp_brush_load (brush, filename))
return brush;
g_return_val_if_fail (filename != NULL, NULL);
fd = open (filename, O_RDONLY | _O_BINARY);
if (fd == -1)
return NULL;
brush = gimp_brush_load_brush (fd, filename);
close (fd);
brush->filename = g_strdup (filename);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
{
temp_buf_swap (brush->mask);
if (brush->pixmap)
temp_buf_swap (brush->pixmap);
}
return brush;
}
static GimpBrush *
@ -158,6 +205,15 @@ gimp_brush_get_mask (GimpBrush *brush)
return brush->mask;
}
TempBuf *
gimp_brush_get_pixmap (GimpBrush *brush)
{
g_return_val_if_fail (brush != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
return brush->pixmap;
}
gchar *
gimp_brush_get_name (GimpBrush *brush)
{
@ -203,125 +259,145 @@ gimp_brush_set_spacing (GimpBrush *brush,
brush->spacing = spacing;
}
gboolean
gimp_brush_load (GimpBrush *brush,
gchar *filename)
{
FILE *fp;
brush->filename = g_strdup (filename);
/* Open the requested file */
if (! (fp = fopen (filename, "rb")))
{
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
if (! gimp_brush_load_brush (brush, fp, filename))
{
return FALSE;
}
/* Clean up */
fclose (fp);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
return TRUE;
}
gboolean
gimp_brush_load_brush (GimpBrush *brush,
FILE *fp,
GimpBrush *
gimp_brush_load_brush (gint fd,
gchar *filename)
{
GimpBrush *brush;
GPattern *pattern;
gint bn_size;
guchar buf [sizeof (BrushHeader)];
BrushHeader header;
guint *hp;
gchar *name;
gint i;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (fd != -1, NULL);
/* Read in the header size */
if ((fread (buf, 1, sizeof (BrushHeader), fp)) < sizeof (BrushHeader))
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
if (read (fd, &header, sizeof (header)) != sizeof (header))
return NULL;
/* rearrange the bytes in each unsigned int */
hp = (guint *) &header;
for (i = 0; i < (sizeof (BrushHeader) / 4); i++)
hp [i] = ((buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]));
header.header_size = g_ntohl (header.header_size);
header.version = g_ntohl (header.version);
header.width = g_ntohl (header.width);
header.height = g_ntohl (header.height);
header.bytes = g_ntohl (header.bytes);
header.magic_number = g_ntohl (header.magic_number);
header.spacing = g_ntohl (header.spacing);
/* Check for correct file format */
if (header.magic_number != GBRUSH_MAGIC)
/* It looks as if version 1 did not have the same magic number. (neo) */
if (header.version != 1 &&
(header.magic_number != GBRUSH_MAGIC || header.version != 2))
{
if (header.version != 1)
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
g_message (_("Unknown brush format version #%d in \"%s\"."),
header.version, filename);
return NULL;
}
if (header.version == 1)
{
/* If this is a version 1 brush, set the fp back 8 bytes */
fseek (fp, -8, SEEK_CUR);
lseek (fd, -8, SEEK_CUR);
header.header_size += 8;
/* spacing is not defined in version 1 */
header.spacing = 25;
}
/* Read in the brush name */
if ((bn_size = (header.header_size - sizeof (BrushHeader))))
if ((bn_size = (header.header_size - sizeof (header))))
{
brush->name = g_new (gchar, bn_size);
if ((fread (brush->name, 1, bn_size, fp)) < bn_size)
name = g_new (gchar, bn_size);
if ((read (fd, name, bn_size)) < bn_size)
{
g_message (_("Error in GIMP brush file...aborting."));
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
g_message (_("Error in GIMP brush file \"%s\"."), filename);
g_free (name);
return NULL;
}
}
else
{
brush->name = g_strdup (_("Unnamed"));
name = g_strdup (_("Unnamed"));
}
switch (header.version)
switch (header.bytes)
{
case 1:
case 2:
/* Get a new brush mask */
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
brush->mask = temp_buf_new (header.width, header.height, 1,
0, 0, NULL);
if (read (fd,
temp_buf_data (brush->mask), header.width * header.height) <
header.width * header.height)
{
g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
/* For backwards-compatibility, check if a pattern follows.
The obsolete .gpb format did it this way. */
pattern = pattern_load (fd, filename);
if (pattern)
{
if (pattern->mask && pattern->mask->bytes == 3)
{
brush->pixmap = pattern->mask;
pattern->mask = NULL;
}
pattern_free (pattern);
}
else
{
/* rewind to make brush pipe loader happy */
if (lseek (fd, - sizeof (PatternHeader), SEEK_CUR) < 0)
{
g_message (_("GIMP brush file appears to be corrupted: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
}
break;
case 4:
brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
brush->mask = temp_buf_new (header.width, header.height, 1, 0, 0, NULL);
brush->pixmap = temp_buf_new (header.width, header.height, 3, 0, 0, NULL);
for (i = 0; i < header.width * header.height; i++)
{
if (read (fd, temp_buf_data (brush->pixmap)
+ i * 3, 3) != 3 ||
read (fd, temp_buf_data (brush->mask) + i, 1) != 1)
{
g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
}
break;
default:
g_message ("Unsupported brush depth: %d\n in file \"%s\"\nGIMP Brushes must be GRAY or RGBA\n",
header.bytes, filename);
g_free (name);
return NULL;
}
brush->name = name;
brush->spacing = header.spacing;
/* set up spacing axis */
brush->x_axis.x = header.width / 2.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = header.height / 2.0;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask),
1, header.width * header.height, fp)) <
header.width * header.height)
g_message (_("GIMP brush file appears to be truncated."));
break;
default:
g_message (_("Unknown brush format version #%d in \"%s\"\n"),
header.version, filename);
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
return TRUE;
return brush;
}

View File

@ -22,15 +22,41 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#include <gtk/gtk.h>
#include <stdio.h>
#include "apptypes.h"
#include "libgimp/gimpvector.h"
#include "brush_header.h"
#include "pattern_header.h"
#include "gimpbrush.h"
#include "gimpbrushlist.h"
#include "gimpsignal.h"
#include "gimprc.h"
#include "brush_header.h"
#include "config.h"
#include "paint_core.h"
#include "temp_buf.h"
#include "libgimp/gimpintl.h"
enum
@ -93,12 +119,15 @@ gimp_brush_init (GimpBrush *brush)
{
brush->filename = NULL;
brush->name = NULL;
brush->spacing = 20;
brush->mask = NULL;
brush->x_axis.x = 15.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = 15.0;
brush->mask = NULL;
brush->pixmap = NULL;
}
@ -127,14 +156,32 @@ gimp_brush_get_type (void)
}
GimpBrush *
gimp_brush_new (gchar *filename)
gimp_brush_load (gchar *filename)
{
GimpBrush *brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
GimpBrush *brush;
gint fd;
if (gimp_brush_load (brush, filename))
return brush;
g_return_val_if_fail (filename != NULL, NULL);
fd = open (filename, O_RDONLY | _O_BINARY);
if (fd == -1)
return NULL;
brush = gimp_brush_load_brush (fd, filename);
close (fd);
brush->filename = g_strdup (filename);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
{
temp_buf_swap (brush->mask);
if (brush->pixmap)
temp_buf_swap (brush->pixmap);
}
return brush;
}
static GimpBrush *
@ -158,6 +205,15 @@ gimp_brush_get_mask (GimpBrush *brush)
return brush->mask;
}
TempBuf *
gimp_brush_get_pixmap (GimpBrush *brush)
{
g_return_val_if_fail (brush != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
return brush->pixmap;
}
gchar *
gimp_brush_get_name (GimpBrush *brush)
{
@ -203,125 +259,145 @@ gimp_brush_set_spacing (GimpBrush *brush,
brush->spacing = spacing;
}
gboolean
gimp_brush_load (GimpBrush *brush,
gchar *filename)
{
FILE *fp;
brush->filename = g_strdup (filename);
/* Open the requested file */
if (! (fp = fopen (filename, "rb")))
{
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
if (! gimp_brush_load_brush (brush, fp, filename))
{
return FALSE;
}
/* Clean up */
fclose (fp);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
return TRUE;
}
gboolean
gimp_brush_load_brush (GimpBrush *brush,
FILE *fp,
GimpBrush *
gimp_brush_load_brush (gint fd,
gchar *filename)
{
GimpBrush *brush;
GPattern *pattern;
gint bn_size;
guchar buf [sizeof (BrushHeader)];
BrushHeader header;
guint *hp;
gchar *name;
gint i;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (fd != -1, NULL);
/* Read in the header size */
if ((fread (buf, 1, sizeof (BrushHeader), fp)) < sizeof (BrushHeader))
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
if (read (fd, &header, sizeof (header)) != sizeof (header))
return NULL;
/* rearrange the bytes in each unsigned int */
hp = (guint *) &header;
for (i = 0; i < (sizeof (BrushHeader) / 4); i++)
hp [i] = ((buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]));
header.header_size = g_ntohl (header.header_size);
header.version = g_ntohl (header.version);
header.width = g_ntohl (header.width);
header.height = g_ntohl (header.height);
header.bytes = g_ntohl (header.bytes);
header.magic_number = g_ntohl (header.magic_number);
header.spacing = g_ntohl (header.spacing);
/* Check for correct file format */
if (header.magic_number != GBRUSH_MAGIC)
/* It looks as if version 1 did not have the same magic number. (neo) */
if (header.version != 1 &&
(header.magic_number != GBRUSH_MAGIC || header.version != 2))
{
if (header.version != 1)
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
g_message (_("Unknown brush format version #%d in \"%s\"."),
header.version, filename);
return NULL;
}
if (header.version == 1)
{
/* If this is a version 1 brush, set the fp back 8 bytes */
fseek (fp, -8, SEEK_CUR);
lseek (fd, -8, SEEK_CUR);
header.header_size += 8;
/* spacing is not defined in version 1 */
header.spacing = 25;
}
/* Read in the brush name */
if ((bn_size = (header.header_size - sizeof (BrushHeader))))
if ((bn_size = (header.header_size - sizeof (header))))
{
brush->name = g_new (gchar, bn_size);
if ((fread (brush->name, 1, bn_size, fp)) < bn_size)
name = g_new (gchar, bn_size);
if ((read (fd, name, bn_size)) < bn_size)
{
g_message (_("Error in GIMP brush file...aborting."));
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
g_message (_("Error in GIMP brush file \"%s\"."), filename);
g_free (name);
return NULL;
}
}
else
{
brush->name = g_strdup (_("Unnamed"));
name = g_strdup (_("Unnamed"));
}
switch (header.version)
switch (header.bytes)
{
case 1:
case 2:
/* Get a new brush mask */
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
brush->mask = temp_buf_new (header.width, header.height, 1,
0, 0, NULL);
if (read (fd,
temp_buf_data (brush->mask), header.width * header.height) <
header.width * header.height)
{
g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
/* For backwards-compatibility, check if a pattern follows.
The obsolete .gpb format did it this way. */
pattern = pattern_load (fd, filename);
if (pattern)
{
if (pattern->mask && pattern->mask->bytes == 3)
{
brush->pixmap = pattern->mask;
pattern->mask = NULL;
}
pattern_free (pattern);
}
else
{
/* rewind to make brush pipe loader happy */
if (lseek (fd, - sizeof (PatternHeader), SEEK_CUR) < 0)
{
g_message (_("GIMP brush file appears to be corrupted: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
}
break;
case 4:
brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
brush->mask = temp_buf_new (header.width, header.height, 1, 0, 0, NULL);
brush->pixmap = temp_buf_new (header.width, header.height, 3, 0, 0, NULL);
for (i = 0; i < header.width * header.height; i++)
{
if (read (fd, temp_buf_data (brush->pixmap)
+ i * 3, 3) != 3 ||
read (fd, temp_buf_data (brush->mask) + i, 1) != 1)
{
g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
}
break;
default:
g_message ("Unsupported brush depth: %d\n in file \"%s\"\nGIMP Brushes must be GRAY or RGBA\n",
header.bytes, filename);
g_free (name);
return NULL;
}
brush->name = name;
brush->spacing = header.spacing;
/* set up spacing axis */
brush->x_axis.x = header.width / 2.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = header.height / 2.0;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask),
1, header.width * header.height, fp)) <
header.width * header.height)
g_message (_("GIMP brush file appears to be truncated."));
break;
default:
g_message (_("Unknown brush format version #%d in \"%s\"\n"),
header.version, filename);
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
return TRUE;
return brush;
}

View File

@ -20,15 +20,12 @@
#define __GIMP_BRUSH_H__
#include <stdio.h>
#include "apptypes.h"
#include "gimpobjectP.h"
#include "paint_core.h"
#include "gimpobject.h"
#include "temp_buf.h"
#include "libgimp/gimpvector.h"
typedef struct _GimpBrushClass GimpBrushClass;
struct _GimpBrush
@ -40,7 +37,8 @@ struct _GimpBrush
gint spacing; /* brush's spacing */
GimpVector2 x_axis; /* for calculating brush spacing */
GimpVector2 y_axis; /* for calculating brush spacing */
TempBuf *mask; /* the actual mask... */
TempBuf *mask; /* the actual mask */
TempBuf *pixmap; /* optional pixmap data */
};
struct _GimpBrushClass
@ -57,15 +55,13 @@ struct _GimpBrushClass
#define GIMP_IS_BRUSH(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH))
GtkType gimp_brush_get_type (void);
GimpBrush * gimp_brush_new (gchar *filename);
GimpBrush * gimp_brush_load (gchar *filename);
gboolean gimp_brush_load (GimpBrush *brush,
gchar *filename);
gboolean gimp_brush_load_brush (GimpBrush *brush,
FILE *fp,
GimpBrush * gimp_brush_load_brush (gint fd,
gchar *filename);
TempBuf * gimp_brush_get_mask (GimpBrush *brush);
TempBuf * gimp_brush_get_pixmap (GimpBrush *brush);
gchar * gimp_brush_get_name (GimpBrush *brush);
void gimp_brush_set_name (GimpBrush *brush,

View File

@ -102,7 +102,7 @@ gimp_brush_generated_get_type (void)
return type;
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_new (gfloat radius,
gfloat hardness,
gfloat angle,
@ -126,10 +126,10 @@ gimp_brush_generated_new (gfloat radius,
/* render brush mask */
gimp_brush_generated_generate (brush);
return brush;
return GIMP_BRUSH (brush);
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_load (const gchar *file_name)
{
GimpBrushGenerated *brush;
@ -193,7 +193,7 @@ gimp_brush_generated_load (const gchar *file_name)
if (stingy_memory_use)
temp_buf_swap (GIMP_BRUSH (brush)->mask);
return brush;
return GIMP_BRUSH (brush);
}
void

View File

@ -102,7 +102,7 @@ gimp_brush_generated_get_type (void)
return type;
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_new (gfloat radius,
gfloat hardness,
gfloat angle,
@ -126,10 +126,10 @@ gimp_brush_generated_new (gfloat radius,
/* render brush mask */
gimp_brush_generated_generate (brush);
return brush;
return GIMP_BRUSH (brush);
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_load (const gchar *file_name)
{
GimpBrushGenerated *brush;
@ -193,7 +193,7 @@ gimp_brush_generated_load (const gchar *file_name)
if (stingy_memory_use)
temp_buf_swap (GIMP_BRUSH (brush)->mask);
return brush;
return GIMP_BRUSH (brush);
}
void

View File

@ -102,7 +102,7 @@ gimp_brush_generated_get_type (void)
return type;
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_new (gfloat radius,
gfloat hardness,
gfloat angle,
@ -126,10 +126,10 @@ gimp_brush_generated_new (gfloat radius,
/* render brush mask */
gimp_brush_generated_generate (brush);
return brush;
return GIMP_BRUSH (brush);
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_load (const gchar *file_name)
{
GimpBrushGenerated *brush;
@ -193,7 +193,7 @@ gimp_brush_generated_load (const gchar *file_name)
if (stingy_memory_use)
temp_buf_swap (GIMP_BRUSH (brush)->mask);
return brush;
return GIMP_BRUSH (brush);
}
void

View File

@ -53,11 +53,11 @@ struct _GimpBrushGeneratedClass
GtkType gimp_brush_generated_get_type (void);
GimpBrushGenerated * gimp_brush_generated_new (gfloat radius,
GimpBrush * gimp_brush_generated_new (gfloat radius,
gfloat hardness,
gfloat angle,
gfloat aspect_ratio);
GimpBrushGenerated * gimp_brush_generated_load (const gchar *file_name);
GimpBrush * gimp_brush_generated_load (const gchar *file_name);
void gimp_brush_generated_save (GimpBrushGenerated *brush,
const gchar *file_name);

View File

@ -19,11 +19,25 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#include <gtk/gtk.h>
#include "apptypes.h"
@ -33,7 +47,6 @@
#include "patterns.h"
#include "gimpbrush.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "paint_core.h"
#include "gimprc.h"
@ -43,87 +56,25 @@
#include "libgimp/gimpintl.h"
static GimpBrushClass *gimp_brush_class;
static GimpBrushPixmapClass *gimp_brush_pixmap_class;
static GimpBrushClass *parent_class;
static GimpBrush *gimp_brush_pixmap_select_brush (PaintCore *paint_core);
static gboolean gimp_brush_pixmap_want_null_motion (PaintCore *paint_core);
static void
gimp_brush_pixmap_destroy (GtkObject *object)
{
GimpBrushPixmap *pixmap;
static GimpBrush * gimp_brush_pipe_select_brush (PaintCore *paint_core);
static gboolean gimp_brush_pipe_want_null_motion (PaintCore *paint_core);
static void gimp_brush_pipe_destroy (GtkObject *object);
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_BRUSH_PIXMAP (object));
pixmap = GIMP_BRUSH_PIXMAP (object);
if (pixmap->pixmap_mask)
temp_buf_free (pixmap->pixmap_mask);
if (GTK_OBJECT_CLASS (gimp_brush_class)->destroy)
GTK_OBJECT_CLASS (gimp_brush_class)->destroy (object);
}
static void
gimp_brush_pixmap_class_init (GimpBrushPixmapClass *klass)
{
GtkObjectClass *object_class;
GimpBrushClass *brush_class;
object_class = GTK_OBJECT_CLASS (klass);
brush_class = GIMP_BRUSH_CLASS (klass);
gimp_brush_class = gtk_type_class (gimp_brush_get_type ());
object_class->destroy = gimp_brush_pixmap_destroy;
brush_class->select_brush = gimp_brush_pixmap_select_brush;
brush_class->want_null_motion = gimp_brush_pixmap_want_null_motion;
}
void
gimp_brush_pixmap_init (GimpBrushPixmap *brush)
{
brush->pixmap_mask = NULL;
brush->pipe = NULL;
}
GtkType
gimp_brush_pixmap_get_type (void)
{
static GtkType type = 0;
if (!type)
{
GtkTypeInfo info =
{
"GimpBrushPixmap",
sizeof (GimpBrushPixmap),
sizeof (GimpBrushPixmapClass),
(GtkClassInitFunc) gimp_brush_pixmap_class_init,
(GtkObjectInitFunc) gimp_brush_pixmap_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (GIMP_TYPE_BRUSH, &info);
}
return type;
}
static GimpBrush *
gimp_brush_pixmap_select_brush (PaintCore *paint_core)
gimp_brush_pipe_select_brush (PaintCore *paint_core)
{
GimpBrushPipe *pipe;
int i, brushix, ix;
double angle;
gint i, brushix, ix;
gdouble angle;
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), NULL);
g_return_val_if_fail (paint_core != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH_PIPE (paint_core->brush), NULL);
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
pipe = GIMP_BRUSH_PIPE (paint_core->brush);
if (pipe->nbrushes == 1)
return GIMP_BRUSH (pipe->current);
@ -168,7 +119,6 @@ gimp_brush_pixmap_select_brush (PaintCore *paint_core)
}
pipe->index[i] = CLAMP (ix, 0, pipe->rank[i]-1);
brushix += pipe->stride[i] * pipe->index[i];
/* g_print ("ix at %d: %d, brushix: %d\n", i, ix, brushix); */
}
/* Make sure is inside bounds */
@ -180,14 +130,15 @@ gimp_brush_pixmap_select_brush (PaintCore *paint_core)
}
static gboolean
gimp_brush_pixmap_want_null_motion (PaintCore *paint_core)
gimp_brush_pipe_want_null_motion (PaintCore *paint_core)
{
GimpBrushPipe *pipe;
gint i;
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), TRUE);
g_return_val_if_fail (paint_core != NULL, TRUE);
g_return_val_if_fail (GIMP_IS_BRUSH_PIPE (paint_core->brush), TRUE);
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
pipe = GIMP_BRUSH_PIPE (paint_core->brush);
if (pipe->nbrushes == 1)
return TRUE;
@ -221,18 +172,24 @@ gimp_brush_pipe_destroy (GtkObject *object)
g_free (pipe->select);
g_free (pipe->index);
if (GTK_OBJECT_CLASS (gimp_brush_pixmap_class)->destroy)
GTK_OBJECT_CLASS (gimp_brush_pixmap_class)->destroy (object);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
gimp_brush_pipe_class_init (GimpBrushPipeClass *klass)
{
GtkObjectClass *object_class;
GimpBrushClass *brush_class;
object_class = GTK_OBJECT_CLASS (klass);
brush_class = GIMP_BRUSH_CLASS (klass);
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
brush_class->select_brush = gimp_brush_pipe_select_brush;
brush_class->want_null_motion = gimp_brush_pipe_want_null_motion;
gimp_brush_pixmap_class = gtk_type_class (GIMP_TYPE_BRUSH_PIXMAP);
object_class->destroy = gimp_brush_pipe_destroy;
}
@ -268,55 +225,75 @@ gimp_brush_pipe_get_type (void)
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (GIMP_TYPE_BRUSH_PIXMAP, &info);
type = gtk_type_unique (GIMP_TYPE_BRUSH, &info);
}
return type;
}
GimpBrushPipe *
#include <errno.h>
GimpBrush *
gimp_brush_pipe_load (gchar *filename)
{
GimpBrushPipe *pipe;
GPattern *pattern;
GimpBrushPipe *pipe = NULL;
GimpPixPipeParams params;
FILE *fp;
gchar buf[1024];
gchar *name;
gint i;
gint num_of_brushes;
gint num_of_brushes = 0;
gint totalcells;
gchar *paramstring;
GString *buffer;
gchar c;
gint fd;
if ((fp = fopen (filename, "rb")) == NULL)
return NULL;
g_return_val_if_fail (filename != NULL, NULL);
/* The file format starts with a painfully simple text header
* and we use a painfully simple way to read it
*/
if (fgets (buf, 1024, fp) == NULL)
fd = open (filename, O_RDONLY | _O_BINARY);
if (fd == -1)
{
fclose (fp);
g_message ("Couldn't open file '%s'", filename);
return NULL;
}
buf[strlen (buf) - 1] = 0;
/* The file format starts with a painfully simple text header */
/* get the name */
buffer = g_string_new (NULL);
while (read (fd, &c, 1) == 1 && c != '\n' && buffer->len < 1024)
g_string_append_c (buffer, c);
if (buffer->len > 0 && buffer->len < 1024)
{
pipe = GIMP_BRUSH_PIPE (gtk_type_new (GIMP_TYPE_BRUSH_PIPE));
name = g_strdup (buf);
GIMP_BRUSH (pipe)->name = buffer->str;
}
g_string_free (buffer, FALSE);
if (!pipe)
{
g_message ("Couldn't read name for brush pipe from file '%s'\n",
filename);
close (fd);
return NULL;
}
/* get the number of brushes */
if (fgets (buf, 1024, fp) == NULL)
buffer = g_string_new (NULL);
while (read (fd, &c, 1) == 1 && c != '\n' && buffer->len < 1024)
g_string_append_c (buffer, c);
if (buffer->len > 0 && buffer->len < 1024)
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
num_of_brushes = strtol (buffer->str, &paramstring, 10);
}
num_of_brushes = strtol (buf, &paramstring, 10);
if (num_of_brushes < 1)
{
g_message (_("Brush pipes should have at least one brush."));
fclose (fp);
g_message (_("Brush pipes should have at least one brush:\n\"%s\""),
filename);
close (fd);
gtk_object_sink (GTK_OBJECT (pipe));
g_string_free (buffer, TRUE);
return NULL;
}
@ -372,6 +349,8 @@ gimp_brush_pipe_load (gchar *filename)
pipe->index[0] = 0;
}
g_string_free (buffer, TRUE);
totalcells = 1; /* Not all necessarily present, maybe */
for (i = 0; i < pipe->dimension; i++)
totalcells *= pipe->rank[i];
@ -385,136 +364,41 @@ gimp_brush_pipe_load (gchar *filename)
}
g_assert (pipe->stride[pipe->dimension-1] == 1);
pattern = g_new0 (GPattern, 1);
pipe->brushes = g_new0 (GimpBrushPixmap *, num_of_brushes);
/* First pixmap brush in the list is the pipe itself */
pipe->brushes[0] = GIMP_BRUSH_PIXMAP (pipe);
/* Current pixmap brush is the first one. */
pipe->current = pipe->brushes[0];
pipe->brushes = g_new0 (GimpBrush *, num_of_brushes);
while (pipe->nbrushes < num_of_brushes)
{
if (pipe->nbrushes > 0)
{
pipe->brushes[pipe->nbrushes] =
GIMP_BRUSH_PIXMAP (gtk_type_new (GIMP_TYPE_BRUSH_PIXMAP));
pipe->brushes[pipe->nbrushes] = gimp_brush_load_brush (fd, filename);
if (pipe->brushes[pipe->nbrushes])
{
gtk_object_ref (GTK_OBJECT (pipe->brushes[pipe->nbrushes]));
gtk_object_sink (GTK_OBJECT (pipe->brushes[pipe->nbrushes]));
g_free (GIMP_BRUSH (pipe->brushes[pipe->nbrushes])->name);
GIMP_BRUSH (pipe->brushes[pipe->nbrushes])->name = NULL;
}
pipe->brushes[pipe->nbrushes]->pipe = pipe;
/* load the brush */
if (!gimp_brush_load_brush (GIMP_BRUSH (pipe->brushes[pipe->nbrushes]),
fp, filename))
else
{
g_message (_("Failed to load one of the brushes in the brush pipe."));
pattern_free (pattern);
g_message (_("Failed to load one of the brushes in the brush pipe\n\"%s\""),
filename);
close (fd);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (!pattern_load (pattern, fp, filename))
{
g_message (_("Failed to load one of the brushes in the brush pipe."));
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (pipe->nbrushes == 0)
{
/* Replace name with the whole pipe's name */
g_free (GIMP_BRUSH (pipe)->name);
GIMP_BRUSH (pipe)->name = name;
}
pipe->brushes[pipe->nbrushes]->pixmap_mask = pattern->mask;
pattern->mask = NULL; /* #8150: mask now belongs to pixmap */
g_free (pattern->name);
pattern->name = NULL; /* #8150: name no longer exists */
pipe->nbrushes++;
}
/* Clean up */
fclose (fp);
g_free (pattern);
return pipe;
}
GimpBrushPipe *
gimp_brush_pixmap_load (gchar *filename)
{
GimpBrushPipe *pipe;
GPattern *pattern;
FILE *fp;
if ((fp = fopen (filename, "rb")) == NULL)
return NULL;
pipe = GIMP_BRUSH_PIPE (gtk_type_new (GIMP_TYPE_BRUSH_PIPE));
/* A (single) pixmap brush is a pixmap pipe brush with just one pixmap */
pipe->dimension = 1;
pipe->rank = g_new (gint, 1);
pipe->rank[0] = 1;
pipe->select = g_new (PipeSelectModes, 1);
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
pipe->index = g_new (gint, 1);
pipe->index[0] = 0;
pattern = g_new0 (GPattern, 1);
pipe->brushes = g_new (GimpBrushPixmap *, 1);
pipe->brushes[0] = GIMP_BRUSH_PIXMAP (pipe);
/* Current brush is the first one. */
pipe->current = pipe->brushes[0];
pipe->brushes[0]->pipe = pipe;
/* just to satisfy the code that relies on this crap */
/* load the brush */
if (!gimp_brush_load_brush (GIMP_BRUSH (pipe->brushes[0]),
fp, filename))
{
g_message (_("Failed to load pixmap brush."));
pattern_free (pattern);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (!pattern_load (pattern, fp, filename))
{
g_message (_("Failed to load pixmap brush."));
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
pipe->brushes[0]->pixmap_mask = pattern->mask;
pipe->nbrushes = 1;
/* Clean up */
fclose (fp);
g_free (pattern->name);
g_free (pattern);
return pipe;
}
TempBuf *
gimp_brush_pixmap_pixmap (GimpBrushPixmap *brush)
{
g_return_val_if_fail (brush != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (brush), NULL);
return brush->pixmap_mask;
GIMP_BRUSH (pipe)->mask = pipe->brushes[0]->mask;
GIMP_BRUSH (pipe)->pixmap = pipe->brushes[0]->pixmap;
close (fd);
return GIMP_BRUSH (pipe);
}

View File

@ -19,11 +19,25 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#include <gtk/gtk.h>
#include "apptypes.h"
@ -33,7 +47,6 @@
#include "patterns.h"
#include "gimpbrush.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "paint_core.h"
#include "gimprc.h"
@ -43,87 +56,25 @@
#include "libgimp/gimpintl.h"
static GimpBrushClass *gimp_brush_class;
static GimpBrushPixmapClass *gimp_brush_pixmap_class;
static GimpBrushClass *parent_class;
static GimpBrush *gimp_brush_pixmap_select_brush (PaintCore *paint_core);
static gboolean gimp_brush_pixmap_want_null_motion (PaintCore *paint_core);
static void
gimp_brush_pixmap_destroy (GtkObject *object)
{
GimpBrushPixmap *pixmap;
static GimpBrush * gimp_brush_pipe_select_brush (PaintCore *paint_core);
static gboolean gimp_brush_pipe_want_null_motion (PaintCore *paint_core);
static void gimp_brush_pipe_destroy (GtkObject *object);
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_BRUSH_PIXMAP (object));
pixmap = GIMP_BRUSH_PIXMAP (object);
if (pixmap->pixmap_mask)
temp_buf_free (pixmap->pixmap_mask);
if (GTK_OBJECT_CLASS (gimp_brush_class)->destroy)
GTK_OBJECT_CLASS (gimp_brush_class)->destroy (object);
}
static void
gimp_brush_pixmap_class_init (GimpBrushPixmapClass *klass)
{
GtkObjectClass *object_class;
GimpBrushClass *brush_class;
object_class = GTK_OBJECT_CLASS (klass);
brush_class = GIMP_BRUSH_CLASS (klass);
gimp_brush_class = gtk_type_class (gimp_brush_get_type ());
object_class->destroy = gimp_brush_pixmap_destroy;
brush_class->select_brush = gimp_brush_pixmap_select_brush;
brush_class->want_null_motion = gimp_brush_pixmap_want_null_motion;
}
void
gimp_brush_pixmap_init (GimpBrushPixmap *brush)
{
brush->pixmap_mask = NULL;
brush->pipe = NULL;
}
GtkType
gimp_brush_pixmap_get_type (void)
{
static GtkType type = 0;
if (!type)
{
GtkTypeInfo info =
{
"GimpBrushPixmap",
sizeof (GimpBrushPixmap),
sizeof (GimpBrushPixmapClass),
(GtkClassInitFunc) gimp_brush_pixmap_class_init,
(GtkObjectInitFunc) gimp_brush_pixmap_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (GIMP_TYPE_BRUSH, &info);
}
return type;
}
static GimpBrush *
gimp_brush_pixmap_select_brush (PaintCore *paint_core)
gimp_brush_pipe_select_brush (PaintCore *paint_core)
{
GimpBrushPipe *pipe;
int i, brushix, ix;
double angle;
gint i, brushix, ix;
gdouble angle;
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), NULL);
g_return_val_if_fail (paint_core != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH_PIPE (paint_core->brush), NULL);
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
pipe = GIMP_BRUSH_PIPE (paint_core->brush);
if (pipe->nbrushes == 1)
return GIMP_BRUSH (pipe->current);
@ -168,7 +119,6 @@ gimp_brush_pixmap_select_brush (PaintCore *paint_core)
}
pipe->index[i] = CLAMP (ix, 0, pipe->rank[i]-1);
brushix += pipe->stride[i] * pipe->index[i];
/* g_print ("ix at %d: %d, brushix: %d\n", i, ix, brushix); */
}
/* Make sure is inside bounds */
@ -180,14 +130,15 @@ gimp_brush_pixmap_select_brush (PaintCore *paint_core)
}
static gboolean
gimp_brush_pixmap_want_null_motion (PaintCore *paint_core)
gimp_brush_pipe_want_null_motion (PaintCore *paint_core)
{
GimpBrushPipe *pipe;
gint i;
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), TRUE);
g_return_val_if_fail (paint_core != NULL, TRUE);
g_return_val_if_fail (GIMP_IS_BRUSH_PIPE (paint_core->brush), TRUE);
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
pipe = GIMP_BRUSH_PIPE (paint_core->brush);
if (pipe->nbrushes == 1)
return TRUE;
@ -221,18 +172,24 @@ gimp_brush_pipe_destroy (GtkObject *object)
g_free (pipe->select);
g_free (pipe->index);
if (GTK_OBJECT_CLASS (gimp_brush_pixmap_class)->destroy)
GTK_OBJECT_CLASS (gimp_brush_pixmap_class)->destroy (object);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
gimp_brush_pipe_class_init (GimpBrushPipeClass *klass)
{
GtkObjectClass *object_class;
GimpBrushClass *brush_class;
object_class = GTK_OBJECT_CLASS (klass);
brush_class = GIMP_BRUSH_CLASS (klass);
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
brush_class->select_brush = gimp_brush_pipe_select_brush;
brush_class->want_null_motion = gimp_brush_pipe_want_null_motion;
gimp_brush_pixmap_class = gtk_type_class (GIMP_TYPE_BRUSH_PIXMAP);
object_class->destroy = gimp_brush_pipe_destroy;
}
@ -268,55 +225,75 @@ gimp_brush_pipe_get_type (void)
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (GIMP_TYPE_BRUSH_PIXMAP, &info);
type = gtk_type_unique (GIMP_TYPE_BRUSH, &info);
}
return type;
}
GimpBrushPipe *
#include <errno.h>
GimpBrush *
gimp_brush_pipe_load (gchar *filename)
{
GimpBrushPipe *pipe;
GPattern *pattern;
GimpBrushPipe *pipe = NULL;
GimpPixPipeParams params;
FILE *fp;
gchar buf[1024];
gchar *name;
gint i;
gint num_of_brushes;
gint num_of_brushes = 0;
gint totalcells;
gchar *paramstring;
GString *buffer;
gchar c;
gint fd;
if ((fp = fopen (filename, "rb")) == NULL)
return NULL;
g_return_val_if_fail (filename != NULL, NULL);
/* The file format starts with a painfully simple text header
* and we use a painfully simple way to read it
*/
if (fgets (buf, 1024, fp) == NULL)
fd = open (filename, O_RDONLY | _O_BINARY);
if (fd == -1)
{
fclose (fp);
g_message ("Couldn't open file '%s'", filename);
return NULL;
}
buf[strlen (buf) - 1] = 0;
/* The file format starts with a painfully simple text header */
/* get the name */
buffer = g_string_new (NULL);
while (read (fd, &c, 1) == 1 && c != '\n' && buffer->len < 1024)
g_string_append_c (buffer, c);
if (buffer->len > 0 && buffer->len < 1024)
{
pipe = GIMP_BRUSH_PIPE (gtk_type_new (GIMP_TYPE_BRUSH_PIPE));
name = g_strdup (buf);
GIMP_BRUSH (pipe)->name = buffer->str;
}
g_string_free (buffer, FALSE);
if (!pipe)
{
g_message ("Couldn't read name for brush pipe from file '%s'\n",
filename);
close (fd);
return NULL;
}
/* get the number of brushes */
if (fgets (buf, 1024, fp) == NULL)
buffer = g_string_new (NULL);
while (read (fd, &c, 1) == 1 && c != '\n' && buffer->len < 1024)
g_string_append_c (buffer, c);
if (buffer->len > 0 && buffer->len < 1024)
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
num_of_brushes = strtol (buffer->str, &paramstring, 10);
}
num_of_brushes = strtol (buf, &paramstring, 10);
if (num_of_brushes < 1)
{
g_message (_("Brush pipes should have at least one brush."));
fclose (fp);
g_message (_("Brush pipes should have at least one brush:\n\"%s\""),
filename);
close (fd);
gtk_object_sink (GTK_OBJECT (pipe));
g_string_free (buffer, TRUE);
return NULL;
}
@ -372,6 +349,8 @@ gimp_brush_pipe_load (gchar *filename)
pipe->index[0] = 0;
}
g_string_free (buffer, TRUE);
totalcells = 1; /* Not all necessarily present, maybe */
for (i = 0; i < pipe->dimension; i++)
totalcells *= pipe->rank[i];
@ -385,136 +364,41 @@ gimp_brush_pipe_load (gchar *filename)
}
g_assert (pipe->stride[pipe->dimension-1] == 1);
pattern = g_new0 (GPattern, 1);
pipe->brushes = g_new0 (GimpBrushPixmap *, num_of_brushes);
/* First pixmap brush in the list is the pipe itself */
pipe->brushes[0] = GIMP_BRUSH_PIXMAP (pipe);
/* Current pixmap brush is the first one. */
pipe->current = pipe->brushes[0];
pipe->brushes = g_new0 (GimpBrush *, num_of_brushes);
while (pipe->nbrushes < num_of_brushes)
{
if (pipe->nbrushes > 0)
{
pipe->brushes[pipe->nbrushes] =
GIMP_BRUSH_PIXMAP (gtk_type_new (GIMP_TYPE_BRUSH_PIXMAP));
pipe->brushes[pipe->nbrushes] = gimp_brush_load_brush (fd, filename);
if (pipe->brushes[pipe->nbrushes])
{
gtk_object_ref (GTK_OBJECT (pipe->brushes[pipe->nbrushes]));
gtk_object_sink (GTK_OBJECT (pipe->brushes[pipe->nbrushes]));
g_free (GIMP_BRUSH (pipe->brushes[pipe->nbrushes])->name);
GIMP_BRUSH (pipe->brushes[pipe->nbrushes])->name = NULL;
}
pipe->brushes[pipe->nbrushes]->pipe = pipe;
/* load the brush */
if (!gimp_brush_load_brush (GIMP_BRUSH (pipe->brushes[pipe->nbrushes]),
fp, filename))
else
{
g_message (_("Failed to load one of the brushes in the brush pipe."));
pattern_free (pattern);
g_message (_("Failed to load one of the brushes in the brush pipe\n\"%s\""),
filename);
close (fd);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (!pattern_load (pattern, fp, filename))
{
g_message (_("Failed to load one of the brushes in the brush pipe."));
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (pipe->nbrushes == 0)
{
/* Replace name with the whole pipe's name */
g_free (GIMP_BRUSH (pipe)->name);
GIMP_BRUSH (pipe)->name = name;
}
pipe->brushes[pipe->nbrushes]->pixmap_mask = pattern->mask;
pattern->mask = NULL; /* #8150: mask now belongs to pixmap */
g_free (pattern->name);
pattern->name = NULL; /* #8150: name no longer exists */
pipe->nbrushes++;
}
/* Clean up */
fclose (fp);
g_free (pattern);
return pipe;
}
GimpBrushPipe *
gimp_brush_pixmap_load (gchar *filename)
{
GimpBrushPipe *pipe;
GPattern *pattern;
FILE *fp;
if ((fp = fopen (filename, "rb")) == NULL)
return NULL;
pipe = GIMP_BRUSH_PIPE (gtk_type_new (GIMP_TYPE_BRUSH_PIPE));
/* A (single) pixmap brush is a pixmap pipe brush with just one pixmap */
pipe->dimension = 1;
pipe->rank = g_new (gint, 1);
pipe->rank[0] = 1;
pipe->select = g_new (PipeSelectModes, 1);
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
pipe->index = g_new (gint, 1);
pipe->index[0] = 0;
pattern = g_new0 (GPattern, 1);
pipe->brushes = g_new (GimpBrushPixmap *, 1);
pipe->brushes[0] = GIMP_BRUSH_PIXMAP (pipe);
/* Current brush is the first one. */
pipe->current = pipe->brushes[0];
pipe->brushes[0]->pipe = pipe;
/* just to satisfy the code that relies on this crap */
/* load the brush */
if (!gimp_brush_load_brush (GIMP_BRUSH (pipe->brushes[0]),
fp, filename))
{
g_message (_("Failed to load pixmap brush."));
pattern_free (pattern);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (!pattern_load (pattern, fp, filename))
{
g_message (_("Failed to load pixmap brush."));
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
pipe->brushes[0]->pixmap_mask = pattern->mask;
pipe->nbrushes = 1;
/* Clean up */
fclose (fp);
g_free (pattern->name);
g_free (pattern);
return pipe;
}
TempBuf *
gimp_brush_pixmap_pixmap (GimpBrushPixmap *brush)
{
g_return_val_if_fail (brush != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (brush), NULL);
return brush->pixmap_mask;
GIMP_BRUSH (pipe)->mask = pipe->brushes[0]->mask;
GIMP_BRUSH (pipe)->pixmap = pipe->brushes[0]->pixmap;
close (fd);
return GIMP_BRUSH (pipe);
}

View File

@ -27,33 +27,59 @@
#include "temp_buf.h"
typedef struct _GimpBrushPixmap GimpBrushPixmap;
typedef struct _GimpBrushPipe GimpBrushPipe;
#define GIMP_TYPE_BRUSH_PIXMAP (gimp_brush_pixmap_get_type ())
#define GIMP_BRUSH_PIXMAP(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PIXMAP, GimpBrushPixmap))
#define GIMP_IS_BRUSH_PIXMAP(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_PIXMAP))
#define GIMP_TYPE_BRUSH_PIPE (gimp_brush_pipe_get_type ())
#define GIMP_BRUSH_PIPE(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PIPE, GimpBrushPipe))
#define GIMP_IS_BRUSH_PIPE(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_PIPE))
typedef enum
{
PIPE_SELECT_CONSTANT,
PIPE_SELECT_INCREMENTAL,
PIPE_SELECT_ANGULAR,
PIPE_SELECT_VELOCITY,
PIPE_SELECT_RANDOM,
PIPE_SELECT_PRESSURE,
PIPE_SELECT_TILT_X,
PIPE_SELECT_TILT_Y
} PipeSelectModes;
struct _GimpBrushPipe
{
GimpBrush gbrush; /* Also itself a brush */
gint dimension;
gint *rank; /* Size in each dimension */
gint *stride; /* Aux for indexing */
PipeSelectModes *select; /* One mode per dimension */
gint *index; /* Current index for incremental dimensions */
gint nbrushes; /* Might be less than the product of the
* ranks in some odd special case */
GimpBrush **brushes;
GimpBrush *current; /* Currently selected brush */
};
typedef struct _GimpBrushPipeClass GimpBrushPipeClass;
struct _GimpBrushPipeClass
{
GimpBrushClass parent_class;
};
GtkType gimp_brush_pixmap_get_type (void);
GtkType gimp_brush_pipe_get_type (void);
GimpBrushPipe * gimp_brush_pipe_load (gchar *filename);
GimpBrushPipe * gimp_brush_pixmap_load (gchar *filename);
TempBuf * gimp_brush_pixmap_pixmap (GimpBrushPixmap *brush);
/* appearantly GIMP_IS_BRUSH_PIPE () returning TRUE is no indication
* that you really have a brush_pipe in front of you, so here we introduce
* a macro that works:
*/
#define GIMP_IS_REALLY_A_BRUSH_PIPE(obj) (GIMP_IS_BRUSH_PIPE (obj) && GIMP_BRUSH_PIPE (obj)->nbrushes > 1)
GimpBrush * gimp_brush_pipe_load (gchar *filename);
#endif /* __GIMP_BRUSH_PIPE_H__ */

View File

@ -25,6 +25,7 @@
#include <gtk/gtk.h>
#include "gimpdrawableP.h"
#include "gimppreviewcache.h"
#include "gimpsignal.h"
#include "gimage.h"
#include "gimage_mask.h"

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -26,7 +26,7 @@
#include "gimpobject.h"
#include "gimpsignal.h"
#include "gimplistP.h"
#include "gimplist.h"
/* code mostly ripped from nether's gimpset class */

View File

@ -20,6 +20,8 @@
#define __GIMP_LIST_H__
#include "gimpobject.h"
/* GimpList - a typed list of objects with signals for adding and
* removing of stuff. If it is weak, destroyed objects get removed
* automatically. If it is not, it refs them so they won't be freed
@ -30,6 +32,25 @@
#define GIMP_TYPE_LIST gimp_list_get_type ()
#define GIMP_LIST(obj) GTK_CHECK_CAST (obj, GIMP_TYPE_LIST, GimpList)
#define GIMP_IS_LIST(obj) GTK_CHECK_TYPE (obj, gimp_list_get_type())
#define GIMP_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_list_get_type(), GimpListClass)
struct _GimpList
{
GimpObject gobject;
GtkType type;
GSList* list;
gboolean weak;
};
struct _GimpListClass
{
GimpObjectClass parent_class;
void (* add) (GimpList *list, void *data);
void (* remove) (GimpList *list, void *data);
};
typedef struct _GimpListClass GimpListClass;
/* Signals:

View File

@ -23,7 +23,6 @@
#include "apptypes.h"
#include "gimpobject.h"
#include "gimpobjectP.h"
static void

View File

@ -20,12 +20,36 @@
#define __GIMP_OBJECT_H__
#include <gtk/gtktypeutils.h>
#include <gtk/gtk.h>
#define GIMP_TYPE_OBJECT gimp_object_get_type ()
#define GIMP_OBJECT(obj) GTK_CHECK_CAST (obj, GIMP_TYPE_OBJECT, GimpObject)
#define GIMP_IS_OBJECT(obj) GTK_CHECK_TYPE (obj, GIMP_TYPE_OBJECT)
#define GIMP_OBJECT_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, GIMP_TYPE_OBJECT, GimpObjectClass)
struct _GimpObject
{
GtkObject object;
};
typedef struct
{
GtkObjectClass parent_class;
} GimpObjectClass;
#define GIMP_TYPE_INIT(typevar, obtype, classtype, obinit, classinit, parent) \
if(!typevar){ \
GtkTypeInfo _info={#obtype, \
sizeof(obtype), \
sizeof(classtype), \
(GtkClassInitFunc)classinit, \
(GtkObjectInitFunc)obinit, \
NULL, NULL, NULL}; \
typevar=gtk_type_unique(parent, &_info); \
}
GtkType gimp_object_get_type (void);

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -24,6 +24,8 @@
#include "dialog_handler.h"
#include "docindex.h"
#include "fileops.h"
#include "gdisplay.h"
#include "gimpimageP.h"
#include "gimpui.h"
#include "gimpdnd.h"
#include "ops_buttons.h"

View File

@ -22,15 +22,41 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#include <gtk/gtk.h>
#include <stdio.h>
#include "apptypes.h"
#include "libgimp/gimpvector.h"
#include "brush_header.h"
#include "pattern_header.h"
#include "gimpbrush.h"
#include "gimpbrushlist.h"
#include "gimpsignal.h"
#include "gimprc.h"
#include "brush_header.h"
#include "config.h"
#include "paint_core.h"
#include "temp_buf.h"
#include "libgimp/gimpintl.h"
enum
@ -93,12 +119,15 @@ gimp_brush_init (GimpBrush *brush)
{
brush->filename = NULL;
brush->name = NULL;
brush->spacing = 20;
brush->mask = NULL;
brush->x_axis.x = 15.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = 15.0;
brush->mask = NULL;
brush->pixmap = NULL;
}
@ -127,14 +156,32 @@ gimp_brush_get_type (void)
}
GimpBrush *
gimp_brush_new (gchar *filename)
gimp_brush_load (gchar *filename)
{
GimpBrush *brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
GimpBrush *brush;
gint fd;
if (gimp_brush_load (brush, filename))
return brush;
g_return_val_if_fail (filename != NULL, NULL);
fd = open (filename, O_RDONLY | _O_BINARY);
if (fd == -1)
return NULL;
brush = gimp_brush_load_brush (fd, filename);
close (fd);
brush->filename = g_strdup (filename);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
{
temp_buf_swap (brush->mask);
if (brush->pixmap)
temp_buf_swap (brush->pixmap);
}
return brush;
}
static GimpBrush *
@ -158,6 +205,15 @@ gimp_brush_get_mask (GimpBrush *brush)
return brush->mask;
}
TempBuf *
gimp_brush_get_pixmap (GimpBrush *brush)
{
g_return_val_if_fail (brush != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
return brush->pixmap;
}
gchar *
gimp_brush_get_name (GimpBrush *brush)
{
@ -203,125 +259,145 @@ gimp_brush_set_spacing (GimpBrush *brush,
brush->spacing = spacing;
}
gboolean
gimp_brush_load (GimpBrush *brush,
gchar *filename)
{
FILE *fp;
brush->filename = g_strdup (filename);
/* Open the requested file */
if (! (fp = fopen (filename, "rb")))
{
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
if (! gimp_brush_load_brush (brush, fp, filename))
{
return FALSE;
}
/* Clean up */
fclose (fp);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
return TRUE;
}
gboolean
gimp_brush_load_brush (GimpBrush *brush,
FILE *fp,
GimpBrush *
gimp_brush_load_brush (gint fd,
gchar *filename)
{
GimpBrush *brush;
GPattern *pattern;
gint bn_size;
guchar buf [sizeof (BrushHeader)];
BrushHeader header;
guint *hp;
gchar *name;
gint i;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (fd != -1, NULL);
/* Read in the header size */
if ((fread (buf, 1, sizeof (BrushHeader), fp)) < sizeof (BrushHeader))
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
if (read (fd, &header, sizeof (header)) != sizeof (header))
return NULL;
/* rearrange the bytes in each unsigned int */
hp = (guint *) &header;
for (i = 0; i < (sizeof (BrushHeader) / 4); i++)
hp [i] = ((buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]));
header.header_size = g_ntohl (header.header_size);
header.version = g_ntohl (header.version);
header.width = g_ntohl (header.width);
header.height = g_ntohl (header.height);
header.bytes = g_ntohl (header.bytes);
header.magic_number = g_ntohl (header.magic_number);
header.spacing = g_ntohl (header.spacing);
/* Check for correct file format */
if (header.magic_number != GBRUSH_MAGIC)
/* It looks as if version 1 did not have the same magic number. (neo) */
if (header.version != 1 &&
(header.magic_number != GBRUSH_MAGIC || header.version != 2))
{
if (header.version != 1)
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
g_message (_("Unknown brush format version #%d in \"%s\"."),
header.version, filename);
return NULL;
}
if (header.version == 1)
{
/* If this is a version 1 brush, set the fp back 8 bytes */
fseek (fp, -8, SEEK_CUR);
lseek (fd, -8, SEEK_CUR);
header.header_size += 8;
/* spacing is not defined in version 1 */
header.spacing = 25;
}
/* Read in the brush name */
if ((bn_size = (header.header_size - sizeof (BrushHeader))))
if ((bn_size = (header.header_size - sizeof (header))))
{
brush->name = g_new (gchar, bn_size);
if ((fread (brush->name, 1, bn_size, fp)) < bn_size)
name = g_new (gchar, bn_size);
if ((read (fd, name, bn_size)) < bn_size)
{
g_message (_("Error in GIMP brush file...aborting."));
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
g_message (_("Error in GIMP brush file \"%s\"."), filename);
g_free (name);
return NULL;
}
}
else
{
brush->name = g_strdup (_("Unnamed"));
name = g_strdup (_("Unnamed"));
}
switch (header.version)
switch (header.bytes)
{
case 1:
case 2:
/* Get a new brush mask */
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
brush->mask = temp_buf_new (header.width, header.height, 1,
0, 0, NULL);
if (read (fd,
temp_buf_data (brush->mask), header.width * header.height) <
header.width * header.height)
{
g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
/* For backwards-compatibility, check if a pattern follows.
The obsolete .gpb format did it this way. */
pattern = pattern_load (fd, filename);
if (pattern)
{
if (pattern->mask && pattern->mask->bytes == 3)
{
brush->pixmap = pattern->mask;
pattern->mask = NULL;
}
pattern_free (pattern);
}
else
{
/* rewind to make brush pipe loader happy */
if (lseek (fd, - sizeof (PatternHeader), SEEK_CUR) < 0)
{
g_message (_("GIMP brush file appears to be corrupted: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
}
break;
case 4:
brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
brush->mask = temp_buf_new (header.width, header.height, 1, 0, 0, NULL);
brush->pixmap = temp_buf_new (header.width, header.height, 3, 0, 0, NULL);
for (i = 0; i < header.width * header.height; i++)
{
if (read (fd, temp_buf_data (brush->pixmap)
+ i * 3, 3) != 3 ||
read (fd, temp_buf_data (brush->mask) + i, 1) != 1)
{
g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
filename);
g_free (name);
gtk_object_unref (GTK_OBJECT (brush));
return NULL;
}
}
break;
default:
g_message ("Unsupported brush depth: %d\n in file \"%s\"\nGIMP Brushes must be GRAY or RGBA\n",
header.bytes, filename);
g_free (name);
return NULL;
}
brush->name = name;
brush->spacing = header.spacing;
/* set up spacing axis */
brush->x_axis.x = header.width / 2.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = header.height / 2.0;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask),
1, header.width * header.height, fp)) <
header.width * header.height)
g_message (_("GIMP brush file appears to be truncated."));
break;
default:
g_message (_("Unknown brush format version #%d in \"%s\"\n"),
header.version, filename);
fclose (fp);
gtk_object_sink (GTK_OBJECT (brush));
return FALSE;
}
return TRUE;
return brush;
}

View File

@ -20,15 +20,12 @@
#define __GIMP_BRUSH_H__
#include <stdio.h>
#include "apptypes.h"
#include "gimpobjectP.h"
#include "paint_core.h"
#include "gimpobject.h"
#include "temp_buf.h"
#include "libgimp/gimpvector.h"
typedef struct _GimpBrushClass GimpBrushClass;
struct _GimpBrush
@ -40,7 +37,8 @@ struct _GimpBrush
gint spacing; /* brush's spacing */
GimpVector2 x_axis; /* for calculating brush spacing */
GimpVector2 y_axis; /* for calculating brush spacing */
TempBuf *mask; /* the actual mask... */
TempBuf *mask; /* the actual mask */
TempBuf *pixmap; /* optional pixmap data */
};
struct _GimpBrushClass
@ -57,15 +55,13 @@ struct _GimpBrushClass
#define GIMP_IS_BRUSH(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH))
GtkType gimp_brush_get_type (void);
GimpBrush * gimp_brush_new (gchar *filename);
GimpBrush * gimp_brush_load (gchar *filename);
gboolean gimp_brush_load (GimpBrush *brush,
gchar *filename);
gboolean gimp_brush_load_brush (GimpBrush *brush,
FILE *fp,
GimpBrush * gimp_brush_load_brush (gint fd,
gchar *filename);
TempBuf * gimp_brush_get_mask (GimpBrush *brush);
TempBuf * gimp_brush_get_pixmap (GimpBrush *brush);
gchar * gimp_brush_get_name (GimpBrush *brush);
void gimp_brush_set_name (GimpBrush *brush,

View File

@ -102,7 +102,7 @@ gimp_brush_generated_get_type (void)
return type;
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_new (gfloat radius,
gfloat hardness,
gfloat angle,
@ -126,10 +126,10 @@ gimp_brush_generated_new (gfloat radius,
/* render brush mask */
gimp_brush_generated_generate (brush);
return brush;
return GIMP_BRUSH (brush);
}
GimpBrushGenerated *
GimpBrush *
gimp_brush_generated_load (const gchar *file_name)
{
GimpBrushGenerated *brush;
@ -193,7 +193,7 @@ gimp_brush_generated_load (const gchar *file_name)
if (stingy_memory_use)
temp_buf_swap (GIMP_BRUSH (brush)->mask);
return brush;
return GIMP_BRUSH (brush);
}
void

View File

@ -53,11 +53,11 @@ struct _GimpBrushGeneratedClass
GtkType gimp_brush_generated_get_type (void);
GimpBrushGenerated * gimp_brush_generated_new (gfloat radius,
GimpBrush * gimp_brush_generated_new (gfloat radius,
gfloat hardness,
gfloat angle,
gfloat aspect_ratio);
GimpBrushGenerated * gimp_brush_generated_load (const gchar *file_name);
GimpBrush * gimp_brush_generated_load (const gchar *file_name);
void gimp_brush_generated_save (GimpBrushGenerated *brush,
const gchar *file_name);

View File

@ -46,8 +46,7 @@
#include "gimpsignal.h"
#include "gimplist.h"
#include "gimpbrush.h"
#include "gimplistP.h"
#include "gimpbrushlistP.h"
#include "gimpbrushlist.h"
#include "libgimp/gimpenv.h"
@ -187,12 +186,13 @@ brushes_get_standard_brush (void)
static void
brushes_brush_load (gchar *filename)
{
if (strcmp (&filename[strlen (filename) - 4], ".gbr") == 0)
{
GimpBrush *brush;
brush = gimp_brush_new (filename);
if (strcmp (&filename[strlen (filename) - 4], ".gbr") == 0 ||
strcmp (&filename[strlen (filename) - 4], ".gpb") == 0)
{
brush = gimp_brush_load (filename);
if (brush != NULL)
gimp_brush_list_add (brush_list, brush);
@ -201,8 +201,6 @@ brushes_brush_load (gchar *filename)
}
else if (strcmp (&filename[strlen(filename) - 4], ".vbr") == 0)
{
GimpBrushGenerated *brush;
brush = gimp_brush_generated_load (filename);
if (brush != NULL)
@ -210,27 +208,14 @@ brushes_brush_load (gchar *filename)
else
g_message (_("Warning: Failed to load brush\n\"%s\""), filename);
}
else if (strcmp (&filename[strlen (filename) - 4], ".gpb") == 0)
{
GimpBrushPipe *brush;
brush = gimp_brush_pixmap_load (filename);
if (brush != NULL)
gimp_brush_list_add (brush_list, GIMP_BRUSH (brush));
else
g_message (_("Warning: Failed to load pixmap brush\n\"%s\""), filename);
}
else if (strcmp (&filename[strlen (filename) - 4], ".gih") == 0)
{
GimpBrushPipe *brush;
brush = gimp_brush_pipe_load (filename);
if (brush != NULL)
gimp_brush_list_add (brush_list, GIMP_BRUSH (brush));
else
g_message (_("Warning: Failed to load pixmap pipe\n\"%s\""), filename);
g_message (_("Warning: Failed to load brush pipe\n\"%s\""), filename);
}
}

View File

@ -20,12 +20,26 @@
#define __GIMP_BRUSH_LIST_H__
#include "gimpbrush.h"
#include "gimplist.h"
#define GIMP_TYPE_BRUSH_LIST (gimp_brush_list_get_type ())
#define GIMP_BRUSH_LIST(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_LIST, GimpBrushList))
#define GIMP_IS_BRUSH_LIST(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_LIST))
#define GIMP_BRUSH_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, gimp_brush_list_get_type(), GimpBrushListClass))
struct _GimpBrushList
{
GimpList gimplist;
gint num_brushes;
};
typedef struct _GimpBrushListClass GimpBrushListClass;
struct _GimpBrushListClass
{
GimpListClass parent_class;
};
/* global variables */

View File

@ -1,24 +0,0 @@
#ifndef __GIMPBRUSHLISTP_H__
#define __GIMPBRUSHLISTP_H__
#include "gimplistP.h"
#include "gimpbrushlist.h"
struct _GimpBrushList
{
GimpList gimplist;
gint num_brushes;
};
typedef struct _GimpBrushListClass GimpBrushListClass;
struct _GimpBrushListClass
{
GimpListClass parent_class;
};
#define BRUSH_LIST_CLASS(klass) \
GTK_CHECK_CLASS_CAST (klass, gimp_brush_list_get_type(), GimpBrushListClass)
#endif /* __GIMPBRUSHLISTP_H__ */

View File

@ -19,11 +19,25 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#include <gtk/gtk.h>
#include "apptypes.h"
@ -33,7 +47,6 @@
#include "patterns.h"
#include "gimpbrush.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "paint_core.h"
#include "gimprc.h"
@ -43,87 +56,25 @@
#include "libgimp/gimpintl.h"
static GimpBrushClass *gimp_brush_class;
static GimpBrushPixmapClass *gimp_brush_pixmap_class;
static GimpBrushClass *parent_class;
static GimpBrush *gimp_brush_pixmap_select_brush (PaintCore *paint_core);
static gboolean gimp_brush_pixmap_want_null_motion (PaintCore *paint_core);
static void
gimp_brush_pixmap_destroy (GtkObject *object)
{
GimpBrushPixmap *pixmap;
static GimpBrush * gimp_brush_pipe_select_brush (PaintCore *paint_core);
static gboolean gimp_brush_pipe_want_null_motion (PaintCore *paint_core);
static void gimp_brush_pipe_destroy (GtkObject *object);
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_BRUSH_PIXMAP (object));
pixmap = GIMP_BRUSH_PIXMAP (object);
if (pixmap->pixmap_mask)
temp_buf_free (pixmap->pixmap_mask);
if (GTK_OBJECT_CLASS (gimp_brush_class)->destroy)
GTK_OBJECT_CLASS (gimp_brush_class)->destroy (object);
}
static void
gimp_brush_pixmap_class_init (GimpBrushPixmapClass *klass)
{
GtkObjectClass *object_class;
GimpBrushClass *brush_class;
object_class = GTK_OBJECT_CLASS (klass);
brush_class = GIMP_BRUSH_CLASS (klass);
gimp_brush_class = gtk_type_class (gimp_brush_get_type ());
object_class->destroy = gimp_brush_pixmap_destroy;
brush_class->select_brush = gimp_brush_pixmap_select_brush;
brush_class->want_null_motion = gimp_brush_pixmap_want_null_motion;
}
void
gimp_brush_pixmap_init (GimpBrushPixmap *brush)
{
brush->pixmap_mask = NULL;
brush->pipe = NULL;
}
GtkType
gimp_brush_pixmap_get_type (void)
{
static GtkType type = 0;
if (!type)
{
GtkTypeInfo info =
{
"GimpBrushPixmap",
sizeof (GimpBrushPixmap),
sizeof (GimpBrushPixmapClass),
(GtkClassInitFunc) gimp_brush_pixmap_class_init,
(GtkObjectInitFunc) gimp_brush_pixmap_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (GIMP_TYPE_BRUSH, &info);
}
return type;
}
static GimpBrush *
gimp_brush_pixmap_select_brush (PaintCore *paint_core)
gimp_brush_pipe_select_brush (PaintCore *paint_core)
{
GimpBrushPipe *pipe;
int i, brushix, ix;
double angle;
gint i, brushix, ix;
gdouble angle;
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), NULL);
g_return_val_if_fail (paint_core != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH_PIPE (paint_core->brush), NULL);
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
pipe = GIMP_BRUSH_PIPE (paint_core->brush);
if (pipe->nbrushes == 1)
return GIMP_BRUSH (pipe->current);
@ -168,7 +119,6 @@ gimp_brush_pixmap_select_brush (PaintCore *paint_core)
}
pipe->index[i] = CLAMP (ix, 0, pipe->rank[i]-1);
brushix += pipe->stride[i] * pipe->index[i];
/* g_print ("ix at %d: %d, brushix: %d\n", i, ix, brushix); */
}
/* Make sure is inside bounds */
@ -180,14 +130,15 @@ gimp_brush_pixmap_select_brush (PaintCore *paint_core)
}
static gboolean
gimp_brush_pixmap_want_null_motion (PaintCore *paint_core)
gimp_brush_pipe_want_null_motion (PaintCore *paint_core)
{
GimpBrushPipe *pipe;
gint i;
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), TRUE);
g_return_val_if_fail (paint_core != NULL, TRUE);
g_return_val_if_fail (GIMP_IS_BRUSH_PIPE (paint_core->brush), TRUE);
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
pipe = GIMP_BRUSH_PIPE (paint_core->brush);
if (pipe->nbrushes == 1)
return TRUE;
@ -221,18 +172,24 @@ gimp_brush_pipe_destroy (GtkObject *object)
g_free (pipe->select);
g_free (pipe->index);
if (GTK_OBJECT_CLASS (gimp_brush_pixmap_class)->destroy)
GTK_OBJECT_CLASS (gimp_brush_pixmap_class)->destroy (object);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
gimp_brush_pipe_class_init (GimpBrushPipeClass *klass)
{
GtkObjectClass *object_class;
GimpBrushClass *brush_class;
object_class = GTK_OBJECT_CLASS (klass);
brush_class = GIMP_BRUSH_CLASS (klass);
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
brush_class->select_brush = gimp_brush_pipe_select_brush;
brush_class->want_null_motion = gimp_brush_pipe_want_null_motion;
gimp_brush_pixmap_class = gtk_type_class (GIMP_TYPE_BRUSH_PIXMAP);
object_class->destroy = gimp_brush_pipe_destroy;
}
@ -268,55 +225,75 @@ gimp_brush_pipe_get_type (void)
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (GIMP_TYPE_BRUSH_PIXMAP, &info);
type = gtk_type_unique (GIMP_TYPE_BRUSH, &info);
}
return type;
}
GimpBrushPipe *
#include <errno.h>
GimpBrush *
gimp_brush_pipe_load (gchar *filename)
{
GimpBrushPipe *pipe;
GPattern *pattern;
GimpBrushPipe *pipe = NULL;
GimpPixPipeParams params;
FILE *fp;
gchar buf[1024];
gchar *name;
gint i;
gint num_of_brushes;
gint num_of_brushes = 0;
gint totalcells;
gchar *paramstring;
GString *buffer;
gchar c;
gint fd;
if ((fp = fopen (filename, "rb")) == NULL)
return NULL;
g_return_val_if_fail (filename != NULL, NULL);
/* The file format starts with a painfully simple text header
* and we use a painfully simple way to read it
*/
if (fgets (buf, 1024, fp) == NULL)
fd = open (filename, O_RDONLY | _O_BINARY);
if (fd == -1)
{
fclose (fp);
g_message ("Couldn't open file '%s'", filename);
return NULL;
}
buf[strlen (buf) - 1] = 0;
/* The file format starts with a painfully simple text header */
/* get the name */
buffer = g_string_new (NULL);
while (read (fd, &c, 1) == 1 && c != '\n' && buffer->len < 1024)
g_string_append_c (buffer, c);
if (buffer->len > 0 && buffer->len < 1024)
{
pipe = GIMP_BRUSH_PIPE (gtk_type_new (GIMP_TYPE_BRUSH_PIPE));
name = g_strdup (buf);
GIMP_BRUSH (pipe)->name = buffer->str;
}
g_string_free (buffer, FALSE);
if (!pipe)
{
g_message ("Couldn't read name for brush pipe from file '%s'\n",
filename);
close (fd);
return NULL;
}
/* get the number of brushes */
if (fgets (buf, 1024, fp) == NULL)
buffer = g_string_new (NULL);
while (read (fd, &c, 1) == 1 && c != '\n' && buffer->len < 1024)
g_string_append_c (buffer, c);
if (buffer->len > 0 && buffer->len < 1024)
{
fclose (fp);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
num_of_brushes = strtol (buffer->str, &paramstring, 10);
}
num_of_brushes = strtol (buf, &paramstring, 10);
if (num_of_brushes < 1)
{
g_message (_("Brush pipes should have at least one brush."));
fclose (fp);
g_message (_("Brush pipes should have at least one brush:\n\"%s\""),
filename);
close (fd);
gtk_object_sink (GTK_OBJECT (pipe));
g_string_free (buffer, TRUE);
return NULL;
}
@ -372,6 +349,8 @@ gimp_brush_pipe_load (gchar *filename)
pipe->index[0] = 0;
}
g_string_free (buffer, TRUE);
totalcells = 1; /* Not all necessarily present, maybe */
for (i = 0; i < pipe->dimension; i++)
totalcells *= pipe->rank[i];
@ -385,136 +364,41 @@ gimp_brush_pipe_load (gchar *filename)
}
g_assert (pipe->stride[pipe->dimension-1] == 1);
pattern = g_new0 (GPattern, 1);
pipe->brushes = g_new0 (GimpBrushPixmap *, num_of_brushes);
/* First pixmap brush in the list is the pipe itself */
pipe->brushes[0] = GIMP_BRUSH_PIXMAP (pipe);
/* Current pixmap brush is the first one. */
pipe->current = pipe->brushes[0];
pipe->brushes = g_new0 (GimpBrush *, num_of_brushes);
while (pipe->nbrushes < num_of_brushes)
{
if (pipe->nbrushes > 0)
{
pipe->brushes[pipe->nbrushes] =
GIMP_BRUSH_PIXMAP (gtk_type_new (GIMP_TYPE_BRUSH_PIXMAP));
pipe->brushes[pipe->nbrushes] = gimp_brush_load_brush (fd, filename);
if (pipe->brushes[pipe->nbrushes])
{
gtk_object_ref (GTK_OBJECT (pipe->brushes[pipe->nbrushes]));
gtk_object_sink (GTK_OBJECT (pipe->brushes[pipe->nbrushes]));
g_free (GIMP_BRUSH (pipe->brushes[pipe->nbrushes])->name);
GIMP_BRUSH (pipe->brushes[pipe->nbrushes])->name = NULL;
}
pipe->brushes[pipe->nbrushes]->pipe = pipe;
/* load the brush */
if (!gimp_brush_load_brush (GIMP_BRUSH (pipe->brushes[pipe->nbrushes]),
fp, filename))
else
{
g_message (_("Failed to load one of the brushes in the brush pipe."));
pattern_free (pattern);
g_message (_("Failed to load one of the brushes in the brush pipe\n\"%s\""),
filename);
close (fd);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (!pattern_load (pattern, fp, filename))
{
g_message (_("Failed to load one of the brushes in the brush pipe."));
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (pipe->nbrushes == 0)
{
/* Replace name with the whole pipe's name */
g_free (GIMP_BRUSH (pipe)->name);
GIMP_BRUSH (pipe)->name = name;
}
pipe->brushes[pipe->nbrushes]->pixmap_mask = pattern->mask;
pattern->mask = NULL; /* #8150: mask now belongs to pixmap */
g_free (pattern->name);
pattern->name = NULL; /* #8150: name no longer exists */
pipe->nbrushes++;
}
/* Clean up */
fclose (fp);
g_free (pattern);
return pipe;
}
GimpBrushPipe *
gimp_brush_pixmap_load (gchar *filename)
{
GimpBrushPipe *pipe;
GPattern *pattern;
FILE *fp;
if ((fp = fopen (filename, "rb")) == NULL)
return NULL;
pipe = GIMP_BRUSH_PIPE (gtk_type_new (GIMP_TYPE_BRUSH_PIPE));
/* A (single) pixmap brush is a pixmap pipe brush with just one pixmap */
pipe->dimension = 1;
pipe->rank = g_new (gint, 1);
pipe->rank[0] = 1;
pipe->select = g_new (PipeSelectModes, 1);
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
pipe->index = g_new (gint, 1);
pipe->index[0] = 0;
pattern = g_new0 (GPattern, 1);
pipe->brushes = g_new (GimpBrushPixmap *, 1);
pipe->brushes[0] = GIMP_BRUSH_PIXMAP (pipe);
/* Current brush is the first one. */
pipe->current = pipe->brushes[0];
pipe->brushes[0]->pipe = pipe;
/* just to satisfy the code that relies on this crap */
/* load the brush */
if (!gimp_brush_load_brush (GIMP_BRUSH (pipe->brushes[0]),
fp, filename))
{
g_message (_("Failed to load pixmap brush."));
pattern_free (pattern);
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
if (!pattern_load (pattern, fp, filename))
{
g_message (_("Failed to load pixmap brush."));
gtk_object_sink (GTK_OBJECT (pipe));
return NULL;
}
pipe->brushes[0]->pixmap_mask = pattern->mask;
pipe->nbrushes = 1;
/* Clean up */
fclose (fp);
g_free (pattern->name);
g_free (pattern);
return pipe;
}
TempBuf *
gimp_brush_pixmap_pixmap (GimpBrushPixmap *brush)
{
g_return_val_if_fail (brush != NULL, NULL);
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (brush), NULL);
return brush->pixmap_mask;
GIMP_BRUSH (pipe)->mask = pipe->brushes[0]->mask;
GIMP_BRUSH (pipe)->pixmap = pipe->brushes[0]->pixmap;
close (fd);
return GIMP_BRUSH (pipe);
}

View File

@ -27,33 +27,59 @@
#include "temp_buf.h"
typedef struct _GimpBrushPixmap GimpBrushPixmap;
typedef struct _GimpBrushPipe GimpBrushPipe;
#define GIMP_TYPE_BRUSH_PIXMAP (gimp_brush_pixmap_get_type ())
#define GIMP_BRUSH_PIXMAP(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PIXMAP, GimpBrushPixmap))
#define GIMP_IS_BRUSH_PIXMAP(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_PIXMAP))
#define GIMP_TYPE_BRUSH_PIPE (gimp_brush_pipe_get_type ())
#define GIMP_BRUSH_PIPE(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_PIPE, GimpBrushPipe))
#define GIMP_IS_BRUSH_PIPE(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_PIPE))
typedef enum
{
PIPE_SELECT_CONSTANT,
PIPE_SELECT_INCREMENTAL,
PIPE_SELECT_ANGULAR,
PIPE_SELECT_VELOCITY,
PIPE_SELECT_RANDOM,
PIPE_SELECT_PRESSURE,
PIPE_SELECT_TILT_X,
PIPE_SELECT_TILT_Y
} PipeSelectModes;
struct _GimpBrushPipe
{
GimpBrush gbrush; /* Also itself a brush */
gint dimension;
gint *rank; /* Size in each dimension */
gint *stride; /* Aux for indexing */
PipeSelectModes *select; /* One mode per dimension */
gint *index; /* Current index for incremental dimensions */
gint nbrushes; /* Might be less than the product of the
* ranks in some odd special case */
GimpBrush **brushes;
GimpBrush *current; /* Currently selected brush */
};
typedef struct _GimpBrushPipeClass GimpBrushPipeClass;
struct _GimpBrushPipeClass
{
GimpBrushClass parent_class;
};
GtkType gimp_brush_pixmap_get_type (void);
GtkType gimp_brush_pipe_get_type (void);
GimpBrushPipe * gimp_brush_pipe_load (gchar *filename);
GimpBrushPipe * gimp_brush_pixmap_load (gchar *filename);
TempBuf * gimp_brush_pixmap_pixmap (GimpBrushPixmap *brush);
/* appearantly GIMP_IS_BRUSH_PIPE () returning TRUE is no indication
* that you really have a brush_pipe in front of you, so here we introduce
* a macro that works:
*/
#define GIMP_IS_REALLY_A_BRUSH_PIPE(obj) (GIMP_IS_BRUSH_PIPE (obj) && GIMP_BRUSH_PIPE (obj)->nbrushes > 1)
GimpBrush * gimp_brush_pipe_load (gchar *filename);
#endif /* __GIMP_BRUSH_PIPE_H__ */

View File

@ -1,78 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
* Copyright (C) 1999 Adrian Likins and Tor Lillqvist
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMPBRUSHPIPEP_H__
#define __GIMPBRUSHPIPEP_H__
typedef enum
{
PIPE_SELECT_CONSTANT,
PIPE_SELECT_INCREMENTAL,
PIPE_SELECT_ANGULAR,
PIPE_SELECT_VELOCITY,
PIPE_SELECT_RANDOM,
PIPE_SELECT_PRESSURE,
PIPE_SELECT_TILT_X,
PIPE_SELECT_TILT_Y
} PipeSelectModes;
/* A GimpBrushPixmap always exists as part in one and only one GimpBrushPipe
* It contains a back-pointer to the GimpBrushPipe so that we can select
* the next brush in the pipe with just a reference to the GimpBrushPipe.
*/
struct _GimpBrushPixmap
{
GimpBrush gbrush;
TempBuf *pixmap_mask;
GimpBrushPipe *pipe;
};
struct _GimpBrushPipe
{
GimpBrushPixmap pixmap; /* Also itself a pixmap brush */
GimpBrushPixmap *current; /* Currently selected brush */
gint dimension;
gint *rank; /* Size in each dimension */
gint *stride; /* Aux for indexing */
gint nbrushes; /* Might be less than the product of the
* ranks in some odd special case
*/
GimpBrushPixmap **brushes;
PipeSelectModes *select; /* One mode per dimension */
gint *index; /* Current index for incremental dimensions */
};
typedef struct _GimpBrushPixmapClass GimpBrushPixmapClass;
struct _GimpBrushPixmapClass
{
GimpBrushClass parent_class;
};
typedef struct _GimpBrushPipeClass GimpBrushPipeClass;
struct _GimpBrushPipeClass
{
GimpBrushPixmapClass parent_class;
};
#endif /* __GIMPBRUSHPIPEP_H__ */

View File

@ -31,7 +31,6 @@
#include "brush_scale.h"
#include "gimpbrush.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "gimpcontextpreview.h"
#include "gimpdnd.h"
#include "gradient_header.h"
@ -474,7 +473,7 @@ gimp_context_preview_popup_timeout (gpointer data)
gcp->popup_width = brush->mask->width;
gcp->popup_height = brush->mask->height;
if (GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
if (GIMP_IS_BRUSH_PIPE (brush))
{
GimpBrushPipe *pipe = GIMP_BRUSH_PIPE (brush);
gint i;
@ -550,18 +549,24 @@ gimp_context_preview_popup_timeout (gpointer data)
{
case GCP_BRUSH:
gimp_context_preview_draw_brush_popup (gcp);
if (GIMP_IS_REALLY_A_BRUSH_PIPE (gcp->data) && gcp_pipe_timer == 0)
if (GIMP_IS_BRUSH_PIPE (gcp->data) && gcp_pipe_timer == 0)
{
gcp_pipe_index = 0;
gcp_pipe_timer = gtk_timeout_add (300, (GtkFunction)gimp_context_preview_animate_pipe, gcp);
gcp_pipe_timer =
gtk_timeout_add (300,
(GtkFunction) gimp_context_preview_animate_pipe,
gcp);
}
break;
case GCP_PATTERN:
gimp_context_preview_draw_pattern_popup (gcp);
break;
case GCP_GRADIENT:
gimp_context_preview_draw_gradient_popup (gcp);
break;
default:
break;
}
@ -645,9 +650,8 @@ draw_brush (GtkPreview *preview,
guchar bg;
gint x, y;
mask_buf = brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (brush))
pixmap_buf = GIMP_BRUSH_PIXMAP (brush)->pixmap_mask;
mask_buf = gimp_brush_get_mask (brush);
pixmap_buf = gimp_brush_get_pixmap (brush);
brush_width = mask_buf->width;
brush_height = mask_buf->height;
@ -660,7 +664,7 @@ draw_brush (GtkPreview *preview,
brush_height = (gdouble)brush_height / MAX (ratio_x, ratio_y) + 0.5;
mask_buf = brush_scale_mask (mask_buf, brush_width, brush_height);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
@ -676,7 +680,7 @@ draw_brush (GtkPreview *preview,
buf = g_new (guchar, 3 * width);
memset (buf, 255, 3 * width);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
{
guchar *pixmap = temp_buf_data (pixmap_buf);
@ -724,16 +728,16 @@ draw_brush (GtkPreview *preview,
offset_x = width - indicator_width;
offset_y = height - indicator_height;
for (y = 0; y < indicator_height; y++)
(GIMP_IS_REALLY_A_BRUSH_PIPE (brush)) ?
(GIMP_IS_BRUSH_PIPE (brush)) ?
gtk_preview_draw_row (preview, scale_pipe_indicator_bits[y][0],
offset_x, offset_y + y, indicator_width) :
gtk_preview_draw_row (preview, scale_indicator_bits[y][0],
offset_x, offset_y + y, indicator_width);
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
temp_buf_free (pixmap_buf);
}
else if (!is_popup && GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
else if (!is_popup && GIMP_IS_BRUSH_PIPE (brush))
{
offset_x = width - indicator_width;
offset_y = height - indicator_height;
@ -775,7 +779,8 @@ gimp_context_preview_animate_pipe (GimpContextPreview *gcp)
GimpBrushPipe *pipe;
GimpBrush *brush;
g_return_val_if_fail (gcp != NULL && GIMP_IS_REALLY_A_BRUSH_PIPE (gcp->data), FALSE);
g_return_val_if_fail (gcp != NULL &&
GIMP_IS_BRUSH_PIPE (gcp->data), FALSE);
if (gcp_popup != NULL && !GTK_WIDGET_VISIBLE (gcp_popup))
{
gcp_pipe_timer = 0;

View File

@ -25,6 +25,7 @@
#include <gtk/gtk.h>
#include "gimpdrawableP.h"
#include "gimppreviewcache.h"
#include "gimpsignal.h"
#include "gimage.h"
#include "gimage_mask.h"

View File

@ -19,9 +19,8 @@
#ifndef __GIMPDRAWABLEP_H__
#define __GIMPDRAWABLEP_H__
#include "gimpobjectP.h"
#include "gimpobject.h"
#include "gimpdrawable.h"
#include "gimppreviewcache.h"
struct _GimpDrawable
@ -65,3 +64,4 @@ void gimp_drawable_configure (GimpDrawable *, GimpImage *,
gint, gint, GimpImageType, gchar *);
#endif /* __GIMPDRAWABLEP_H__ */

View File

@ -24,9 +24,6 @@
#include "apptypes.h"
#include "gimpobjectP.h"
#include "gimpimageP.h"
#include "cursorutil.h"
#include "drawable.h"
#include "floating_sel.h"

View File

@ -22,7 +22,7 @@
#include <gtk/gtk.h> /* eeeek */
#include "gimpobjectP.h"
#include "gimpobject.h"
#include "gimpimage.h"
#include "tile_manager.h"

View File

@ -26,7 +26,7 @@
#include "gimpobject.h"
#include "gimpsignal.h"
#include "gimplistP.h"
#include "gimplist.h"
/* code mostly ripped from nether's gimpset class */

View File

@ -20,6 +20,8 @@
#define __GIMP_LIST_H__
#include "gimpobject.h"
/* GimpList - a typed list of objects with signals for adding and
* removing of stuff. If it is weak, destroyed objects get removed
* automatically. If it is not, it refs them so they won't be freed
@ -30,6 +32,25 @@
#define GIMP_TYPE_LIST gimp_list_get_type ()
#define GIMP_LIST(obj) GTK_CHECK_CAST (obj, GIMP_TYPE_LIST, GimpList)
#define GIMP_IS_LIST(obj) GTK_CHECK_TYPE (obj, gimp_list_get_type())
#define GIMP_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_list_get_type(), GimpListClass)
struct _GimpList
{
GimpObject gobject;
GtkType type;
GSList* list;
gboolean weak;
};
struct _GimpListClass
{
GimpObjectClass parent_class;
void (* add) (GimpList *list, void *data);
void (* remove) (GimpList *list, void *data);
};
typedef struct _GimpListClass GimpListClass;
/* Signals:

View File

@ -23,7 +23,6 @@
#include "apptypes.h"
#include "gimpobject.h"
#include "gimpobjectP.h"
static void

View File

@ -20,12 +20,36 @@
#define __GIMP_OBJECT_H__
#include <gtk/gtktypeutils.h>
#include <gtk/gtk.h>
#define GIMP_TYPE_OBJECT gimp_object_get_type ()
#define GIMP_OBJECT(obj) GTK_CHECK_CAST (obj, GIMP_TYPE_OBJECT, GimpObject)
#define GIMP_IS_OBJECT(obj) GTK_CHECK_TYPE (obj, GIMP_TYPE_OBJECT)
#define GIMP_OBJECT_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, GIMP_TYPE_OBJECT, GimpObjectClass)
struct _GimpObject
{
GtkObject object;
};
typedef struct
{
GtkObjectClass parent_class;
} GimpObjectClass;
#define GIMP_TYPE_INIT(typevar, obtype, classtype, obinit, classinit, parent) \
if(!typevar){ \
GtkTypeInfo _info={#obtype, \
sizeof(obtype), \
sizeof(classtype), \
(GtkClassInitFunc)classinit, \
(GtkObjectInitFunc)obinit, \
NULL, NULL, NULL}; \
typevar=gtk_type_unique(parent, &_info); \
}
GtkType gimp_object_get_type (void);

View File

@ -1,33 +0,0 @@
#ifndef __GIMP_OBJECT_P_H__
#define __GIMP_OBJECT_P_H__
#include <gtk/gtk.h>
struct _GimpObject
{
GtkObject object;
};
typedef struct
{
GtkObjectClass parent_class;
} GimpObjectClass;
#define GIMP_OBJECT_CLASS(klass) \
GTK_CHECK_CLASS_CAST (klass, GIMP_TYPE_OBJECT, GimpObjectClass)
#define GIMP_TYPE_INIT(typevar, obtype, classtype, obinit, classinit, parent) \
if(!typevar){ \
GtkTypeInfo _info={#obtype, \
sizeof(obtype), \
sizeof(classtype), \
(GtkClassInitFunc)classinit, \
(GtkObjectInitFunc)obinit, \
NULL, NULL, NULL}; \
typevar=gtk_type_unique(parent, &_info); \
}
#endif

View File

@ -18,7 +18,6 @@
#ifndef __GIMP_SET_P_H__
#define __GIMP_SET_P_H__
#include "gimpobjectP.h"
#include "gimpset.h"
#define GIMP_SET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_set_get_type(), GimpSetClass)

View File

@ -32,7 +32,6 @@
#include "gimpbrushgenerated.h"
#include "gimpbrushlist.h"
#include "gimpbrushpipe.h"
#include "gimpbrushpipeP.h"
#include "gimpcontext.h"
#include "gimpdnd.h"
#include "gimplist.h"
@ -953,9 +952,9 @@ draw_brush_popup (GtkPreview *preview,
buf = g_new (guchar, 3 * width);
memset (buf, 255, 3 * width);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (gimp_brush_get_pixmap (brush))
{
guchar *pixmap = temp_buf_data (GIMP_BRUSH_PIXMAP (brush)->pixmap_mask);
guchar *pixmap = temp_buf_data (gimp_brush_get_pixmap (brush));
for (y = 0; y < offset_y; y++)
gtk_preview_draw_row (preview, buf, 0, y, width);
@ -1070,7 +1069,7 @@ brush_popup_timeout (gpointer data)
/* decide where to put the popup */
width = brush->mask->width;
height = brush->mask->height;
if (GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
if (GIMP_IS_BRUSH_PIPE (brush))
{
GimpBrushPipe *pipe = GIMP_BRUSH_PIPE (brush);
GimpBrush *tmp_brush;
@ -1100,7 +1099,7 @@ brush_popup_timeout (gpointer data)
draw_brush_popup (GTK_PREVIEW (bsp->brush_preview), brush, width, height);
gtk_widget_queue_draw (bsp->brush_preview);
if (GIMP_IS_REALLY_A_BRUSH_PIPE (brush) && bsp->popup_anim_timeout_tag == 0)
if (GIMP_IS_BRUSH_PIPE (brush) && bsp->popup_anim_timeout_tag == 0)
{
static popup_timeout_args_t timeout_args;
@ -1222,9 +1221,8 @@ display_brush (BrushSelect *bsp,
cell_width = bsp->cell_width - 2 * MARGIN_WIDTH;
cell_height = bsp->cell_height - 2 * MARGIN_HEIGHT;
mask_buf = brush->mask;
if (GIMP_IS_BRUSH_PIXMAP (brush))
pixmap_buf = GIMP_BRUSH_PIXMAP (brush)->pixmap_mask;
mask_buf = gimp_brush_get_mask (brush);
pixmap_buf = gimp_brush_get_pixmap (brush);
if (mask_buf->width > cell_width || mask_buf->height > cell_height)
{
@ -1234,7 +1232,7 @@ display_brush (BrushSelect *bsp,
mask_buf = brush_scale_mask (mask_buf,
(gdouble)(mask_buf->width) / MAX (ratio_x, ratio_y) + 0.5,
(gdouble)(mask_buf->height) / MAX (ratio_x, ratio_y) + 0.5);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
{
/* TODO: the scale function should scale the pixmap
and the mask in one run */
@ -1257,9 +1255,11 @@ display_brush (BrushSelect *bsp,
mask = temp_buf_data (mask_buf) + (ystart - offset_y) * mask_buf->width;
buf = g_new (guchar, 3 * cell_width);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
{
guchar *pixmap = temp_buf_data (pixmap_buf) + (ystart - offset_y) * mask_buf->width * 3;
guchar *pixmap =
temp_buf_data (pixmap_buf) + (ystart - offset_y) * mask_buf->width * 3;
for (i = ystart; i < yend; i++)
{
b = buf;
@ -1303,12 +1303,13 @@ display_brush (BrushSelect *bsp,
if (scale)
{
temp_buf_free (mask_buf);
if (GIMP_IS_BRUSH_PIXMAP (brush))
if (pixmap_buf)
temp_buf_free (pixmap_buf);
for (i = 0; i < indicator_height; i++, offset_y++)
{
if (offset_y > 0 && offset_y < bsp->preview->allocation.height)
(GIMP_IS_REALLY_A_BRUSH_PIPE (brush)) ?
(GIMP_IS_BRUSH_PIPE (brush)) ?
gtk_preview_draw_row (GTK_PREVIEW (bsp->preview),
scale_pipe_indicator_bits[i][0],
offset_x, offset_y, indicator_width) :
@ -1317,7 +1318,7 @@ display_brush (BrushSelect *bsp,
offset_x, offset_y, indicator_width);
}
}
else if (GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
else if (GIMP_IS_BRUSH_PIPE (brush))
{
for (i = 0; i < indicator_height; i++, offset_y++)
{
@ -1617,7 +1618,7 @@ brush_select_events (GtkWidget *widget,
/* Show the brush popup window if the brush is too large */
if (brush->mask->width > bsp->cell_width - 2 * MARGIN_WIDTH ||
brush->mask->height > bsp->cell_height - 2 * MARGIN_HEIGHT ||
GIMP_IS_REALLY_A_BRUSH_PIPE (brush))
GIMP_IS_BRUSH_PIPE (brush))
{
brush_popup_open (bsp, bevent->x, bevent->y, brush);
}
@ -1808,19 +1809,21 @@ static void
brush_select_new_brush_callback (GtkWidget *widget,
gpointer data)
{
GimpBrushGenerated *brush;
GimpBrush *brush;
BrushSelect *bsp;
bsp = (BrushSelect *) data;
brush = gimp_brush_generated_new (10, .5, 0.0, 1.0);
gimp_brush_list_add (brush_list, GIMP_BRUSH (brush));
if (brush)
{
gimp_brush_list_add (brush_list, brush);
gimp_context_set_brush (bsp->context, GIMP_BRUSH (brush));
gimp_context_set_brush (bsp->context, brush);
if (brush_edit_generated_dialog)
brush_edit_generated_set_brush (brush_edit_generated_dialog,
GIMP_BRUSH (brush));
brush_edit_generated_set_brush (brush_edit_generated_dialog, brush);
}
brush_select_edit_brush_callback (widget, data);
}

View File

@ -21,6 +21,7 @@
#include "gimpbrush.h"
#include "gimpcontext.h"
typedef struct _BrushSelect BrushSelect;

View File

@ -31,6 +31,7 @@
#include "gimage.h"
#include "gimage_mask.h"
#include "gimpdnd.h"
#include "gimppreviewcache.h"
#include "gimprc.h"
#include "gimpui.h"
#include "layers_dialogP.h"

View File

@ -26,7 +26,6 @@
#include "airbrush.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "gimage.h"
#include "gimpui.h"
@ -330,7 +329,7 @@ airbrush_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
mode = INCREMENTAL;
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -25,7 +25,6 @@
#include "appenv.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "paint_funcs.h"
#include "paint_core.h"
@ -172,7 +171,7 @@ pencil_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
/* if its a pixmap, do pixmap stuff */
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -196,6 +196,7 @@ paint_core_button_press (Tool *tool,
{
PaintCore *paint_core;
GDisplay *gdisp;
GimpBrush *current_brush;
gboolean draw_line;
gdouble x, y;
GimpDrawable *drawable;
@ -203,6 +204,9 @@ paint_core_button_press (Tool *tool,
gdisp = (GDisplay *) gdisp_ptr;
paint_core = (PaintCore *) tool->private;
g_return_if_fail (gdisp != NULL);
g_return_if_fail (paint_core != NULL);
gdisplay_untransform_coords_f (gdisp, (double) bevent->x, (double) bevent->y,
&x, &y, TRUE);
drawable = gimage_active_drawable (gdisp->gimage);
@ -318,6 +322,9 @@ paint_core_button_press (Tool *tool,
else
paint_core->pick_state = FALSE;
/* store the current brush pointer */
current_brush = paint_core->brush;
/* Paint to the image */
if (draw_line)
{
@ -361,6 +368,9 @@ paint_core_button_press (Tool *tool,
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
(* paint_core->paint_func) (paint_core, drawable, POSTTRACE_PAINT);
/* restore the current brush pointer */
paint_core->brush = current_brush;
}
void
@ -833,6 +843,7 @@ void
paint_core_interpolate (PaintCore *paint_core,
GimpDrawable *drawable)
{
GimpBrush *current_brush;
GimpVector2 delta;
#ifdef GTK_HAVE_SIX_VALUATORS
gdouble dpressure, dxtilt, dytilt, dwheel;
@ -910,11 +921,18 @@ paint_core_interpolate (PaintCore *paint_core,
#ifdef GTK_HAVE_SIX_VALUATORS
paint_core->curwheel = paint_core->lastwheel + dwheel * t;
#endif /* GTK_HAVE_SIX_VALUATORS */
/* save the current brush */
current_brush = paint_core->brush;
if (paint_core->flags & TOOL_CAN_HANDLE_CHANGING_BRUSH)
paint_core->brush =
(* GIMP_BRUSH_CLASS (GTK_OBJECT (paint_core->brush)
->klass)->select_brush) (paint_core);
(* paint_core->paint_func) (paint_core, drawable, MOTION_PAINT);
/* restore the current brush pointer */
paint_core->brush = current_brush;
}
}
paint_core->distance = total;
@ -2013,11 +2031,11 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
TempBuf *pixmap_mask;
TempBuf *brush_mask;
g_return_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush));
g_return_if_fail (GIMP_IS_BRUSH (paint_core->brush));
g_return_if_fail (paint_core->brush->pixmap != NULL);
/* scale the brushes */
pixmap_mask =
paint_core_scale_pixmap (gimp_brush_pixmap_pixmap (GIMP_BRUSH_PIXMAP (paint_core->brush)), scale);
pixmap_mask = paint_core_scale_pixmap (paint_core->brush->pixmap, scale);
if (mode == SOFT)
brush_mask = paint_core_scale_mask (paint_core->brush->mask, scale);

View File

@ -26,7 +26,6 @@
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushlist.h"
#include "gimpbrushpipe.h"
#include "gimpui.h"
#include "gradient.h"
#include "paint_funcs.h"
@ -547,9 +546,10 @@ paintbrush_motion (PaintCore *paint_core,
}
/* we check to see if this is a pixmap, if so composite the
pixmap image into the are instead of the color */
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,
paint_core_color_area_with_pixmap (paint_core, gimage, drawable,
area,
scale, SOFT);
paint_appl_mode = INCREMENTAL;
}

View File

@ -17,7 +17,7 @@
#ifndef __PARASITE_LIST_P_H__
#define __PARASITE_LIST_P_H__
#include "gimpobjectP.h"
#include "gimpobject.h"
#include "parasitelist.h"
struct _ParasiteList

View File

@ -21,11 +21,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
@ -40,6 +51,7 @@
#include "libgimp/gimpintl.h"
/* global variables */
GPattern *active_pattern = NULL;
GSList *pattern_list = NULL;
@ -48,11 +60,16 @@ gint num_patterns = 0;
/* static variables */
static GPattern *standard_pattern = NULL;
/* local function prototypes */
static void load_pattern (gchar *);
static void pattern_free_func (gpointer, gpointer);
static gint pattern_compare_func (gconstpointer,
gconstpointer);
static GPattern * pattern_load_real (gint fd,
gchar *filename,
gboolean quiet);
static void load_pattern (gchar *filename);
static void pattern_free_func (gpointer data,
gpointer dummy);
static gint pattern_compare_func (gconstpointer second,
gconstpointer first);
/* public functions */
@ -148,83 +165,87 @@ pattern_list_get_pattern (GSList *list,
return NULL;
}
gboolean
pattern_load (GPattern *pattern,
FILE *fp,
GPattern *
pattern_load (gint fd,
gchar *filename)
{
return pattern_load_real (fd, filename, TRUE);
}
static GPattern *
pattern_load_real (gint fd,
gchar *filename,
gboolean quiet)
{
GPattern *pattern;
PatternHeader header;
gint bn_size;
guchar buf [sizeof (PatternHeader)];
guint *hp;
gint i;
gchar *name;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (fd != -1, NULL);
/* Read in the header size */
if ((fread (buf, 1, sizeof (PatternHeader), fp)) < sizeof (PatternHeader))
{
fclose (fp);
pattern_free (pattern);
return FALSE;
}
if (read (fd, &header, sizeof (header)) != sizeof (header))
return NULL;
/* rearrange the bytes in each unsigned int */
hp = (guint *) &header;
for (i = 0; i < (sizeof (PatternHeader) / 4); i++)
hp [i] = (buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]);
header.header_size = g_ntohl (header.header_size);
header.version = g_ntohl (header.version);
header.width = g_ntohl (header.width);
header.height = g_ntohl (header.height);
header.bytes = g_ntohl (header.bytes);
header.magic_number = g_ntohl (header.magic_number);
/* Check for correct file format */
if (header.magic_number != GPATTERN_MAGIC)
if (header.magic_number != GPATTERN_MAGIC || header.version != 1 ||
header.header_size <= sizeof (header))
{
/* One thing that can save this error is if the pattern is version 1 */
if (header.version != 1)
{
fclose (fp);
pattern_free (pattern);
return FALSE;
}
}
/* Check for correct version */
if (header.version != GPATTERN_FILE_VERSION)
{
g_message (_("Unknown GIMP pattern version #%d in \"%s\"\n"),
if (!quiet)
g_message (_("Unknown pattern format version #%d in \"%s\"."),
header.version, filename);
fclose (fp);
pattern_free (pattern);
return FALSE;
return NULL;
}
/* Get a new pattern mask */
pattern->mask =
temp_buf_new (header.width, header.height, header.bytes, 0, 0, NULL);
/* Check for supported bit depths */
if (header.bytes != 1 && header.bytes != 3)
{
g_message ("Unsupported pattern depth: %d\n in file \"%s\"\nGIMP Patterns must be GRAY or RGB\n",
header.bytes, filename);
return NULL;
}
/* Read in the pattern name */
if ((bn_size = (header.header_size - sizeof (PatternHeader))))
/* Read in the brush name */
if ((bn_size = (header.header_size - sizeof (header))))
{
pattern->name = g_new (gchar, bn_size);
if ((fread (pattern->name, 1, bn_size, fp)) < bn_size)
name = g_new (gchar, bn_size);
if ((read (fd, name, bn_size)) < bn_size)
{
g_message (_("Error in GIMP pattern file \"%s\""), filename);
fclose (fp);
pattern_free (pattern);
return FALSE;
g_message (_("Error in GIMP pattern file \"%s\"."), filename);
g_free (name);
return NULL;
}
}
else
pattern->name = g_strdup (_("Unnamed"));
/* Read the pattern mask data */
/* Read the image data */
if ((fread (temp_buf_data (pattern->mask), 1,
header.width * header.height * header.bytes, fp)) <
header.width * header.height * header.bytes)
{
g_message (_("GIMP pattern file \"%s\" appears to be truncated."),
filename);
name = g_strdup (_("Unnamed"));
}
/* success */
return TRUE;
pattern = g_new0 (GPattern, 1);
pattern->mask = temp_buf_new (header.width, header.height, header.bytes,
0, 0, NULL);
if (read (fd, temp_buf_data (pattern->mask),
header.width * header.height * header.bytes) < header.width * header.height * header.bytes)
{
g_message (_("GIMP pattern file appears to be truncated: \"%s\"."),
filename);
pattern_free (pattern);
return NULL;
}
pattern->name = name;
return pattern;
}
void
@ -261,31 +282,24 @@ static void
load_pattern (gchar *filename)
{
GPattern *pattern;
FILE *fp;
gint fd;
pattern = g_new0 (GPattern, 1);
g_return_if_fail (filename != NULL);
fd = open (filename, O_RDONLY | _O_BINARY);
if (fd == -1)
return;
pattern = pattern_load_real (fd, filename, FALSE);
if (!pattern)
return;
pattern->filename = g_strdup (filename);
pattern->name = NULL;
pattern->mask = NULL;
/* Open the requested file */
if (! (fp = fopen (filename, "rb")))
{
pattern_free (pattern);
return;
}
if (! pattern_load (pattern, fp, filename))
{
g_message (_("Error loading pattern \"%s\""), filename);
return;
}
/* Clean up */
fclose (fp);
/*temp_buf_swap (pattern->mask);*/
/* Swap the pattern to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (pattern->mask);
pattern_list = g_slist_insert_sorted (pattern_list, pattern,
pattern_compare_func);

View File

@ -46,9 +46,9 @@ GPattern * pattern_list_get_pattern (GSList *list,
gchar *name);
/* this is useful for pixmap brushes etc. */
gboolean pattern_load (GPattern *pattern,
FILE *fp,
GPattern * pattern_load (gint fd,
gchar *filename);
void pattern_free (GPattern *pattern);
#endif /* __PATTERNS_H__ */

View File

@ -25,7 +25,6 @@
#include "appenv.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "paint_funcs.h"
#include "paint_core.h"
@ -172,7 +171,7 @@ pencil_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
/* if its a pixmap, do pixmap stuff */
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -26,7 +26,6 @@
#include "airbrush.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "gimage.h"
#include "gimpui.h"
@ -330,7 +329,7 @@ airbrush_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
mode = INCREMENTAL;
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -26,7 +26,6 @@
#include "airbrush.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "gimage.h"
#include "gimpui.h"
@ -330,7 +329,7 @@ airbrush_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
mode = INCREMENTAL;
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -25,7 +25,6 @@
#include "appenv.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "paint_funcs.h"
#include "paint_core.h"
@ -172,7 +171,7 @@ pencil_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
/* if its a pixmap, do pixmap stuff */
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -196,6 +196,7 @@ paint_core_button_press (Tool *tool,
{
PaintCore *paint_core;
GDisplay *gdisp;
GimpBrush *current_brush;
gboolean draw_line;
gdouble x, y;
GimpDrawable *drawable;
@ -203,6 +204,9 @@ paint_core_button_press (Tool *tool,
gdisp = (GDisplay *) gdisp_ptr;
paint_core = (PaintCore *) tool->private;
g_return_if_fail (gdisp != NULL);
g_return_if_fail (paint_core != NULL);
gdisplay_untransform_coords_f (gdisp, (double) bevent->x, (double) bevent->y,
&x, &y, TRUE);
drawable = gimage_active_drawable (gdisp->gimage);
@ -318,6 +322,9 @@ paint_core_button_press (Tool *tool,
else
paint_core->pick_state = FALSE;
/* store the current brush pointer */
current_brush = paint_core->brush;
/* Paint to the image */
if (draw_line)
{
@ -361,6 +368,9 @@ paint_core_button_press (Tool *tool,
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
(* paint_core->paint_func) (paint_core, drawable, POSTTRACE_PAINT);
/* restore the current brush pointer */
paint_core->brush = current_brush;
}
void
@ -833,6 +843,7 @@ void
paint_core_interpolate (PaintCore *paint_core,
GimpDrawable *drawable)
{
GimpBrush *current_brush;
GimpVector2 delta;
#ifdef GTK_HAVE_SIX_VALUATORS
gdouble dpressure, dxtilt, dytilt, dwheel;
@ -910,11 +921,18 @@ paint_core_interpolate (PaintCore *paint_core,
#ifdef GTK_HAVE_SIX_VALUATORS
paint_core->curwheel = paint_core->lastwheel + dwheel * t;
#endif /* GTK_HAVE_SIX_VALUATORS */
/* save the current brush */
current_brush = paint_core->brush;
if (paint_core->flags & TOOL_CAN_HANDLE_CHANGING_BRUSH)
paint_core->brush =
(* GIMP_BRUSH_CLASS (GTK_OBJECT (paint_core->brush)
->klass)->select_brush) (paint_core);
(* paint_core->paint_func) (paint_core, drawable, MOTION_PAINT);
/* restore the current brush pointer */
paint_core->brush = current_brush;
}
}
paint_core->distance = total;
@ -2013,11 +2031,11 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
TempBuf *pixmap_mask;
TempBuf *brush_mask;
g_return_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush));
g_return_if_fail (GIMP_IS_BRUSH (paint_core->brush));
g_return_if_fail (paint_core->brush->pixmap != NULL);
/* scale the brushes */
pixmap_mask =
paint_core_scale_pixmap (gimp_brush_pixmap_pixmap (GIMP_BRUSH_PIXMAP (paint_core->brush)), scale);
pixmap_mask = paint_core_scale_pixmap (paint_core->brush->pixmap, scale);
if (mode == SOFT)
brush_mask = paint_core_scale_mask (paint_core->brush->mask, scale);

View File

@ -26,7 +26,6 @@
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushlist.h"
#include "gimpbrushpipe.h"
#include "gimpui.h"
#include "gradient.h"
#include "paint_funcs.h"
@ -547,9 +546,10 @@ paintbrush_motion (PaintCore *paint_core,
}
/* we check to see if this is a pixmap, if so composite the
pixmap image into the are instead of the color */
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,
paint_core_color_area_with_pixmap (paint_core, gimage, drawable,
area,
scale, SOFT);
paint_appl_mode = INCREMENTAL;
}

View File

@ -25,7 +25,6 @@
#include "appenv.h"
#include "drawable.h"
#include "gdisplay.h"
#include "gimpbrushpipe.h"
#include "gradient.h"
#include "paint_funcs.h"
#include "paint_core.h"
@ -172,7 +171,7 @@ pencil_motion (PaintCore *paint_core,
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
}
else if (GIMP_IS_BRUSH_PIXMAP (paint_core->brush))
else if (paint_core->brush && paint_core->brush->pixmap)
{
/* if its a pixmap, do pixmap stuff */
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,

View File

@ -50,8 +50,8 @@ gee_zoom
gicon
gif
gifload
gih
glasstile
gpb
gqbist
gradmap
grid

View File

@ -65,8 +65,8 @@ libexec_PROGRAMS = \
gicon \
gif \
gifload \
gih \
glasstile \
gpb \
gqbist \
gradmap \
grid \
@ -590,19 +590,19 @@ gifload_LDADD = \
$(GTK_LIBS) \
$(INTLLIBS)
glasstile_SOURCES = \
glasstile.c
gih_SOURCES = \
gih.c
glasstile_LDADD = \
gih_LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(GTK_LIBS) \
$(INTLLIBS)
gpb_SOURCES = \
gpb.c
glasstile_SOURCES = \
glasstile.c
gpb_LDADD = \
glasstile_LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(GTK_LIBS) \

View File

@ -7,6 +7,10 @@
* tool to read them.
* July 6, 1998 by Seth Burgess <sjburges@gimp.org>
*
* Dec 17, 2000
* Load and save GIMP brushes in GRAY or RGBA. jtl + neo
*
*
* TODO: Give some better error reporting on not opening files/bad headers
* etc.
*/
@ -14,7 +18,7 @@
#include "config.h"
#include <glib.h> /* Include early for G_OS_WIN32 */
#include <setjmp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -41,6 +45,7 @@
#include <libgimp/gimpui.h>
#include "app/brush_header.h"
#include "app/pattern_header.h"
#include "libgimp/stdplugins-intl.h"
@ -60,7 +65,8 @@ t_info info =
10
};
gint run_flag = FALSE;
gboolean run_flag = FALSE;
/* Declare some local functions.
*/
@ -82,6 +88,7 @@ static void ok_callback (GtkWidget *widget,
static void entry_callback (GtkWidget *widget,
gpointer data);
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
@ -123,11 +130,11 @@ query (void)
static gint nsave_args = sizeof (save_args) / sizeof (save_args[0]);
gimp_install_procedure ("file_gbr_load",
"loads files of the .gbr file format",
"Loads GIMP brushes (1 or 4 bpp)",
"FIXME: write help",
"Tim Newsome",
"Tim Newsome",
"1997",
"Tim Newsome, Jens Lautenbacher, Sven Neumann",
"Tim Newsome, Jens Lautenbacher, Sven Neumann",
"1997-2000",
"<Load>/GBR",
NULL,
GIMP_PLUGIN,
@ -137,11 +144,11 @@ query (void)
gimp_install_procedure ("file_gbr_save",
"saves files in the .gbr file format",
"Yeah!",
"Tim Newsome",
"Tim Newsome",
"1997",
"Tim Newsome, Jens Lautenbacher, Sven Neumann",
"Tim Newsome, Jens Lautenbacher, Sven Neumann",
"1997-2000",
"<Save>/GBR",
"GRAY",
"RGBA, GRAY",
GIMP_PLUGIN,
nsave_args, 0,
save_args, NULL);
@ -204,7 +211,9 @@ run (gchar *name,
INIT_I18N_UI();
gimp_ui_init ("gbr", FALSE);
export = gimp_export_image (&image_ID, &drawable_ID, "GBR",
GIMP_EXPORT_CAN_HANDLE_GRAY);
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
if (export == GIMP_EXPORT_CANCEL)
{
values[0].data.d_status = GIMP_PDB_CANCEL;
@ -225,7 +234,8 @@ run (gchar *name,
status = GIMP_PDB_CANCEL;
break;
case GIMP_RUN_NONINTERACTIVE: /* FIXME - need a real GIMP_RUN_NONINTERACTIVE */
case GIMP_RUN_NONINTERACTIVE:
/* FIXME - need a real GIMP_RUN_NONINTERACTIVE */
if (nparams != 7)
{
status = GIMP_PDB_CALLING_ERROR;
@ -268,15 +278,17 @@ run (gchar *name,
static gint32
load_image (gchar *filename)
{
char *temp;
int fd;
BrushHeader ph;
gchar *buffer;
gint32 image_ID, layer_ID;
gchar *temp;
gint fd;
BrushHeader bh;
guchar *brush_buf = NULL;
gint32 image_ID;
gint32 layer_ID;
GimpDrawable *drawable;
gint line;
GimpPixelRgn pixel_rgn;
int version_extra;
gint version_extra;
GimpImageBaseType base_type;
GimpImageType image_type;
temp = g_strdup_printf (_("Loading %s:"), filename);
gimp_progress_init (temp);
@ -289,42 +301,43 @@ load_image (gchar *filename)
return -1;
}
if (read(fd, &ph, sizeof(ph)) != sizeof(ph))
if (read (fd, &bh, sizeof (bh)) != sizeof (bh))
{
close (fd);
return -1;
}
/* rearrange the bytes in each unsigned int */
ph.header_size = g_ntohl(ph.header_size);
ph.version = g_ntohl(ph.version);
ph.width = g_ntohl(ph.width);
ph.height = g_ntohl(ph.height);
ph.bytes = g_ntohl(ph.bytes);
ph.magic_number = g_ntohl(ph.magic_number);
ph.spacing = g_ntohl(ph.spacing);
bh.header_size = g_ntohl (bh.header_size);
bh.version = g_ntohl (bh.version);
bh.width = g_ntohl (bh.width);
bh.height = g_ntohl (bh.height);
bh.bytes = g_ntohl (bh.bytes);
bh.magic_number = g_ntohl (bh.magic_number);
bh.spacing = g_ntohl (bh.spacing);
/* How much extra to add ot the header seek - 1 needs a bit more */
/* How much extra to add to the header seek - 1 needs a bit more */
version_extra = 0;
if (ph.version == 1)
if (bh.version == 1)
{
/* Version 1 didn't know about spacing */
ph.spacing=25;
bh.spacing = 25;
/* And we need to rewind the handle a bit too */
lseek (fd, -8, SEEK_CUR);
version_extra = 8;
}
/* Version 1 didn't know about magic either */
if ((ph.version != 1 &&
(ph.magic_number != GBRUSH_MAGIC || ph.version != 2)) ||
ph.header_size <= sizeof(ph)) {
if ((bh.version != 1 &&
(bh.magic_number != GBRUSH_MAGIC || bh.version != 2)) ||
bh.header_size <= sizeof (bh))
{
close (fd);
return -1;
}
if (lseek(fd, ph.header_size - sizeof(ph) + version_extra, SEEK_CUR)
!= ph.header_size)
if (lseek (fd, bh.header_size - sizeof (bh) + version_extra, SEEK_CUR)
!= bh.header_size)
{
close (fd);
return -1;
@ -332,36 +345,58 @@ load_image (gchar *filename)
/* Now there's just raw data left. */
brush_buf = g_malloc (bh.width * bh.height * bh.bytes);
if (read (fd, brush_buf,
bh.width * bh.height * bh.bytes) != bh.width * bh.height * bh.bytes)
{
close (fd);
g_free (brush_buf);
return -1;
}
/*
* Create a new image of the proper size and
* associate the filename with it.
*/
image_ID = gimp_image_new (ph.width, ph.height, (ph.bytes >= 3) ? GIMP_RGB : GIMP_GRAY);
switch (bh.bytes)
{
case 1:
base_type = GIMP_GRAY;
image_type = GIMP_GRAY_IMAGE;
break;
case 4:
base_type = GIMP_RGB;
image_type = GIMP_RGBA_IMAGE;
break;
default:
g_message ("Unsupported brush depth: %d\nGIMP Brushes must be GRAY or RGBA\n",
bh.bytes);
return -1;
}
image_ID = gimp_image_new (bh.width, bh.height, base_type);
gimp_image_set_filename (image_ID, filename);
layer_ID = gimp_layer_new (image_ID, _("Background"), ph.width, ph.height,
(ph.bytes >= 3) ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE, 100,
GIMP_NORMAL_MODE);
layer_ID = gimp_layer_new (image_ID, _("Background"),
bh.width, bh.height,
image_type, 100, GIMP_NORMAL_MODE);
gimp_image_add_layer (image_ID, layer_ID, 0);
drawable = gimp_drawable_get (layer_ID);
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width,
drawable->height, TRUE, FALSE);
gimp_pixel_rgn_init (&pixel_rgn, drawable,
0, 0, drawable->width, drawable->height,
TRUE, FALSE);
buffer = g_malloc (ph.width * ph.bytes);
gimp_pixel_rgn_set_rect (&pixel_rgn, (guchar *) brush_buf,
0, 0, bh.width, bh.height);
if (image_type == GIMP_GRAY_IMAGE)
gimp_invert (layer_ID);
for (line = 0; line < ph.height; line++)
{
if (read(fd, buffer, ph.width * ph.bytes) != ph.width * ph.bytes)
{
close (fd);
g_free(buffer);
return -1;
}
gimp_pixel_rgn_set_row (&pixel_rgn, (guchar *)buffer, 0, line, ph.width);
gimp_progress_update ((double) line / (double) ph.height);
}
g_free (brush_buf);
gimp_drawable_flush (drawable);
@ -369,28 +404,34 @@ load_image (gchar *filename)
}
static gint
save_image (char *filename,
save_image (gchar *filename,
gint32 image_ID,
gint32 drawable_ID)
{
int fd;
BrushHeader ph;
unsigned char *buffer;
gint fd;
BrushHeader bh;
guchar *buffer;
GimpDrawable *drawable;
gint line;
gint x;
GimpPixelRgn pixel_rgn;
char *temp;
gchar *temp;
if (gimp_drawable_type(drawable_ID) != GIMP_GRAY_IMAGE)
if (gimp_drawable_type (drawable_ID) != GIMP_GRAY_IMAGE &&
gimp_drawable_type (drawable_ID) != GIMP_RGBA_IMAGE)
{
g_message (_("GIMP brushes are either GRAYSCALE or RGBA\n"));
return FALSE;
}
temp = g_strdup_printf (_("Saving %s:"), filename);
gimp_progress_init (temp);
g_free (temp);
drawable = gimp_drawable_get (drawable_ID);
gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0, drawable->width,
drawable->height, FALSE, FALSE);
gimp_pixel_rgn_init (&pixel_rgn, drawable,
0, 0, drawable->width, drawable->height,
FALSE, FALSE);
fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY | _O_BINARY, 0644);
@ -400,15 +441,15 @@ save_image (char *filename,
return FALSE;
}
ph.header_size = g_htonl(sizeof(ph) + strlen(info.description) + 1);
ph.version = g_htonl(2);
ph.width = g_htonl(drawable->width);
ph.height = g_htonl(drawable->height);
ph.bytes = g_htonl(drawable->bpp);
ph.magic_number = g_htonl(GBRUSH_MAGIC);
ph.spacing = g_htonl(info.spacing);
bh.header_size = g_htonl (sizeof (bh) + strlen (info.description) + 1);
bh.version = g_htonl (2);
bh.width = g_htonl (drawable->width);
bh.height = g_htonl (drawable->height);
bh.bytes = g_htonl (drawable->bpp);
bh.magic_number = g_htonl (GBRUSH_MAGIC);
bh.spacing = g_htonl (info.spacing);
if (write(fd, &ph, sizeof(ph)) != sizeof(ph))
if (write (fd, &bh, sizeof (bh)) != sizeof (bh))
{
close (fd);
return FALSE;
@ -425,15 +466,24 @@ save_image (char *filename,
for (line = 0; line < drawable->height; line++)
{
gimp_pixel_rgn_get_row (&pixel_rgn, buffer, 0, line, drawable->width);
if (write(fd, buffer, drawable->width * drawable->bpp) !=
drawable->width * drawable->bpp) {
if (drawable->bpp == 1)
{
for (x = 0; x < drawable->width; x++)
buffer[x] = 255 - buffer[x];
}
if (write (fd, buffer,
drawable->width * drawable->bpp) != drawable->width * drawable->bpp)
{
g_free (buffer);
close (fd);
return FALSE;
}
gimp_progress_update((double) line / (double) drawable->height);
gimp_progress_update ((gdouble) line / (gdouble) drawable->height);
}
g_free(buffer);
g_free (buffer);
close (fd);
return TRUE;
@ -503,7 +553,7 @@ static void
ok_callback (GtkWidget *widget,
gpointer data)
{
run_flag = 1;
run_flag = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}

File diff suppressed because it is too large Load Diff

View File

@ -183,7 +183,8 @@ run (gchar *name,
INIT_I18N_UI();
gimp_ui_init ("pat", FALSE);
export = gimp_export_image (&image_ID, &drawable_ID, "PAT",
(GIMP_EXPORT_CAN_HANDLE_RGB | GIMP_EXPORT_CAN_HANDLE_GRAY));
(GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_RGB));
if (export == GIMP_EXPORT_CANCEL)
{
values[0].data.d_status = GIMP_PDB_CANCEL;
@ -254,6 +255,8 @@ load_image (gchar *filename)
GimpDrawable *drawable;
gint line;
GimpPixelRgn pixel_rgn;
GimpImageBaseType base_type;
GimpImageType image_type;
temp = g_strdup_printf( _("Loading %s:"), filename);
gimp_progress_init (temp);
@ -295,15 +298,32 @@ load_image (gchar *filename)
/*
* Create a new image of the proper size and associate the filename with it.
*/
image_ID = gimp_image_new(ph.width, ph.height, (ph.bytes >= 3) ? GIMP_RGB : GIMP_GRAY);
switch (ph.bytes)
{
case 1:
base_type = GIMP_GRAY;
image_type = GIMP_GRAY_IMAGE;
break;
case 3:
base_type = GIMP_RGB;
image_type = GIMP_RGB_IMAGE;
break;
default:
g_message ("Unsupported pattern depth: %d\nGIMP Patterns must be GRAY or RGB\n", ph.bytes);
return -1;
}
image_ID = gimp_image_new (ph.width, ph.height, base_type);
gimp_image_set_filename(image_ID, filename);
layer_ID = gimp_layer_new (image_ID, _("Background"), ph.width, ph.height,
(ph.bytes >= 3) ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE, 100, GIMP_NORMAL_MODE);
image_type, 100, GIMP_NORMAL_MODE);
gimp_image_add_layer (image_ID, layer_ID, 0);
drawable = gimp_drawable_get(layer_ID);
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height,
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
drawable->width, drawable->height,
TRUE, FALSE);
buffer = g_malloc (ph.width * ph.bytes);

View File

@ -42,12 +42,12 @@
'gauss_iir' => { libdep => 'gtk', ui => 1 },
'gauss_rle' => { libdep => 'gtk', ui => 1 },
'gbr' => { libdep => 'gtk', ui => 1 },
'gpb' => { libdep => 'gtk', ui => 1 },
'gee' => { libdep => 'gtk', ui => 1 },
'gee-zoom' => { libdep => 'gtk', ui => 1 },
'gee_zoom' => { libdep => 'gtk', ui => 1 },
'gicon' => { libdep => 'gtk', ui => 1 },
'gif' => { libdep => 'gtk', ui => 1 },
'gifload' => { libdep => 'gtk' },
'gih' => { libdep => 'gtk', ui => 1 },
'glasstile' => { libdep => 'gtk', ui => 1 },
'gqbist' => { libdep => 'gtk', ui => 1 },
'gradmap' => { libdep => 'glib', ui => 1 },

View File

@ -353,7 +353,7 @@ CODE
);
}
@headers = qw("gimplist.h" "gimpbrush.h" "gimpbrushlistP.h" "gimpcontext.h");
@headers = qw("gimplist.h" "gimpbrush.h" "gimpbrushlist.h" "gimpcontext.h");
@procs = qw(brushes_refresh brushes_get_brush brushes_set_brush
brushes_get_opacity brushes_set_opacity brushes_get_spacing