app/core/core-enums.h Implement three different brush shapes for generated

2004-08-01  Simon Budig  <simon@gimp.org>

	* app/core/core-enums.h
	* app/core/gimpbrushgenerated.[ch]: Implement three different
	brush shapes for generated brushes.

	* app/core/gimpbrush.c: changed accordingly.
	* app/core/core-enums.c: regenerated.

	* app/widgets/gimpbrusheditor.[ch]: Add toggles for the shape.
	* themes/Default/images/stock-brush-generated-*-16.png: New stock
	icons for the brush shapes.

	* themes/Default/images/Makefile.am
	* libgimpwidgets/gimpstock.[ch]: changed accordingly

	untabified the files touched.
This commit is contained in:
Simon Budig 2004-08-01 03:06:58 +00:00 committed by Simon Budig
parent 286c7c7c90
commit c40e29399d
17 changed files with 719 additions and 226 deletions

View file

@ -1,3 +1,21 @@
2004-08-01 Simon Budig <simon@gimp.org>
* app/core/core-enums.h
* app/core/gimpbrushgenerated.[ch]: Implement three different
brush shapes for generated brushes.
* app/core/gimpbrush.c: changed accordingly.
* app/core/core-enums.c: regenerated.
* app/widgets/gimpbrusheditor.[ch]: Add toggles for the shape.
* themes/Default/images/stock-brush-generated-*-16.png: New stock
icons for the brush shapes.
* themes/Default/images/Makefile.am
* libgimpwidgets/gimpstock.[ch]: changed accordingly
untabified the files touched.
2004-08-01 DindinX <david@dindinx.org>
* plug-ins/common/iwarp.c: ported to GimpPreviewArea.

View file

@ -346,6 +346,25 @@ gimp_icon_type_get_type (void)
return type;
}
GType
gimp_brush_generated_shape_get_type (void)
{
static const GEnumValue values[] =
{
{ GIMP_BRUSH_GENERATED_CIRCLE, N_("Circle"), "circle" },
{ GIMP_BRUSH_GENERATED_SQUARE, N_("Square"), "square" },
{ GIMP_BRUSH_GENERATED_DIAMOND, N_("Diamond"), "diamond" },
{ 0, NULL, NULL }
};
static GType type = 0;
if (! type)
type = g_enum_register_static ("GimpBrushGeneratedShape", values);
return type;
}
GType
gimp_orientation_type_get_type (void)
{

View file

@ -264,6 +264,18 @@ typedef enum
} GimpIconType;
#define GIMP_TYPE_BRUSH_GENERATED_SHAPE (gimp_brush_generated_shape_get_type ())
GType gimp_brush_generated_shape_get_type (void) G_GNUC_CONST;
typedef enum /*< pdb-skip >*/
{
GIMP_BRUSH_GENERATED_CIRCLE, /*< desc="Circle" >*/
GIMP_BRUSH_GENERATED_SQUARE, /*< desc="Square" >*/
GIMP_BRUSH_GENERATED_DIAMOND /*< desc="Diamond" >*/
} GimpBrushGeneratedShape;
#define GIMP_TYPE_ORIENTATION_TYPE (gimp_orientation_type_get_type ())
GType gimp_orientation_type_get_type (void) G_GNUC_CONST;
@ -548,21 +560,21 @@ typedef enum /*< pdb-skip, skip >*/
/* aliases */
GIMP_CONTEXT_PAINT_PROPS_MASK = (GIMP_CONTEXT_FOREGROUND_MASK |
GIMP_CONTEXT_BACKGROUND_MASK |
GIMP_CONTEXT_OPACITY_MASK |
GIMP_CONTEXT_PAINT_MODE_MASK |
GIMP_CONTEXT_BRUSH_MASK |
GIMP_CONTEXT_PATTERN_MASK |
GIMP_CONTEXT_GRADIENT_MASK),
GIMP_CONTEXT_BACKGROUND_MASK |
GIMP_CONTEXT_OPACITY_MASK |
GIMP_CONTEXT_PAINT_MODE_MASK |
GIMP_CONTEXT_BRUSH_MASK |
GIMP_CONTEXT_PATTERN_MASK |
GIMP_CONTEXT_GRADIENT_MASK),
GIMP_CONTEXT_ALL_PROPS_MASK = (GIMP_CONTEXT_IMAGE_MASK |
GIMP_CONTEXT_DISPLAY_MASK |
GIMP_CONTEXT_TOOL_MASK |
GIMP_CONTEXT_PALETTE_MASK |
GIMP_CONTEXT_FONT_MASK |
GIMP_CONTEXT_BUFFER_MASK |
GIMP_CONTEXT_IMAGEFILE_MASK |
GIMP_CONTEXT_TEMPLATE_MASK |
GIMP_CONTEXT_PAINT_PROPS_MASK)
GIMP_CONTEXT_DISPLAY_MASK |
GIMP_CONTEXT_TOOL_MASK |
GIMP_CONTEXT_PALETTE_MASK |
GIMP_CONTEXT_FONT_MASK |
GIMP_CONTEXT_BUFFER_MASK |
GIMP_CONTEXT_IMAGEFILE_MASK |
GIMP_CONTEXT_TEMPLATE_MASK |
GIMP_CONTEXT_PAINT_PROPS_MASK)
} GimpContextPropMask;
typedef enum /*< skip >*/

View file

@ -111,8 +111,8 @@ gimp_brush_get_type (void)
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_brush_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpBrush),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_brush_init,
@ -268,10 +268,10 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
if (pixmap_buf)
{
/* TODO: the scale function should scale the pixmap and the
* mask in one run
*/
* mask in one run
*/
pixmap_buf =
brush_scale_pixmap (pixmap_buf, brush_width, brush_height);
brush_scale_pixmap (pixmap_buf, brush_width, brush_height);
}
scale = TRUE;
@ -349,7 +349,9 @@ gimp_brush_new (const gchar *name,
{
g_return_val_if_fail (name != NULL, NULL);
return gimp_brush_generated_new (name, 5.0, 0.5, 1.0, 0.0,
return gimp_brush_generated_new (name,
GIMP_BRUSH_GENERATED_CIRCLE,
5.0, 0.5, 1.0, 0.0,
stingy_memory_use);
}
@ -484,7 +486,7 @@ gimp_brush_get_spacing (const GimpBrush *brush)
void
gimp_brush_set_spacing (GimpBrush *brush,
gint spacing)
gint spacing)
{
g_return_if_fail (GIMP_IS_BRUSH (brush));
@ -528,7 +530,7 @@ gimp_brush_load_brush (gint fd,
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Could not read %d bytes from '%s': %s"),
(gint) sizeof (header),
gimp_filename_to_utf8 (filename), g_strerror (errno));
gimp_filename_to_utf8 (filename), g_strerror (errno));
return NULL;
}
@ -588,14 +590,14 @@ gimp_brush_load_brush (gint fd,
name = g_new (gchar, bn_size);
if ((read (fd, name, bn_size)) < bn_size)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"File appears truncated."),
gimp_filename_to_utf8 (filename));
g_free (name);
return NULL;
}
g_free (name);
return NULL;
}
utf8 = gimp_any_to_utf8 (name, -1,
_("Invalid UTF-8 string in brush file '%s'."),

View file

@ -111,8 +111,8 @@ gimp_brush_get_type (void)
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_brush_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpBrush),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_brush_init,
@ -268,10 +268,10 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
if (pixmap_buf)
{
/* TODO: the scale function should scale the pixmap and the
* mask in one run
*/
* mask in one run
*/
pixmap_buf =
brush_scale_pixmap (pixmap_buf, brush_width, brush_height);
brush_scale_pixmap (pixmap_buf, brush_width, brush_height);
}
scale = TRUE;
@ -349,7 +349,9 @@ gimp_brush_new (const gchar *name,
{
g_return_val_if_fail (name != NULL, NULL);
return gimp_brush_generated_new (name, 5.0, 0.5, 1.0, 0.0,
return gimp_brush_generated_new (name,
GIMP_BRUSH_GENERATED_CIRCLE,
5.0, 0.5, 1.0, 0.0,
stingy_memory_use);
}
@ -484,7 +486,7 @@ gimp_brush_get_spacing (const GimpBrush *brush)
void
gimp_brush_set_spacing (GimpBrush *brush,
gint spacing)
gint spacing)
{
g_return_if_fail (GIMP_IS_BRUSH (brush));
@ -528,7 +530,7 @@ gimp_brush_load_brush (gint fd,
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Could not read %d bytes from '%s': %s"),
(gint) sizeof (header),
gimp_filename_to_utf8 (filename), g_strerror (errno));
gimp_filename_to_utf8 (filename), g_strerror (errno));
return NULL;
}
@ -588,14 +590,14 @@ gimp_brush_load_brush (gint fd,
name = g_new (gchar, bn_size);
if ((read (fd, name, bn_size)) < bn_size)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"File appears truncated."),
gimp_filename_to_utf8 (filename));
g_free (name);
return NULL;
}
g_free (name);
return NULL;
}
utf8 = gimp_any_to_utf8 (name, -1,
_("Invalid UTF-8 string in brush file '%s'."),

View file

@ -48,6 +48,7 @@
enum
{
PROP_0,
PROP_SHAPE,
PROP_RADIUS,
PROP_HARDNESS,
PROP_ASPECT_RATIO,
@ -92,8 +93,8 @@ gimp_brush_generated_get_type (void)
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_brush_generated_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpBrushGenerated),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_brush_generated_init,
@ -123,6 +124,12 @@ gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
data_class->get_extension = gimp_brush_generated_get_extension;
data_class->duplicate = gimp_brush_generated_duplicate;
g_object_class_install_property (object_class, PROP_SHAPE,
g_param_spec_enum ("shape", NULL, NULL,
GIMP_TYPE_BRUSH_GENERATED_SHAPE,
GIMP_BRUSH_GENERATED_CIRCLE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_RADIUS,
g_param_spec_double ("radius", NULL, NULL,
1.0, 1000.0, 5.0,
@ -149,6 +156,7 @@ gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
static void
gimp_brush_generated_init (GimpBrushGenerated *brush)
{
brush->shape = GIMP_BRUSH_GENERATED_CIRCLE;
brush->radius = 5.0;
brush->hardness = 0.0;
brush->aspect_ratio = 1.0;
@ -165,6 +173,9 @@ gimp_brush_generated_set_property (GObject *object,
switch (property_id)
{
case PROP_SHAPE:
gimp_brush_generated_set_shape (brush, g_value_get_enum (value));
break;
case PROP_RADIUS:
gimp_brush_generated_set_radius (brush, g_value_get_double (value));
break;
@ -193,6 +204,9 @@ gimp_brush_generated_get_property (GObject *object,
switch (property_id)
{
case PROP_SHAPE:
g_value_set_enum (value, brush->shape);
break;
case PROP_RADIUS:
g_value_set_double (value, brush->angle);
break;
@ -226,7 +240,7 @@ gimp_brush_generated_save (GimpData *data,
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN,
_("Could not open '%s' for writing: %s"),
gimp_filename_to_utf8 (data->filename),
g_strerror (errno));
g_strerror (errno));
return FALSE;
}
@ -234,11 +248,26 @@ gimp_brush_generated_save (GimpData *data,
fprintf (file, "GIMP-VBR\n");
/* write version */
fprintf (file, "1.0\n");
if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE)
fprintf (file, "1.5\n");
else
fprintf (file, "1.0\n");
/* write name */
fprintf (file, "%.255s\n", GIMP_OBJECT (brush)->name);
if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE)
{
GEnumClass *enum_class;
GEnumValue *shape_val;
enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE);
/* write shape */
shape_val = g_enum_get_value (enum_class, brush->shape);
fprintf (file, "%s\n", shape_val->value_nick);
}
/* write brush spacing */
fprintf (file, "%s\n",
g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f",
@ -282,10 +311,11 @@ gimp_brush_generated_duplicate (GimpData *data,
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data);
return gimp_brush_generated_new (GIMP_OBJECT (brush)->name,
brush->shape,
brush->radius,
brush->hardness,
brush->aspect_ratio,
brush->angle,
brush->hardness,
brush->aspect_ratio,
brush->angle,
stingy_memory_use);
}
@ -337,14 +367,27 @@ gimp_brush_generated_dirty (GimpData *data)
gbrush->y_axis.x = s * short_radius;
gbrush->y_axis.y = c * short_radius;
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
gbrush->y_axis.x * gbrush->y_axis.x));
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
gbrush->y_axis.y * gbrush->y_axis.y));
switch (brush->shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
gbrush->y_axis.x * gbrush->y_axis.x));
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
gbrush->y_axis.y * gbrush->y_axis.y));
break;
case GIMP_BRUSH_GENERATED_SQUARE:
width = ceil (fabs (gbrush->x_axis.x) + fabs (gbrush->y_axis.x));
height = ceil (fabs (gbrush->x_axis.y) + fabs (gbrush->y_axis.y));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
width = ceil (MAX (fabs (gbrush->x_axis.x), fabs (gbrush->y_axis.x)));
height = ceil (MAX (fabs (gbrush->x_axis.y), fabs (gbrush->y_axis.y)));
break;
}
gbrush->mask = temp_buf_new (width * 2 + 1,
height * 2 + 1,
1, width, height, 0);
height * 2 + 1,
1, width, height, 0);
centerp = temp_buf_data (gbrush->mask) + height * gbrush->mask->width + width;
@ -366,9 +409,9 @@ gimp_brush_generated_dirty (GimpData *data)
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
if (d > brush->radius)
buffer[x] = 0.0;
buffer[x] = 0.0;
else
buffer[x] = gauss (pow (d / brush->radius, exponent));
buffer[x] = gauss (pow (d / brush->radius, exponent));
sum += buffer[x];
}
@ -378,9 +421,9 @@ gimp_brush_generated_dirty (GimpData *data)
sum -= buffer[x % OVERSAMPLING];
if (d > brush->radius)
buffer[x % OVERSAMPLING] = 0.0;
buffer[x % OVERSAMPLING] = 0.0;
else
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
sum += buffer[x % OVERSAMPLING];
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
@ -395,22 +438,33 @@ gimp_brush_generated_dirty (GimpData *data)
for (y = 0; y <= height; y++)
{
for (x = -width; x <= width; x++)
{
{
gdouble tx, ty;
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
d = sqrt (tx*tx + ty*ty);
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
switch (brush->shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
d = sqrt (tx*tx + ty*ty);
break;
case GIMP_BRUSH_GENERATED_SQUARE:
d = MAX (fabs (tx), fabs (ty));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
d = fabs (tx) + fabs (ty);
break;
}
if (d < brush->radius + 1)
a = lookup[(gint) RINT (d * OVERSAMPLING)];
else
a = 0;
if (d < brush->radius + 1)
a = lookup[(gint) RINT (d * OVERSAMPLING)];
else
a = 0;
centerp[ y * gbrush->mask->width + x] = a;
centerp[-1 * y * gbrush->mask->width - x] = a;
}
centerp[ y * gbrush->mask->width + x] = a;
centerp[-1 * y * gbrush->mask->width - x] = a;
}
}
g_free (lookup);
@ -420,18 +474,20 @@ gimp_brush_generated_dirty (GimpData *data)
}
GimpData *
gimp_brush_generated_new (const gchar *name,
gfloat radius,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gboolean stingy_memory_use)
gimp_brush_generated_new (const gchar *name,
GimpBrushGeneratedShape shape,
gfloat radius,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gboolean stingy_memory_use)
{
GimpBrushGenerated *brush;
g_return_val_if_fail (name != NULL, NULL);
brush = g_object_new (GIMP_TYPE_BRUSH_GENERATED,
"shape", shape,
"name", name,
"radius", radius,
"hardness", hardness,
@ -455,15 +511,17 @@ gimp_brush_generated_load (const gchar *filename,
gboolean stingy_memory_use,
GError **error)
{
GimpBrushGenerated *brush;
FILE *file;
gchar string[256];
gchar *name = NULL;
gdouble spacing;
gdouble radius;
gdouble hardness;
gdouble aspect_ratio;
gdouble angle;
GimpBrushGenerated *brush;
FILE *file;
gchar string[256];
gchar *name = NULL;
GimpBrushGeneratedShape shape = GIMP_BRUSH_GENERATED_CIRCLE;
gboolean have_shape = FALSE;
gdouble spacing;
gdouble radius;
gdouble hardness;
gdouble aspect_ratio;
gdouble angle;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (g_path_is_absolute (filename), NULL);
@ -500,11 +558,18 @@ gimp_brush_generated_load (const gchar *filename,
if (strncmp (string, "1.0", 3))
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush version."),
gimp_filename_to_utf8 (filename));
return NULL;
if (strncmp (string, "1.5", 3))
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush version."),
gimp_filename_to_utf8 (filename));
return NULL;
}
else
{
have_shape = TRUE;
}
}
/* read name */
@ -517,6 +582,33 @@ gimp_brush_generated_load (const gchar *filename,
_("Invalid UTF-8 string in brush file '%s'."),
gimp_filename_to_utf8 (filename));
if (have_shape)
{
GEnumClass *enum_class;
GEnumValue *shape_val;
enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE);
/* read shape */
errno = 0;
if (! fgets (string, sizeof (string), file))
goto failed;
g_strstrip (string);
shape_val = g_enum_get_value_by_nick (enum_class, string);
if (!shape_val)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush shape."),
gimp_filename_to_utf8 (filename));
return NULL;
}
shape = shape_val->value;
}
/* read brush spacing */
errno = 0;
if (! fgets (string, sizeof (string), file))
@ -551,6 +643,7 @@ gimp_brush_generated_load (const gchar *filename,
/* create new brush */
brush = g_object_new (GIMP_TYPE_BRUSH_GENERATED,
"shape", shape,
"name", name,
"radius", radius,
"hardness", hardness,
@ -582,9 +675,27 @@ gimp_brush_generated_load (const gchar *filename,
return NULL;
}
GimpBrushGeneratedShape
gimp_brush_generated_set_shape (GimpBrushGenerated *brush,
GimpBrushGeneratedShape shape)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
if (brush->shape != shape)
{
brush->shape = shape;
g_object_notify (G_OBJECT (brush), "shape");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->shape;
}
gfloat
gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat radius)
gfloat radius)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -603,7 +714,7 @@ gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat hardness)
gfloat hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -622,7 +733,7 @@ gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat ratio)
gfloat ratio)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -641,7 +752,7 @@ gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
gfloat angle)
gfloat angle)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -661,6 +772,15 @@ gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
return brush->angle;
}
GimpBrushGeneratedShape
gimp_brush_generated_get_shape (const GimpBrushGenerated *brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
return brush->shape;
}
gfloat
gimp_brush_generated_get_radius (const GimpBrushGenerated *brush)
{

View file

@ -48,6 +48,7 @@
enum
{
PROP_0,
PROP_SHAPE,
PROP_RADIUS,
PROP_HARDNESS,
PROP_ASPECT_RATIO,
@ -92,8 +93,8 @@ gimp_brush_generated_get_type (void)
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_brush_generated_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpBrushGenerated),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_brush_generated_init,
@ -123,6 +124,12 @@ gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
data_class->get_extension = gimp_brush_generated_get_extension;
data_class->duplicate = gimp_brush_generated_duplicate;
g_object_class_install_property (object_class, PROP_SHAPE,
g_param_spec_enum ("shape", NULL, NULL,
GIMP_TYPE_BRUSH_GENERATED_SHAPE,
GIMP_BRUSH_GENERATED_CIRCLE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_RADIUS,
g_param_spec_double ("radius", NULL, NULL,
1.0, 1000.0, 5.0,
@ -149,6 +156,7 @@ gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
static void
gimp_brush_generated_init (GimpBrushGenerated *brush)
{
brush->shape = GIMP_BRUSH_GENERATED_CIRCLE;
brush->radius = 5.0;
brush->hardness = 0.0;
brush->aspect_ratio = 1.0;
@ -165,6 +173,9 @@ gimp_brush_generated_set_property (GObject *object,
switch (property_id)
{
case PROP_SHAPE:
gimp_brush_generated_set_shape (brush, g_value_get_enum (value));
break;
case PROP_RADIUS:
gimp_brush_generated_set_radius (brush, g_value_get_double (value));
break;
@ -193,6 +204,9 @@ gimp_brush_generated_get_property (GObject *object,
switch (property_id)
{
case PROP_SHAPE:
g_value_set_enum (value, brush->shape);
break;
case PROP_RADIUS:
g_value_set_double (value, brush->angle);
break;
@ -226,7 +240,7 @@ gimp_brush_generated_save (GimpData *data,
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN,
_("Could not open '%s' for writing: %s"),
gimp_filename_to_utf8 (data->filename),
g_strerror (errno));
g_strerror (errno));
return FALSE;
}
@ -234,11 +248,26 @@ gimp_brush_generated_save (GimpData *data,
fprintf (file, "GIMP-VBR\n");
/* write version */
fprintf (file, "1.0\n");
if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE)
fprintf (file, "1.5\n");
else
fprintf (file, "1.0\n");
/* write name */
fprintf (file, "%.255s\n", GIMP_OBJECT (brush)->name);
if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE)
{
GEnumClass *enum_class;
GEnumValue *shape_val;
enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE);
/* write shape */
shape_val = g_enum_get_value (enum_class, brush->shape);
fprintf (file, "%s\n", shape_val->value_nick);
}
/* write brush spacing */
fprintf (file, "%s\n",
g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f",
@ -282,10 +311,11 @@ gimp_brush_generated_duplicate (GimpData *data,
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data);
return gimp_brush_generated_new (GIMP_OBJECT (brush)->name,
brush->shape,
brush->radius,
brush->hardness,
brush->aspect_ratio,
brush->angle,
brush->hardness,
brush->aspect_ratio,
brush->angle,
stingy_memory_use);
}
@ -337,14 +367,27 @@ gimp_brush_generated_dirty (GimpData *data)
gbrush->y_axis.x = s * short_radius;
gbrush->y_axis.y = c * short_radius;
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
gbrush->y_axis.x * gbrush->y_axis.x));
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
gbrush->y_axis.y * gbrush->y_axis.y));
switch (brush->shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
gbrush->y_axis.x * gbrush->y_axis.x));
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
gbrush->y_axis.y * gbrush->y_axis.y));
break;
case GIMP_BRUSH_GENERATED_SQUARE:
width = ceil (fabs (gbrush->x_axis.x) + fabs (gbrush->y_axis.x));
height = ceil (fabs (gbrush->x_axis.y) + fabs (gbrush->y_axis.y));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
width = ceil (MAX (fabs (gbrush->x_axis.x), fabs (gbrush->y_axis.x)));
height = ceil (MAX (fabs (gbrush->x_axis.y), fabs (gbrush->y_axis.y)));
break;
}
gbrush->mask = temp_buf_new (width * 2 + 1,
height * 2 + 1,
1, width, height, 0);
height * 2 + 1,
1, width, height, 0);
centerp = temp_buf_data (gbrush->mask) + height * gbrush->mask->width + width;
@ -366,9 +409,9 @@ gimp_brush_generated_dirty (GimpData *data)
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
if (d > brush->radius)
buffer[x] = 0.0;
buffer[x] = 0.0;
else
buffer[x] = gauss (pow (d / brush->radius, exponent));
buffer[x] = gauss (pow (d / brush->radius, exponent));
sum += buffer[x];
}
@ -378,9 +421,9 @@ gimp_brush_generated_dirty (GimpData *data)
sum -= buffer[x % OVERSAMPLING];
if (d > brush->radius)
buffer[x % OVERSAMPLING] = 0.0;
buffer[x % OVERSAMPLING] = 0.0;
else
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
sum += buffer[x % OVERSAMPLING];
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
@ -395,22 +438,33 @@ gimp_brush_generated_dirty (GimpData *data)
for (y = 0; y <= height; y++)
{
for (x = -width; x <= width; x++)
{
{
gdouble tx, ty;
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
d = sqrt (tx*tx + ty*ty);
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
switch (brush->shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
d = sqrt (tx*tx + ty*ty);
break;
case GIMP_BRUSH_GENERATED_SQUARE:
d = MAX (fabs (tx), fabs (ty));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
d = fabs (tx) + fabs (ty);
break;
}
if (d < brush->radius + 1)
a = lookup[(gint) RINT (d * OVERSAMPLING)];
else
a = 0;
if (d < brush->radius + 1)
a = lookup[(gint) RINT (d * OVERSAMPLING)];
else
a = 0;
centerp[ y * gbrush->mask->width + x] = a;
centerp[-1 * y * gbrush->mask->width - x] = a;
}
centerp[ y * gbrush->mask->width + x] = a;
centerp[-1 * y * gbrush->mask->width - x] = a;
}
}
g_free (lookup);
@ -420,18 +474,20 @@ gimp_brush_generated_dirty (GimpData *data)
}
GimpData *
gimp_brush_generated_new (const gchar *name,
gfloat radius,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gboolean stingy_memory_use)
gimp_brush_generated_new (const gchar *name,
GimpBrushGeneratedShape shape,
gfloat radius,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gboolean stingy_memory_use)
{
GimpBrushGenerated *brush;
g_return_val_if_fail (name != NULL, NULL);
brush = g_object_new (GIMP_TYPE_BRUSH_GENERATED,
"shape", shape,
"name", name,
"radius", radius,
"hardness", hardness,
@ -455,15 +511,17 @@ gimp_brush_generated_load (const gchar *filename,
gboolean stingy_memory_use,
GError **error)
{
GimpBrushGenerated *brush;
FILE *file;
gchar string[256];
gchar *name = NULL;
gdouble spacing;
gdouble radius;
gdouble hardness;
gdouble aspect_ratio;
gdouble angle;
GimpBrushGenerated *brush;
FILE *file;
gchar string[256];
gchar *name = NULL;
GimpBrushGeneratedShape shape = GIMP_BRUSH_GENERATED_CIRCLE;
gboolean have_shape = FALSE;
gdouble spacing;
gdouble radius;
gdouble hardness;
gdouble aspect_ratio;
gdouble angle;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (g_path_is_absolute (filename), NULL);
@ -500,11 +558,18 @@ gimp_brush_generated_load (const gchar *filename,
if (strncmp (string, "1.0", 3))
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush version."),
gimp_filename_to_utf8 (filename));
return NULL;
if (strncmp (string, "1.5", 3))
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush version."),
gimp_filename_to_utf8 (filename));
return NULL;
}
else
{
have_shape = TRUE;
}
}
/* read name */
@ -517,6 +582,33 @@ gimp_brush_generated_load (const gchar *filename,
_("Invalid UTF-8 string in brush file '%s'."),
gimp_filename_to_utf8 (filename));
if (have_shape)
{
GEnumClass *enum_class;
GEnumValue *shape_val;
enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE);
/* read shape */
errno = 0;
if (! fgets (string, sizeof (string), file))
goto failed;
g_strstrip (string);
shape_val = g_enum_get_value_by_nick (enum_class, string);
if (!shape_val)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush shape."),
gimp_filename_to_utf8 (filename));
return NULL;
}
shape = shape_val->value;
}
/* read brush spacing */
errno = 0;
if (! fgets (string, sizeof (string), file))
@ -551,6 +643,7 @@ gimp_brush_generated_load (const gchar *filename,
/* create new brush */
brush = g_object_new (GIMP_TYPE_BRUSH_GENERATED,
"shape", shape,
"name", name,
"radius", radius,
"hardness", hardness,
@ -582,9 +675,27 @@ gimp_brush_generated_load (const gchar *filename,
return NULL;
}
GimpBrushGeneratedShape
gimp_brush_generated_set_shape (GimpBrushGenerated *brush,
GimpBrushGeneratedShape shape)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
if (brush->shape != shape)
{
brush->shape = shape;
g_object_notify (G_OBJECT (brush), "shape");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->shape;
}
gfloat
gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat radius)
gfloat radius)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -603,7 +714,7 @@ gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat hardness)
gfloat hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -622,7 +733,7 @@ gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat ratio)
gfloat ratio)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -641,7 +752,7 @@ gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
gfloat angle)
gfloat angle)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -661,6 +772,15 @@ gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
return brush->angle;
}
GimpBrushGeneratedShape
gimp_brush_generated_get_shape (const GimpBrushGenerated *brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
return brush->shape;
}
gfloat
gimp_brush_generated_get_radius (const GimpBrushGenerated *brush)
{

View file

@ -48,6 +48,7 @@
enum
{
PROP_0,
PROP_SHAPE,
PROP_RADIUS,
PROP_HARDNESS,
PROP_ASPECT_RATIO,
@ -92,8 +93,8 @@ gimp_brush_generated_get_type (void)
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_brush_generated_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpBrushGenerated),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_brush_generated_init,
@ -123,6 +124,12 @@ gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
data_class->get_extension = gimp_brush_generated_get_extension;
data_class->duplicate = gimp_brush_generated_duplicate;
g_object_class_install_property (object_class, PROP_SHAPE,
g_param_spec_enum ("shape", NULL, NULL,
GIMP_TYPE_BRUSH_GENERATED_SHAPE,
GIMP_BRUSH_GENERATED_CIRCLE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_RADIUS,
g_param_spec_double ("radius", NULL, NULL,
1.0, 1000.0, 5.0,
@ -149,6 +156,7 @@ gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
static void
gimp_brush_generated_init (GimpBrushGenerated *brush)
{
brush->shape = GIMP_BRUSH_GENERATED_CIRCLE;
brush->radius = 5.0;
brush->hardness = 0.0;
brush->aspect_ratio = 1.0;
@ -165,6 +173,9 @@ gimp_brush_generated_set_property (GObject *object,
switch (property_id)
{
case PROP_SHAPE:
gimp_brush_generated_set_shape (brush, g_value_get_enum (value));
break;
case PROP_RADIUS:
gimp_brush_generated_set_radius (brush, g_value_get_double (value));
break;
@ -193,6 +204,9 @@ gimp_brush_generated_get_property (GObject *object,
switch (property_id)
{
case PROP_SHAPE:
g_value_set_enum (value, brush->shape);
break;
case PROP_RADIUS:
g_value_set_double (value, brush->angle);
break;
@ -226,7 +240,7 @@ gimp_brush_generated_save (GimpData *data,
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN,
_("Could not open '%s' for writing: %s"),
gimp_filename_to_utf8 (data->filename),
g_strerror (errno));
g_strerror (errno));
return FALSE;
}
@ -234,11 +248,26 @@ gimp_brush_generated_save (GimpData *data,
fprintf (file, "GIMP-VBR\n");
/* write version */
fprintf (file, "1.0\n");
if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE)
fprintf (file, "1.5\n");
else
fprintf (file, "1.0\n");
/* write name */
fprintf (file, "%.255s\n", GIMP_OBJECT (brush)->name);
if (brush->shape != GIMP_BRUSH_GENERATED_CIRCLE)
{
GEnumClass *enum_class;
GEnumValue *shape_val;
enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE);
/* write shape */
shape_val = g_enum_get_value (enum_class, brush->shape);
fprintf (file, "%s\n", shape_val->value_nick);
}
/* write brush spacing */
fprintf (file, "%s\n",
g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f",
@ -282,10 +311,11 @@ gimp_brush_generated_duplicate (GimpData *data,
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data);
return gimp_brush_generated_new (GIMP_OBJECT (brush)->name,
brush->shape,
brush->radius,
brush->hardness,
brush->aspect_ratio,
brush->angle,
brush->hardness,
brush->aspect_ratio,
brush->angle,
stingy_memory_use);
}
@ -337,14 +367,27 @@ gimp_brush_generated_dirty (GimpData *data)
gbrush->y_axis.x = s * short_radius;
gbrush->y_axis.y = c * short_radius;
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
gbrush->y_axis.x * gbrush->y_axis.x));
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
gbrush->y_axis.y * gbrush->y_axis.y));
switch (brush->shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
gbrush->y_axis.x * gbrush->y_axis.x));
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
gbrush->y_axis.y * gbrush->y_axis.y));
break;
case GIMP_BRUSH_GENERATED_SQUARE:
width = ceil (fabs (gbrush->x_axis.x) + fabs (gbrush->y_axis.x));
height = ceil (fabs (gbrush->x_axis.y) + fabs (gbrush->y_axis.y));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
width = ceil (MAX (fabs (gbrush->x_axis.x), fabs (gbrush->y_axis.x)));
height = ceil (MAX (fabs (gbrush->x_axis.y), fabs (gbrush->y_axis.y)));
break;
}
gbrush->mask = temp_buf_new (width * 2 + 1,
height * 2 + 1,
1, width, height, 0);
height * 2 + 1,
1, width, height, 0);
centerp = temp_buf_data (gbrush->mask) + height * gbrush->mask->width + width;
@ -366,9 +409,9 @@ gimp_brush_generated_dirty (GimpData *data)
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
if (d > brush->radius)
buffer[x] = 0.0;
buffer[x] = 0.0;
else
buffer[x] = gauss (pow (d / brush->radius, exponent));
buffer[x] = gauss (pow (d / brush->radius, exponent));
sum += buffer[x];
}
@ -378,9 +421,9 @@ gimp_brush_generated_dirty (GimpData *data)
sum -= buffer[x % OVERSAMPLING];
if (d > brush->radius)
buffer[x % OVERSAMPLING] = 0.0;
buffer[x % OVERSAMPLING] = 0.0;
else
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
sum += buffer[x % OVERSAMPLING];
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
@ -395,22 +438,33 @@ gimp_brush_generated_dirty (GimpData *data)
for (y = 0; y <= height; y++)
{
for (x = -width; x <= width; x++)
{
{
gdouble tx, ty;
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
d = sqrt (tx*tx + ty*ty);
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
switch (brush->shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
d = sqrt (tx*tx + ty*ty);
break;
case GIMP_BRUSH_GENERATED_SQUARE:
d = MAX (fabs (tx), fabs (ty));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
d = fabs (tx) + fabs (ty);
break;
}
if (d < brush->radius + 1)
a = lookup[(gint) RINT (d * OVERSAMPLING)];
else
a = 0;
if (d < brush->radius + 1)
a = lookup[(gint) RINT (d * OVERSAMPLING)];
else
a = 0;
centerp[ y * gbrush->mask->width + x] = a;
centerp[-1 * y * gbrush->mask->width - x] = a;
}
centerp[ y * gbrush->mask->width + x] = a;
centerp[-1 * y * gbrush->mask->width - x] = a;
}
}
g_free (lookup);
@ -420,18 +474,20 @@ gimp_brush_generated_dirty (GimpData *data)
}
GimpData *
gimp_brush_generated_new (const gchar *name,
gfloat radius,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gboolean stingy_memory_use)
gimp_brush_generated_new (const gchar *name,
GimpBrushGeneratedShape shape,
gfloat radius,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gboolean stingy_memory_use)
{
GimpBrushGenerated *brush;
g_return_val_if_fail (name != NULL, NULL);
brush = g_object_new (GIMP_TYPE_BRUSH_GENERATED,
"shape", shape,
"name", name,
"radius", radius,
"hardness", hardness,
@ -455,15 +511,17 @@ gimp_brush_generated_load (const gchar *filename,
gboolean stingy_memory_use,
GError **error)
{
GimpBrushGenerated *brush;
FILE *file;
gchar string[256];
gchar *name = NULL;
gdouble spacing;
gdouble radius;
gdouble hardness;
gdouble aspect_ratio;
gdouble angle;
GimpBrushGenerated *brush;
FILE *file;
gchar string[256];
gchar *name = NULL;
GimpBrushGeneratedShape shape = GIMP_BRUSH_GENERATED_CIRCLE;
gboolean have_shape = FALSE;
gdouble spacing;
gdouble radius;
gdouble hardness;
gdouble aspect_ratio;
gdouble angle;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (g_path_is_absolute (filename), NULL);
@ -500,11 +558,18 @@ gimp_brush_generated_load (const gchar *filename,
if (strncmp (string, "1.0", 3))
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush version."),
gimp_filename_to_utf8 (filename));
return NULL;
if (strncmp (string, "1.5", 3))
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush version."),
gimp_filename_to_utf8 (filename));
return NULL;
}
else
{
have_shape = TRUE;
}
}
/* read name */
@ -517,6 +582,33 @@ gimp_brush_generated_load (const gchar *filename,
_("Invalid UTF-8 string in brush file '%s'."),
gimp_filename_to_utf8 (filename));
if (have_shape)
{
GEnumClass *enum_class;
GEnumValue *shape_val;
enum_class = g_type_class_peek (GIMP_TYPE_BRUSH_GENERATED_SHAPE);
/* read shape */
errno = 0;
if (! fgets (string, sizeof (string), file))
goto failed;
g_strstrip (string);
shape_val = g_enum_get_value_by_nick (enum_class, string);
if (!shape_val)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Fatal parse error in brush file '%s': "
"Unknown GIMP brush shape."),
gimp_filename_to_utf8 (filename));
return NULL;
}
shape = shape_val->value;
}
/* read brush spacing */
errno = 0;
if (! fgets (string, sizeof (string), file))
@ -551,6 +643,7 @@ gimp_brush_generated_load (const gchar *filename,
/* create new brush */
brush = g_object_new (GIMP_TYPE_BRUSH_GENERATED,
"shape", shape,
"name", name,
"radius", radius,
"hardness", hardness,
@ -582,9 +675,27 @@ gimp_brush_generated_load (const gchar *filename,
return NULL;
}
GimpBrushGeneratedShape
gimp_brush_generated_set_shape (GimpBrushGenerated *brush,
GimpBrushGeneratedShape shape)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
if (brush->shape != shape)
{
brush->shape = shape;
g_object_notify (G_OBJECT (brush), "shape");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->shape;
}
gfloat
gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat radius)
gfloat radius)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -603,7 +714,7 @@ gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat hardness)
gfloat hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -622,7 +733,7 @@ gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat ratio)
gfloat ratio)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -641,7 +752,7 @@ gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat
gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
gfloat angle)
gfloat angle)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
@ -661,6 +772,15 @@ gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
return brush->angle;
}
GimpBrushGeneratedShape
gimp_brush_generated_get_shape (const GimpBrushGenerated *brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
return brush->shape;
}
gfloat
gimp_brush_generated_get_radius (const GimpBrushGenerated *brush)
{

View file

@ -40,12 +40,13 @@ typedef struct _GimpBrushGeneratedClass GimpBrushGeneratedClass;
struct _GimpBrushGenerated
{
GimpBrush parent_instance;
GimpBrush parent_instance;
gfloat radius;
gfloat hardness; /* 0.0 - 1.0 */
gfloat aspect_ratio; /* y/x */
gfloat angle; /* in degrees */
GimpBrushGeneratedShape shape;
gfloat radius;
gfloat hardness; /* 0.0 - 1.0 */
gfloat aspect_ratio; /* y/x */
gfloat angle; /* in degrees */
};
struct _GimpBrushGeneratedClass
@ -57,24 +58,30 @@ struct _GimpBrushGeneratedClass
GType gimp_brush_generated_get_type (void) G_GNUC_CONST;
GimpData * gimp_brush_generated_new (const gchar *name,
GimpBrushGeneratedShape shape,
gfloat radius,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
gboolean stingy_memory_use);
GList * gimp_brush_generated_load (const gchar *file_name,
gboolean stingy_memory_use,
GError **error);
gfloat gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat radius);
gfloat gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat hardness);
gfloat gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat ratio);
gfloat gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
gfloat angle);
GimpBrushGeneratedShape
gimp_brush_generated_set_shape (GimpBrushGenerated *brush,
GimpBrushGeneratedShape shape);
gfloat gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat radius);
gfloat gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat hardness);
gfloat gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat ratio);
gfloat gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
gfloat angle);
GimpBrushGeneratedShape
gimp_brush_generated_get_shape (const GimpBrushGenerated *brush);
gfloat gimp_brush_generated_get_radius (const GimpBrushGenerated *brush);
gfloat gimp_brush_generated_get_hardness (const GimpBrushGenerated *brush);
gfloat gimp_brush_generated_get_aspect_ratio (const GimpBrushGenerated *brush);

View file

@ -33,6 +33,7 @@
#include "core/gimpbrushgenerated.h"
#include "gimpbrusheditor.h"
#include "gimpenumwidgets.h"
#include "gimppreview.h"
#include "gimp-intl.h"
@ -52,6 +53,8 @@ static void gimp_brush_editor_set_data (GimpDataEditor *editor,
static void gimp_brush_editor_update_brush (GtkAdjustment *adjustment,
GimpBrushEditor *editor);
static void gimp_brush_editor_update_brush_shape (GtkWidget *widget,
GimpBrushEditor *editor);
static void gimp_brush_editor_notify_brush (GimpBrushGenerated *brush,
GParamSpec *pspec,
GimpBrushEditor *editor);
@ -101,7 +104,7 @@ gimp_brush_editor_class_init (GimpBrushEditorClass *klass)
static void
gimp_brush_editor_init (GimpBrushEditor *editor)
{
GtkWidget *frame;
GtkWidget *frame, *box;
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
@ -119,6 +122,8 @@ gimp_brush_editor_init (GimpBrushEditor *editor)
gtk_container_add (GTK_CONTAINER (frame), editor->preview);
gtk_widget_show (editor->preview);
editor->shape_group = NULL;
/* table for sliders/labels */
editor->options_table = gtk_table_new (4, 3, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (editor->options_table), 2);
@ -126,10 +131,23 @@ gimp_brush_editor_init (GimpBrushEditor *editor)
gtk_box_pack_start (GTK_BOX (editor), editor->options_table, FALSE, FALSE, 0);
gtk_widget_show (editor->options_table);
/* Stock Box for the brush shape */
box = gimp_enum_stock_box_new (GIMP_TYPE_BRUSH_GENERATED_SHAPE,
"gimp-brush-generated",
GTK_ICON_SIZE_MENU,
G_CALLBACK (gimp_brush_editor_update_brush_shape),
editor,
&editor->shape_group);
gimp_table_attach_aligned (GTK_TABLE (editor->options_table),
0, 0,
_("Shape:"), 0.0, 0.5,
box, 2, TRUE);
gtk_widget_show (box);
/* brush radius scale */
editor->radius_data =
GTK_ADJUSTMENT (gimp_scale_entry_new (GTK_TABLE (editor->options_table),
0, 0,
0, 1,
_("Radius:"), -1, 5,
0.0, 1.0, 1000.0, 0.1, 1.0, 1,
TRUE, 0.0, 0.0,
@ -142,7 +160,7 @@ gimp_brush_editor_init (GimpBrushEditor *editor)
/* brush hardness scale */
editor->hardness_data =
GTK_ADJUSTMENT (gimp_scale_entry_new (GTK_TABLE (editor->options_table),
0, 1,
0, 2,
_("Hardness:"), -1, 5,
0.0, 0.0, 1.0, 0.01, 0.1, 2,
TRUE, 0.0, 0.0,
@ -155,7 +173,7 @@ gimp_brush_editor_init (GimpBrushEditor *editor)
/* brush aspect ratio scale */
editor->aspect_ratio_data =
GTK_ADJUSTMENT (gimp_scale_entry_new (GTK_TABLE (editor->options_table),
0, 2,
0, 3,
_("Aspect ratio:"), -1, 5,
0.0, 1.0, 20.0, 0.1, 1.0, 1,
TRUE, 0.0, 0.0,
@ -168,7 +186,7 @@ gimp_brush_editor_init (GimpBrushEditor *editor)
/* brush angle scale */
editor->angle_data =
GTK_ADJUSTMENT (gimp_scale_entry_new (GTK_TABLE (editor->options_table),
0, 3,
0, 4,
_("Angle:"), -1, 5,
0.0, 0.0, 180.0, 0.1, 1.0, 1,
TRUE, 0.0, 0.0,
@ -183,11 +201,12 @@ static void
gimp_brush_editor_set_data (GimpDataEditor *editor,
GimpData *data)
{
GimpBrushEditor *brush_editor;
gdouble radius = 0.0;
gdouble hardness = 0.0;
gdouble ratio = 0.0;
gdouble angle = 0.0;
GimpBrushEditor *brush_editor;
GimpBrushGeneratedShape shape = GIMP_BRUSH_GENERATED_CIRCLE;
gdouble radius = 0.0;
gdouble hardness = 0.0;
gdouble ratio = 0.0;
gdouble angle = 0.0;
brush_editor = GIMP_BRUSH_EDITOR (editor);
@ -210,6 +229,7 @@ gimp_brush_editor_set_data (GimpDataEditor *editor,
{
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (editor->data);
shape = gimp_brush_generated_get_shape (brush);
radius = gimp_brush_generated_get_radius (brush);
hardness = gimp_brush_generated_get_hardness (brush);
ratio = gimp_brush_generated_get_aspect_ratio (brush);
@ -219,6 +239,8 @@ gimp_brush_editor_set_data (GimpDataEditor *editor,
gtk_widget_set_sensitive (brush_editor->options_table,
editor->data_editable);
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (brush_editor->shape_group),
shape);
gtk_adjustment_set_value (brush_editor->radius_data, radius);
gtk_adjustment_set_value (brush_editor->hardness_data, hardness);
gtk_adjustment_set_value (brush_editor->aspect_ratio_data, ratio);
@ -295,6 +317,26 @@ gimp_brush_editor_update_brush (GtkAdjustment *adjustment,
}
}
static void
gimp_brush_editor_update_brush_shape (GtkWidget *widget,
GimpBrushEditor *editor)
{
GimpBrushGeneratedShape shape;
GimpBrushGenerated *brush;
if (! GIMP_IS_BRUSH_GENERATED (GIMP_DATA_EDITOR (editor)->data))
return;
brush = GIMP_BRUSH_GENERATED (GIMP_DATA_EDITOR (editor)->data);
shape = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
"gimp-item-data"));
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) &&
gimp_brush_generated_get_shape (brush) != shape)
gimp_brush_generated_set_shape (brush, shape);
}
static void
gimp_brush_editor_notify_brush (GimpBrushGenerated *brush,
GParamSpec *pspec,
@ -303,7 +345,23 @@ gimp_brush_editor_notify_brush (GimpBrushGenerated *brush,
GtkAdjustment *adj = NULL;
gdouble value = 0.0;
if (! strcmp (pspec->name, "radius"))
if (! strcmp (pspec->name, "shape"))
{
g_signal_handlers_block_by_func (editor->shape_group,
G_CALLBACK (gimp_brush_editor_update_brush_shape),
editor);
gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (editor->shape_group),
brush->shape);
g_signal_handlers_unblock_by_func (editor->shape_group,
G_CALLBACK (gimp_brush_editor_update_brush_shape),
editor);
adj = editor->radius_data;
value = brush->radius;
}
else if (! strcmp (pspec->name, "radius"))
{
adj = editor->radius_data;
value = brush->radius;

View file

@ -42,6 +42,7 @@ struct _GimpBrushEditor
GtkWidget *preview;
GtkWidget *shape_group;
GtkWidget *options_table;
GtkAdjustment *radius_data;
GtkAdjustment *hardness_data;

View file

@ -237,6 +237,9 @@ static GtkStockItem gimp_stock_items[] =
{ GIMP_STOCK_WEB, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_VIDEO, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_BRUSH_GENERATED_CIRCLE, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_BRUSH_GENERATED_DIAMOND, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_BRUSH_GENERATED_SQUARE, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_CAP_BUTT, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_CAP_ROUND, NULL, 0, 0, LIBGIMP_DOMAIN },
{ GIMP_STOCK_CAP_SQUARE, NULL, 0, 0, LIBGIMP_DOMAIN },
@ -557,6 +560,10 @@ gimp_stock_menu_pixbufs[] =
{ GIMP_STOCK_WEB, stock_web_16 },
{ GIMP_STOCK_VIDEO, stock_video_16 },
{ GIMP_STOCK_BRUSH_GENERATED_CIRCLE, stock_brush_generated_circle_16 },
{ GIMP_STOCK_BRUSH_GENERATED_DIAMOND, stock_brush_generated_diamond_16 },
{ GIMP_STOCK_BRUSH_GENERATED_SQUARE, stock_brush_generated_square_16 },
{ GIMP_STOCK_CAP_BUTT, stock_cap_butt_16 },
{ GIMP_STOCK_CAP_ROUND, stock_cap_round_16 },
{ GIMP_STOCK_CAP_SQUARE, stock_cap_square_16 },

View file

@ -208,6 +208,10 @@ G_BEGIN_DECLS
#define GIMP_STOCK_WEB "gimp-web"
#define GIMP_STOCK_VIDEO "gimp-video"
#define GIMP_STOCK_BRUSH_GENERATED_CIRCLE "gimp-brush-generated-circle"
#define GIMP_STOCK_BRUSH_GENERATED_DIAMOND "gimp-brush-generated-diamond"
#define GIMP_STOCK_BRUSH_GENERATED_SQUARE "gimp-brush-generated-square"
#define GIMP_STOCK_CAP_BUTT "gimp-cap-butt"
#define GIMP_STOCK_CAP_ROUND "gimp-cap-round"
#define GIMP_STOCK_CAP_SQUARE "gimp-cap-square"

View file

@ -32,6 +32,9 @@ WILBER_VARIABLES = \
## Below are compiled in stock icons
STOCK_MENU_IMAGES = \
stock-brush-generated-circle-16.png \
stock-brush-generated-diamond-16.png \
stock-brush-generated-square-16.png \
stock-cap-butt-16.png \
stock-cap-round-16.png \
stock-cap-square-16.png \

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 B