1998-07-09 13:31:06 +08:00
|
|
|
/* The GIMP -- an image manipulation program
|
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* gimp_brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1999-02-21 07:20:54 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
2001-02-05 01:34:30 +08:00
|
|
|
#include <ctype.h>
|
1999-02-21 07:20:54 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2000-12-29 23:22:01 +08:00
|
|
|
#include <gtk/gtk.h>
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-01-24 07:56:18 +08:00
|
|
|
#include "libgimpmath/gimpmath.h"
|
|
|
|
|
2000-12-17 05:37:03 +08:00
|
|
|
#include "apptypes.h"
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
#include "appenv.h"
|
|
|
|
#include "gimpbrushgenerated.h"
|
1998-07-25 18:20:07 +08:00
|
|
|
#include "gimprc.h"
|
1999-08-17 09:05:59 +08:00
|
|
|
#include "gimpbrush.h"
|
2000-12-29 23:22:01 +08:00
|
|
|
#include "temp_buf.h"
|
1998-07-09 13:31:06 +08:00
|
|
|
|
2001-01-22 09:46:28 +08:00
|
|
|
/* this needs to go away */
|
|
|
|
#include "tools/paint_core.h"
|
|
|
|
|
2000-12-29 23:22:01 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
#define OVERSAMPLING 5
|
|
|
|
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
static void gimp_brush_generated_generate (GimpBrushGenerated *brush);
|
1998-07-15 20:15:24 +08:00
|
|
|
|
2000-09-29 20:00:00 +08:00
|
|
|
|
2001-01-10 08:36:54 +08:00
|
|
|
static GimpBrushClass *parent_class = NULL;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
|
|
|
|
static void
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_destroy (GtkObject *object)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
2000-02-24 19:39:26 +08:00
|
|
|
if (GTK_OBJECT_CLASS (parent_class)->destroy)
|
2001-01-10 08:36:54 +08:00
|
|
|
GTK_OBJECT_CLASS (parent_class)->destroy (object);
|
1998-07-09 13:31:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
|
|
|
|
{
|
|
|
|
GtkObjectClass *object_class;
|
2000-02-24 19:39:26 +08:00
|
|
|
|
2001-01-10 08:36:54 +08:00
|
|
|
object_class = (GtkObjectClass *) klass;
|
1998-07-09 13:31:06 +08:00
|
|
|
|
|
|
|
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
2000-02-24 19:39:26 +08:00
|
|
|
object_class->destroy = gimp_brush_generated_destroy;
|
1998-07-09 13:31:06 +08:00
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
static void
|
|
|
|
gimp_brush_generated_init (GimpBrushGenerated *brush)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
2000-02-24 19:39:26 +08:00
|
|
|
brush->radius = 5.0;
|
|
|
|
brush->hardness = 0.0;
|
|
|
|
brush->angle = 0.0;
|
|
|
|
brush->aspect_ratio = 1.0;
|
|
|
|
brush->freeze = 0;
|
1998-07-09 13:31:06 +08:00
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
guint
|
|
|
|
gimp_brush_generated_get_type (void)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
static GtkType type = 0;
|
|
|
|
|
|
|
|
if (!type)
|
|
|
|
{
|
|
|
|
GtkTypeInfo info =
|
|
|
|
{
|
|
|
|
"GimpBrushGenerated",
|
|
|
|
sizeof (GimpBrushGenerated),
|
|
|
|
sizeof (GimpBrushGeneratedClass),
|
|
|
|
(GtkClassInitFunc) gimp_brush_generated_class_init,
|
|
|
|
(GtkObjectInitFunc) gimp_brush_generated_init,
|
|
|
|
/* reserved_1 */ NULL,
|
|
|
|
/* reserved_2 */ NULL,
|
|
|
|
(GtkClassInitFunc) NULL
|
|
|
|
};
|
|
|
|
|
2000-02-24 19:39:26 +08:00
|
|
|
type = gtk_type_unique (GIMP_TYPE_BRUSH, &info);
|
1999-10-27 02:27:27 +08:00
|
|
|
}
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
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
2000-12-18 23:14:08 +08:00
|
|
|
GimpBrush *
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_new (gfloat radius,
|
|
|
|
gfloat hardness,
|
|
|
|
gfloat angle,
|
|
|
|
gfloat aspect_ratio)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
|
|
|
GimpBrushGenerated *brush;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* set up normal brush data */
|
2001-01-14 11:55:56 +08:00
|
|
|
brush = GIMP_BRUSH_GENERATED (gtk_type_new (GIMP_TYPE_BRUSH_GENERATED));
|
|
|
|
|
|
|
|
gimp_object_set_name (GIMP_OBJECT (brush), "Untitled");
|
1998-07-09 13:31:06 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
GIMP_BRUSH (brush)->spacing = 20;
|
1998-07-09 13:31:06 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* set up gimp_brush_generated data */
|
|
|
|
brush->radius = radius;
|
|
|
|
brush->hardness = hardness;
|
|
|
|
brush->angle = angle;
|
1998-07-09 13:31:06 +08:00
|
|
|
brush->aspect_ratio = aspect_ratio;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* render brush mask */
|
|
|
|
gimp_brush_generated_generate (brush);
|
1998-07-09 13:31:06 +08:00
|
|
|
|
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
2000-12-18 23:14:08 +08:00
|
|
|
return GIMP_BRUSH (brush);
|
1998-07-16 19:44:56 +08:00
|
|
|
}
|
|
|
|
|
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
2000-12-18 23:14:08 +08:00
|
|
|
GimpBrush *
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_load (const gchar *file_name)
|
1998-07-16 19:44:56 +08:00
|
|
|
{
|
|
|
|
GimpBrushGenerated *brush;
|
2000-02-24 19:39:26 +08:00
|
|
|
FILE *fp;
|
|
|
|
gchar string[256];
|
|
|
|
gfloat fl;
|
|
|
|
gfloat version;
|
1999-10-27 02:27:27 +08:00
|
|
|
|
2000-02-24 19:39:26 +08:00
|
|
|
if ((fp = fopen (file_name, "rb")) == NULL)
|
1998-07-16 19:44:56 +08:00
|
|
|
return NULL;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* make sure the file we are reading is the right type */
|
|
|
|
fgets (string, 255, fp);
|
2000-09-28 01:50:59 +08:00
|
|
|
|
|
|
|
if (strncmp (string, "GIMP-VBR", 8) != 0)
|
|
|
|
return NULL;
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* make sure we are reading a compatible version */
|
|
|
|
fgets (string, 255, fp);
|
|
|
|
sscanf (string, "%f", &version);
|
|
|
|
g_return_val_if_fail (version < 2.0, NULL);
|
|
|
|
|
|
|
|
/* create new brush */
|
|
|
|
brush =
|
2000-09-29 20:00:00 +08:00
|
|
|
GIMP_BRUSH_GENERATED (gtk_type_new (gimp_brush_generated_get_type ()));
|
1999-10-27 02:27:27 +08:00
|
|
|
|
|
|
|
GIMP_BRUSH (brush)->filename = g_strdup (file_name);
|
|
|
|
|
|
|
|
gimp_brush_generated_freeze (brush);
|
|
|
|
|
|
|
|
/* read name */
|
1999-08-31 04:42:34 +08:00
|
|
|
fgets (string, 255, fp);
|
2000-09-29 20:00:00 +08:00
|
|
|
if (string[strlen (string) - 1] == '\n')
|
|
|
|
string[strlen (string) - 1] = 0;
|
2001-01-14 11:55:56 +08:00
|
|
|
gimp_object_set_name (GIMP_OBJECT (brush), string);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
|
|
|
/* read brush spacing */
|
|
|
|
fscanf (fp, "%f", &fl);
|
|
|
|
GIMP_BRUSH (brush)->spacing = fl;
|
|
|
|
|
|
|
|
/* read brush radius */
|
|
|
|
fscanf (fp, "%f", &fl);
|
|
|
|
gimp_brush_generated_set_radius (brush, fl);
|
|
|
|
|
|
|
|
/* read brush hardness */
|
|
|
|
fscanf (fp, "%f", &fl);
|
|
|
|
gimp_brush_generated_set_hardness (brush, fl);
|
|
|
|
|
|
|
|
/* read brush aspect_ratio */
|
|
|
|
fscanf (fp, "%f", &fl);
|
|
|
|
gimp_brush_generated_set_aspect_ratio (brush, fl);
|
|
|
|
|
|
|
|
/* read brush angle */
|
|
|
|
fscanf (fp, "%f", &fl);
|
|
|
|
gimp_brush_generated_set_angle (brush, fl);
|
|
|
|
|
|
|
|
fclose (fp);
|
|
|
|
|
|
|
|
gimp_brush_generated_thaw (brush);
|
1998-07-09 13:31:06 +08:00
|
|
|
|
1998-07-25 18:20:07 +08:00
|
|
|
if (stingy_memory_use)
|
1999-10-27 02:27:27 +08:00
|
|
|
temp_buf_swap (GIMP_BRUSH (brush)->mask);
|
1998-07-25 18:20:07 +08:00
|
|
|
|
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
2000-12-18 23:14:08 +08:00
|
|
|
return GIMP_BRUSH (brush);
|
1998-07-09 13:31:06 +08:00
|
|
|
}
|
|
|
|
|
1998-07-16 19:44:56 +08:00
|
|
|
void
|
2001-02-05 01:34:30 +08:00
|
|
|
gimp_brush_generated_save (GimpBrushGenerated *brush,
|
|
|
|
const gchar *directory)
|
1998-07-16 19:44:56 +08:00
|
|
|
{
|
2001-02-05 01:34:30 +08:00
|
|
|
FILE *fp;
|
|
|
|
gchar *filename = NULL;
|
1999-10-27 02:27:27 +08:00
|
|
|
|
2001-02-05 01:34:30 +08:00
|
|
|
g_return_if_fail (brush != NULL);
|
|
|
|
g_return_if_fail (GIMP_IS_BRUSH_GENERATED (brush));
|
|
|
|
g_return_if_fail (directory != NULL);
|
|
|
|
|
|
|
|
if (! GIMP_BRUSH (brush)->filename)
|
|
|
|
{
|
|
|
|
gchar *safe_name;
|
|
|
|
gint i;
|
|
|
|
gint unum = 1;
|
|
|
|
|
|
|
|
/* make sure we don't create a naughty filename */
|
|
|
|
safe_name = g_strdup (GIMP_OBJECT (brush)->name);
|
|
|
|
if (safe_name[0] == '.')
|
|
|
|
safe_name[0] = '_';
|
|
|
|
for (i = 0; safe_name[i]; i++)
|
|
|
|
if (safe_name[i] == G_DIR_SEPARATOR || isspace (safe_name[i]))
|
|
|
|
safe_name[i] = '_';
|
|
|
|
|
|
|
|
filename = g_strdup_printf ("%s%s.vbr",
|
|
|
|
directory, safe_name);
|
|
|
|
|
|
|
|
while ((fp = fopen (filename, "r")))
|
|
|
|
{
|
|
|
|
/* make sure we don't overite an existing brush */
|
|
|
|
fclose (fp);
|
|
|
|
g_free (filename);
|
|
|
|
filename = g_strdup_printf ("%s%s_%d.vbr",
|
|
|
|
directory, safe_name, unum);
|
|
|
|
unum++;
|
|
|
|
}
|
|
|
|
g_free (safe_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
filename = g_strdup (GIMP_BRUSH (brush)->filename);
|
|
|
|
|
|
|
|
if (strlen(filename) < 4 || strcmp (&filename[strlen (filename) - 4],
|
|
|
|
".vbr"))
|
|
|
|
{
|
|
|
|
/* we only want to save .vbr files, so set filename to null
|
|
|
|
* if this isn't a .vbr file
|
|
|
|
*/
|
|
|
|
g_free (filename);
|
|
|
|
filename = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! filename)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* we are (finaly) ready to try to save the generated brush file */
|
|
|
|
if ((fp = fopen (filename, "wb")) == NULL)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
2001-02-05 01:34:30 +08:00
|
|
|
g_warning ("Unable to save file %s", filename);
|
1999-10-27 02:27:27 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write magic header */
|
|
|
|
fprintf (fp, "GIMP-VBR\n");
|
|
|
|
|
|
|
|
/* write version */
|
|
|
|
fprintf (fp, "1.0\n");
|
|
|
|
|
|
|
|
/* write name */
|
2001-01-14 11:55:56 +08:00
|
|
|
fprintf (fp, "%.255s\n", GIMP_OBJECT (brush)->name);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
|
|
|
/* write brush spacing */
|
2001-01-14 11:55:56 +08:00
|
|
|
fprintf (fp, "%f\n", (gfloat) GIMP_BRUSH (brush)->spacing);
|
1999-10-27 02:27:27 +08:00
|
|
|
|
|
|
|
/* write brush radius */
|
|
|
|
fprintf (fp, "%f\n", brush->radius);
|
|
|
|
|
|
|
|
/* write brush hardness */
|
|
|
|
fprintf (fp, "%f\n", brush->hardness);
|
|
|
|
|
|
|
|
/* write brush aspect_ratio */
|
|
|
|
fprintf (fp, "%f\n", brush->aspect_ratio);
|
|
|
|
|
|
|
|
/* write brush angle */
|
|
|
|
fprintf (fp, "%f\n", brush->angle);
|
|
|
|
|
|
|
|
fclose (fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_brush_generated_delete (GimpBrushGenerated *brush)
|
|
|
|
{
|
|
|
|
if (GIMP_BRUSH (brush)->filename)
|
|
|
|
{
|
|
|
|
unlink (GIMP_BRUSH (brush)->filename);
|
|
|
|
}
|
1998-07-16 19:44:56 +08:00
|
|
|
}
|
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
void
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_freeze (GimpBrushGenerated *brush)
|
1998-07-15 20:15:24 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (brush != NULL);
|
|
|
|
g_return_if_fail (GIMP_IS_BRUSH_GENERATED (brush));
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
brush->freeze++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_thaw (GimpBrushGenerated *brush)
|
1998-07-15 20:15:24 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (brush != NULL);
|
|
|
|
g_return_if_fail (GIMP_IS_BRUSH_GENERATED (brush));
|
|
|
|
|
|
|
|
if (brush->freeze > 0)
|
|
|
|
brush->freeze--;
|
1999-10-27 02:27:27 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (brush->freeze == 0)
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_generate (brush);
|
1998-07-15 20:15:24 +08:00
|
|
|
}
|
1998-07-25 18:20:07 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
static double
|
|
|
|
gauss (gdouble f)
|
1999-09-02 17:20:48 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
/* this aint' a real gauss function */
|
|
|
|
if (f < -.5)
|
1998-07-24 16:56:18 +08:00
|
|
|
{
|
2000-09-29 20:00:00 +08:00
|
|
|
f = -1.0 - f;
|
2000-02-24 19:39:26 +08:00
|
|
|
return (2.0 * f*f);
|
1998-07-24 16:56:18 +08:00
|
|
|
}
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
if (f < .5)
|
2000-02-24 19:39:26 +08:00
|
|
|
return (1.0 - 2.0 * f*f);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
f = 1.0 -f;
|
2000-02-24 19:39:26 +08:00
|
|
|
return (2.0 * f*f);
|
1998-07-24 16:56:18 +08:00
|
|
|
}
|
1998-07-15 20:15:24 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
void
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_generate (GimpBrushGenerated *brush)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
|
|
|
register GimpBrush *gbrush = NULL;
|
2000-09-29 20:00:00 +08:00
|
|
|
register gint x, y;
|
|
|
|
register guchar *centerp;
|
|
|
|
register gdouble d;
|
|
|
|
register gdouble exponent;
|
|
|
|
register guchar a;
|
|
|
|
register gint length;
|
|
|
|
register guchar *lookup;
|
|
|
|
register gdouble sum, c, s, tx, ty;
|
2000-02-24 19:39:26 +08:00
|
|
|
gdouble buffer[OVERSAMPLING];
|
2000-09-29 20:00:00 +08:00
|
|
|
gint width, height;
|
2000-02-24 19:39:26 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
g_return_if_fail (brush != NULL);
|
|
|
|
g_return_if_fail (GIMP_IS_BRUSH_GENERATED (brush));
|
|
|
|
|
|
|
|
if (brush->freeze) /* if we are frozen defer rerendering till later */
|
1998-07-09 13:31:06 +08:00
|
|
|
return;
|
1998-07-25 18:20:07 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gbrush = GIMP_BRUSH (brush);
|
1998-07-25 18:20:07 +08:00
|
|
|
|
|
|
|
if (stingy_memory_use && gbrush->mask)
|
|
|
|
temp_buf_unswap (gbrush->mask);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if (gbrush->mask)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
|
|
|
temp_buf_free(gbrush->mask);
|
|
|
|
}
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-20 22:05:33 +08:00
|
|
|
/* compute the range of the brush. should do a better job than this? */
|
2000-02-19 02:20:04 +08:00
|
|
|
s = sin (gimp_deg_to_rad (brush->angle));
|
|
|
|
c = cos (gimp_deg_to_rad (brush->angle));
|
2000-09-29 20:00:00 +08:00
|
|
|
|
2000-01-26 07:06:12 +08:00
|
|
|
tx = MAX (fabs (c*ceil (brush->radius) - s*ceil (brush->radius)
|
|
|
|
/ brush->aspect_ratio),
|
|
|
|
fabs (c*ceil (brush->radius) + s*ceil (brush->radius)
|
|
|
|
/ brush->aspect_ratio));
|
|
|
|
ty = MAX (fabs (s*ceil (brush->radius) + c*ceil (brush->radius)
|
|
|
|
/ brush->aspect_ratio),
|
|
|
|
fabs (s*ceil (brush->radius) - c*ceil (brush->radius)
|
|
|
|
/ brush->aspect_ratio));
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if (brush->radius > tx)
|
1999-10-27 02:27:27 +08:00
|
|
|
width = ceil (tx);
|
1998-07-09 13:31:06 +08:00
|
|
|
else
|
1999-10-27 02:27:27 +08:00
|
|
|
width = ceil (brush->radius);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if (brush->radius > ty)
|
1999-10-27 02:27:27 +08:00
|
|
|
height = ceil (ty);
|
1998-07-09 13:31:06 +08:00
|
|
|
else
|
1999-10-27 02:27:27 +08:00
|
|
|
height = ceil (brush->radius);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-24 16:56:18 +08:00
|
|
|
/* compute the axis for spacing */
|
2000-09-29 20:00:00 +08:00
|
|
|
GIMP_BRUSH (brush)->x_axis.x = c * brush->radius;
|
|
|
|
GIMP_BRUSH (brush)->x_axis.y = -1.0 * s * brush->radius;
|
1998-07-09 13:31:06 +08:00
|
|
|
|
2000-09-29 20:00:00 +08:00
|
|
|
GIMP_BRUSH (brush)->y_axis.x = (s * brush->radius / brush->aspect_ratio);
|
|
|
|
GIMP_BRUSH (brush)->y_axis.y = (c * brush->radius / brush->aspect_ratio);
|
1998-07-24 16:56:18 +08:00
|
|
|
|
2000-09-29 20:00:00 +08:00
|
|
|
gbrush->mask = temp_buf_new (width * 2 + 1,
|
|
|
|
height * 2 + 1,
|
1999-10-27 02:27:27 +08:00
|
|
|
1, width, height, 0);
|
2000-09-29 20:00:00 +08:00
|
|
|
centerp = &gbrush->mask->data[height * gbrush->mask->width + width];
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if ((1.0 - brush->hardness) < 0.000001)
|
|
|
|
exponent = 1000000;
|
|
|
|
else
|
|
|
|
exponent = 1/(1.0 - brush->hardness);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
/* set up lookup table */
|
2000-09-29 20:00:00 +08:00
|
|
|
length = ceil (sqrt (2 * ceil (brush->radius+1) * ceil (brush->radius+1))+1) * OVERSAMPLING;
|
1999-10-27 02:27:27 +08:00
|
|
|
lookup = g_malloc (length);
|
1998-07-09 13:31:06 +08:00
|
|
|
sum = 0.0;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
for (x = 0; x < OVERSAMPLING; x++)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
2000-09-29 20:00:00 +08:00
|
|
|
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
|
1999-10-27 02:27:27 +08:00
|
|
|
if (d > brush->radius)
|
2000-09-29 20:00:00 +08:00
|
|
|
buffer[x] = 0.0;
|
|
|
|
else
|
|
|
|
/* buffer[x] = (1.0 - pow (d/brush->radius, exponent)); */
|
|
|
|
buffer[x] = gauss (pow (d/brush->radius, exponent));
|
|
|
|
sum += buffer[x];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (x = 0; d < brush->radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
|
|
|
|
{
|
|
|
|
sum -= buffer[x % OVERSAMPLING];
|
|
|
|
if (d > brush->radius)
|
|
|
|
buffer[x % OVERSAMPLING] = 0.0;
|
1999-10-27 02:27:27 +08:00
|
|
|
else
|
|
|
|
/* buffer[x%OVERSAMPLING] = (1.0 - pow (d/brush->radius, exponent)); */
|
2000-09-29 20:00:00 +08:00
|
|
|
buffer[x % OVERSAMPLING] = gauss (pow (d/brush->radius, exponent));
|
1999-10-27 02:27:27 +08:00
|
|
|
sum += buffer[x%OVERSAMPLING];
|
2000-09-29 20:00:00 +08:00
|
|
|
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
|
1999-10-27 02:27:27 +08:00
|
|
|
}
|
1998-07-09 13:31:06 +08:00
|
|
|
while (x < length)
|
1999-10-27 02:27:27 +08:00
|
|
|
{
|
|
|
|
lookup[x++] = 0;
|
|
|
|
}
|
|
|
|
/* compute one half and mirror it */
|
1998-07-09 13:31:06 +08:00
|
|
|
for (y = 0; y <= height; y++)
|
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
for (x = -width; x <= width; x++)
|
|
|
|
{
|
|
|
|
tx = c*x - s*y;
|
|
|
|
ty = c*y + s*x;
|
|
|
|
ty *= brush->aspect_ratio;
|
|
|
|
d = sqrt (tx*tx + ty*ty);
|
|
|
|
if (d < brush->radius+1)
|
2000-09-29 20:00:00 +08:00
|
|
|
a = lookup[(gint) RINT (d * OVERSAMPLING)];
|
1999-10-27 02:27:27 +08:00
|
|
|
else
|
|
|
|
a = 0;
|
|
|
|
centerp[ y*gbrush->mask->width + x] = a;
|
|
|
|
centerp[-1*y*gbrush->mask->width - x] = a;
|
|
|
|
}
|
1998-07-09 13:31:06 +08:00
|
|
|
}
|
|
|
|
g_free (lookup);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gtk_signal_emit_by_name (GTK_OBJECT (brush), "dirty");
|
1998-07-09 13:31:06 +08:00
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
|
|
|
gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
|
|
|
|
gfloat radius)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if (radius < 0.0)
|
|
|
|
radius = 0.0;
|
2000-02-24 19:39:26 +08:00
|
|
|
else if (radius > 32767.0)
|
1998-07-09 13:31:06 +08:00
|
|
|
radius = 32767.0;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (radius == brush->radius)
|
|
|
|
return radius;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
brush->radius = radius;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (!brush->freeze)
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_generate (brush);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->radius;
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
|
|
|
gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
|
|
|
|
gfloat hardness)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if (hardness < 0.0)
|
|
|
|
hardness = 0.0;
|
2000-09-29 20:00:00 +08:00
|
|
|
else if (hardness > 1.0)
|
1998-07-09 13:31:06 +08:00
|
|
|
hardness = 1.0;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (brush->hardness == hardness)
|
|
|
|
return hardness;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
brush->hardness = hardness;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (!brush->freeze)
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_generate (brush);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->hardness;
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
|
|
|
gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
|
|
|
|
gfloat angle)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if (angle < 0.0)
|
1999-10-27 02:27:27 +08:00
|
|
|
angle = -1.0 * fmod (angle, 180.0);
|
2000-09-29 20:00:00 +08:00
|
|
|
else if (angle > 180.0)
|
1999-10-27 02:27:27 +08:00
|
|
|
angle = fmod (angle, 180.0);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (brush->angle == angle)
|
|
|
|
return angle;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
brush->angle = angle;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (!brush->freeze)
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_brush_generated_generate (brush);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->angle;
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
|
|
|
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
|
|
|
|
gfloat ratio)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
if (ratio < 1.0)
|
|
|
|
ratio = 1.0;
|
2000-09-29 20:00:00 +08:00
|
|
|
else if (ratio > 1000)
|
1998-07-09 13:31:06 +08:00
|
|
|
ratio = 1000;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (brush->aspect_ratio == ratio)
|
|
|
|
return ratio;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
brush->aspect_ratio = ratio;
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-15 20:15:24 +08:00
|
|
|
if (!brush->freeze)
|
|
|
|
gimp_brush_generated_generate(brush);
|
2000-09-29 20:00:00 +08:00
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->aspect_ratio;
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
|
|
|
gimp_brush_generated_get_radius (const GimpBrushGenerated *brush)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->radius;
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
2000-09-29 20:00:00 +08:00
|
|
|
gimp_brush_generated_get_hardness (const GimpBrushGenerated *brush)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->hardness;
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
2000-09-29 20:00:00 +08:00
|
|
|
gimp_brush_generated_get_angle (const GimpBrushGenerated *brush)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->angle;
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gfloat
|
2000-09-29 20:00:00 +08:00
|
|
|
gimp_brush_generated_get_aspect_ratio (const GimpBrushGenerated *brush)
|
1998-07-09 13:31:06 +08:00
|
|
|
{
|
1999-10-27 02:27:27 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
|
|
|
|
|
1998-07-09 13:31:06 +08:00
|
|
|
return brush->aspect_ratio;
|
|
|
|
}
|