mirror of https://github.com/GNOME/gimp.git
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:
parent
333bfaf5b6
commit
3cff8419db
77
ChangeLog
77
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpcontext.h"
|
||||
|
||||
|
||||
typedef struct _BrushSelect BrushSelect;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpbrushlistP.h"
|
||||
#include "gimpbrushlist.h"
|
||||
#include "gimpcontext.h"
|
||||
#include "gimplist.h"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ¶mstring, 10);
|
||||
}
|
||||
num_of_brushes = strtol (buf, ¶mstring, 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);
|
||||
}
|
||||
|
|
|
@ -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, ¶mstring, 10);
|
||||
}
|
||||
num_of_brushes = strtol (buf, ¶mstring, 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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gimpdrawableP.h"
|
||||
#include "gimppreviewcache.h"
|
||||
#include "gimpsignal.h"
|
||||
#include "gimage.h"
|
||||
#include "gimage_mask.h"
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "gimpobject.h"
|
||||
#include "gimpsignal.h"
|
||||
#include "gimplistP.h"
|
||||
#include "gimplist.h"
|
||||
|
||||
|
||||
/* code mostly ripped from nether's gimpset class */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobject.h"
|
||||
#include "gimpobjectP.h"
|
||||
|
||||
|
||||
static void
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -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"
|
||||
|
|
252
app/gimpbrush.c
252
app/gimpbrush.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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__ */
|
|
@ -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, ¶mstring, 10);
|
||||
}
|
||||
num_of_brushes = strtol (buf, ¶mstring, 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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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__ */
|
|
@ -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;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gimpdrawableP.h"
|
||||
#include "gimppreviewcache.h"
|
||||
#include "gimpsignal.h"
|
||||
#include "gimage.h"
|
||||
#include "gimage_mask.h"
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpimageP.h"
|
||||
|
||||
#include "cursorutil.h"
|
||||
#include "drawable.h"
|
||||
#include "floating_sel.h"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <gtk/gtk.h> /* eeeek */
|
||||
|
||||
#include "gimpobjectP.h"
|
||||
#include "gimpobject.h"
|
||||
#include "gimpimage.h"
|
||||
|
||||
#include "tile_manager.h"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "gimpobject.h"
|
||||
#include "gimpsignal.h"
|
||||
#include "gimplistP.h"
|
||||
#include "gimplist.h"
|
||||
|
||||
|
||||
/* code mostly ripped from nether's gimpset class */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "apptypes.h"
|
||||
|
||||
#include "gimpobject.h"
|
||||
#include "gimpobjectP.h"
|
||||
|
||||
|
||||
static void
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
|
||||
#include "gimpbrush.h"
|
||||
#include "gimpcontext.h"
|
||||
|
||||
|
||||
typedef struct _BrushSelect BrushSelect;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
172
app/patterns.c
172
app/patterns.c
|
@ -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);
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -50,8 +50,8 @@ gee_zoom
|
|||
gicon
|
||||
gif
|
||||
gifload
|
||||
gih
|
||||
glasstile
|
||||
gpb
|
||||
gqbist
|
||||
gradmap
|
||||
grid
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue