app/core/gimpbrush.[ch] app/core/gimpbrushgenerated.c

2007-03-12  Michael Natterer  <mitch@gimp.org>

	* app/core/gimpbrush.[ch]
	* app/core/gimpbrushgenerated.c
	* app/tools/gimppaintoptions-gui.c
	* app/base/brush-scale.[ch]
	* app/base/temp-buf.[ch]
	* app/paint/gimppaintoptions.c
	* app/paint/gimpbrushcore.c: revert last commit. The patch needs
	more review and it's easier to start from quare one than have
	patches on top of patches.


svn path=/trunk/; revision=22101
This commit is contained in:
Michael Natterer 2007-03-12 09:33:57 +00:00 committed by Michael Natterer
parent c73b3aa123
commit 4648f542cf
11 changed files with 443 additions and 254 deletions

View file

@ -1,3 +1,15 @@
2007-03-12 Michael Natterer <mitch@gimp.org>
* app/core/gimpbrush.[ch]
* app/core/gimpbrushgenerated.c
* app/tools/gimppaintoptions-gui.c
* app/base/brush-scale.[ch]
* app/base/temp-buf.[ch]
* app/paint/gimppaintoptions.c
* app/paint/gimpbrushcore.c: revert last commit. The patch needs
more review and it's easier to start from quare one than have
patches on top of patches.
2007-03-11 Michael Schumacher <schumaml@cvs.gnome.org>
Made brushes scalable (both up and down) by using existing

View file

@ -24,40 +24,327 @@
#include "brush-scale.h"
#include "temp-buf.h"
#include "pixel-region.h"
#include "paint-funcs/scale-funcs.h"
MaskBuf *
brush_scale_buf (MaskBuf *brush_mask,
gint dest_width,
gint dest_height,
gint bpp)
brush_scale_mask (MaskBuf *brush_mask,
gint dest_width,
gint dest_height)
{
PixelRegion source_region;
PixelRegion dest_region;
MaskBuf *dest_brush_mask;
MaskBuf *scale_brush;
gint src_width;
gint src_height;
gint value;
gint area;
gint i, j;
gint x, x0, y, y0;
gint dx, dx0, dy, dy0;
gint fx, fx0, fy, fy0;
guchar *src, *dest;
/* Use existing scaling routines for brush scaling. */
g_return_val_if_fail (brush_mask != NULL &&
dest_width != 0 && dest_height != 0, NULL);
pixel_region_init_temp_buf (&source_region, brush_mask,
brush_mask->x,
brush_mask->y,
brush_mask->width,
brush_mask->height);
src_width = brush_mask->width;
src_height = brush_mask->height;
dest_brush_mask = mask_buf_new (dest_width, dest_height, bpp);
g_return_val_if_fail (dest_brush_mask != NULL, NULL);
scale_brush = mask_buf_new (dest_width, dest_height);
g_return_val_if_fail (scale_brush != NULL, NULL);
pixel_region_init_temp_buf (&dest_region, dest_brush_mask,
brush_mask->x,
brush_mask->y,
dest_width,
dest_height);
/* get the data */
dest = mask_buf_data (scale_brush);
src = mask_buf_data (brush_mask);
scale_region (&source_region, &dest_region, GIMP_INTERPOLATION_LINEAR,
NULL, NULL);
fx = fx0 = (256.0 * src_width) / dest_width;
fy = fy0 = (256.0 * src_height) / dest_height;
area = (fx0 * fy0) >> 8;
return dest_brush_mask;
x = x0 = 0;
y = y0 = 0;
dx = dx0 = 0;
dy = dy0 = 0;
for (i=0; i<dest_height; i++)
{
for (j=0; j<dest_width; j++)
{
value = 0;
fy = fy0;
y = y0;
dy = dy0;
if (dy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
value += (dx * dy * src[x + src_width * y]) >> 8;
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
value += dy * src[x + src_width * y];
x++;
fx -= 256;
}
if (fx)
{
value += fx * dy * src[x + src_width * y] >> 8;
dx = 256 - fx;
}
y++;
fy -= dy;
dy = 0;
}
while (fy >= 256)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
value += dx * src[x + src_width * y];
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
value += 256 * src[x + src_width * y];
x++;
fx -= 256;
}
if (fx)
{
value += fx * src[x + src_width * y];
dx = 256 - fx;
}
y++;
fy -= 256;
}
if (fy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
value += (dx * fy * src[x + src_width * y]) >> 8;
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
value += fy * src[x + src_width * y];
x++;
fx -= 256;
}
if (fx)
{
value += (fx * fy * src[x + src_width * y]) >> 8;
dx = 256 - fx;
}
dy = 256 - fy;
}
*dest++ = MIN ((value / area), 255);
x0 = x;
dx0 = dx;
}
x0 = 0;
dx0 = 0;
y0 = y;
dy0 = dy;
}
return scale_brush;
}
#define ADD_RGB(dest, factor, src) \
dest[0] += factor * src[0]; \
dest[1] += factor * src[1]; \
dest[2] += factor * src[2];
MaskBuf *
brush_scale_pixmap (MaskBuf *pixmap,
gint dest_width,
gint dest_height)
{
MaskBuf *scale_brush;
gint src_width;
gint src_height;
gint value[3];
gint factor;
gint area;
gint i, j;
gint x, x0, y, y0;
gint dx, dx0, dy, dy0;
gint fx, fx0, fy, fy0;
guchar *src, *src_ptr, *dest;
g_return_val_if_fail (pixmap != NULL && pixmap->bytes == 3 &&
dest_width != 0 && dest_height != 0, NULL);
src_width = pixmap->width;
src_height = pixmap->height;
scale_brush = temp_buf_new (dest_width, dest_height, 3, 0, 0, NULL);
g_return_val_if_fail (scale_brush != NULL, NULL);
/* get the data */
dest = mask_buf_data (scale_brush);
src = mask_buf_data (pixmap);
fx = fx0 = (256.0 * src_width) / dest_width;
fy = fy0 = (256.0 * src_height) / dest_height;
area = (fx0 * fy0) >> 8;
x = x0 = 0;
y = y0 = 0;
dx = dx0 = 0;
dy = dy0 = 0;
for (i=0; i<dest_height; i++)
{
for (j=0; j<dest_width; j++)
{
value[0] = 0;
value[1] = 0;
value[2] = 0;
fy = fy0;
y = y0;
dy = dy0;
if (dy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = (dx * dy) >> 8;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = dy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = (fx * dy) >> 8;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
y++;
fy -= dy;
dy = 0;
}
while (fy >= 256)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = dx;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = 256;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = fx;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
y++;
fy -= 256;
}
if (fy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = (dx * fy) >> 8;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = fy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = (fx * fy) >> 8;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
dy = 256 - fy;
}
*dest++ = MIN ((value[0] / area), 255);
*dest++ = MIN ((value[1] / area), 255);
*dest++ = MIN ((value[2] / area), 255);
x0 = x;
dx0 = dx;
}
x0 = 0;
dx0 = 0;
y0 = y;
dy0 = dy;
}
return scale_brush;
}
#undef ADD_RGB

View file

@ -20,10 +20,12 @@
#define __BRUSH_SCALE_H__
MaskBuf * brush_scale_buf (MaskBuf *brush_mask,
gint dest_width,
gint dest_height,
gint bpp);
MaskBuf * brush_scale_mask (MaskBuf *brush_mask,
gint dest_width,
gint dest_height);
MaskBuf * brush_scale_pixmap (MaskBuf *pixmap,
gint dest_width,
gint dest_height);
#endif /* __BRUSH_SCALE_H__ */

View file

@ -487,12 +487,11 @@ temp_buf_to_gray (TempBuf *src_buf,
MaskBuf *
mask_buf_new (gint width,
gint height,
gint bpp)
gint height)
{
static guchar empty = 0;
return temp_buf_new (width, height, bpp, 0, 0, &empty);
return temp_buf_new (width, height, 1, 0, 0, &empty);
}
void

View file

@ -72,8 +72,7 @@ gsize temp_buf_get_memsize (TempBuf *buf);
/* The mask buffer functions */
MaskBuf * mask_buf_new (gint width,
gint height,
gint bpp);
gint height);
void mask_buf_free (MaskBuf *mask_buf);
guchar * mask_buf_data (MaskBuf *mask_buf);
guchar * mask_buf_data_clear (MaskBuf *mask_buf);

View file

@ -83,10 +83,6 @@ static TempBuf * gimp_brush_real_scale_mask (GimpBrush *brush,
static TempBuf * gimp_brush_real_scale_pixmap (GimpBrush *brush,
gdouble scale);
static void gimp_brush_real_get_scaled_size (GimpBrush *brush,
gdouble scale,
gint *scaled_width,
gint *scaled_height);
G_DEFINE_TYPE (GimpBrush, gimp_brush, GIMP_TYPE_DATA)
@ -129,7 +125,6 @@ gimp_brush_class_init (GimpBrushClass *klass)
klass->want_null_motion = gimp_brush_real_want_null_motion;
klass->scale_mask = gimp_brush_real_scale_mask;
klass->scale_pixmap = gimp_brush_real_scale_pixmap;
klass->get_scaled_size = gimp_brush_real_get_scaled_size;
klass->spacing_changed = NULL;
g_object_class_install_property (object_class, PROP_SPACING,
@ -275,15 +270,15 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
if (brush_width <= 0) brush_width = 1;
if (brush_height <= 0) brush_height = 1;
mask_buf = brush_scale_buf (mask_buf, brush_width, brush_height, mask_buf->bytes);
mask_buf = brush_scale_mask (mask_buf, brush_width, brush_height);
if (pixmap_buf)
{
/* TODO: the scale function should scale the pixmap and the
* mask in one run
*/
pixmap_buf = brush_scale_buf (pixmap_buf,
brush_width, brush_height, pixmap_buf->bytes);
pixmap_buf = brush_scale_pixmap (pixmap_buf,
brush_width, brush_height);
}
scale = TRUE;
@ -375,10 +370,11 @@ gimp_brush_real_scale_mask (GimpBrush *brush,
gint width;
gint height;
gimp_brush_get_scaled_size (brush, scale, &width, &height);
width = (gint) (brush->mask->width * scale + 0.5);
height = (gint) (brush->mask->height * scale + 0.5);
if (width > 0 && height > 0)
return brush_scale_buf (brush->mask, width, height, brush->mask->bytes);
return brush_scale_mask (brush->mask, width, height);
return NULL;
}
@ -390,23 +386,15 @@ gimp_brush_real_scale_pixmap (GimpBrush *brush,
gint width;
gint height;
gimp_brush_get_scaled_size (brush, scale, &width, &height);
width = (gint) (brush->pixmap->width * scale + 0.5);
height = (gint) (brush->pixmap->height * scale + 0.5);
if (width > 0 && height > 0)
return brush_scale_buf (brush->pixmap, width, height, brush->pixmap->bytes);
return brush_scale_pixmap (brush->pixmap, width, height);
return NULL;
}
static void
gimp_brush_real_get_scaled_size (GimpBrush *brush,
gdouble scale,
gint *width,
gint *height)
{
*width = (gint) (brush->mask->width * scale + 0.5);
*height = (gint) (brush->mask->height * scale + 0.5);
}
/* public functions */
@ -488,18 +476,6 @@ gimp_brush_scale_pixmap (GimpBrush *brush,
return GIMP_BRUSH_GET_CLASS (brush)->scale_pixmap (brush, scale);
}
void
gimp_brush_get_scaled_size (GimpBrush *brush,
gdouble scale,
gint *width,
gint *height)
{
g_return_if_fail (GIMP_IS_BRUSH (brush));
g_return_if_fail (scale > 0.0);
return GIMP_BRUSH_GET_CLASS (brush)->get_scaled_size (brush, scale, width, height);
}
TempBuf *
gimp_brush_get_mask (const GimpBrush *brush)
{

View file

@ -61,10 +61,6 @@ struct _GimpBrushClass
gdouble scale);
TempBuf * (* scale_pixmap) (GimpBrush *brush,
gdouble scale);
void (* get_scaled_size) (GimpBrush *brush,
gdouble scale,
gint *width,
gint *height);
/* signals */
void (* spacing_changed) (GimpBrush *brush);
@ -88,12 +84,6 @@ TempBuf * gimp_brush_scale_mask (GimpBrush *brush,
TempBuf * gimp_brush_scale_pixmap (GimpBrush *brush,
gdouble scale);
/* Gets width and height of the scaled mask of the brush, with given scale. */
void gimp_brush_get_scaled_size (GimpBrush *brush,
gdouble scale,
gint *width,
gint *height);
TempBuf * gimp_brush_get_mask (const GimpBrush *brush);
TempBuf * gimp_brush_get_pixmap (const GimpBrush *brush);

View file

@ -64,25 +64,6 @@ static gchar * gimp_brush_generated_get_extension (GimpData *data);
static GimpData * gimp_brush_generated_duplicate (GimpData *data);
static TempBuf * gimp_brush_generated_scale_mask (GimpBrush *gbrush,
gdouble scale);
static void gimp_brush_generated_get_half_width_and_height
(GimpBrushGenerated *gbrush,
GimpBrushGeneratedShape shape,
gfloat radius,
gint spikes,
gfloat hardness,
gfloat aspect_ratio,
gdouble angle_in_degrees,
gint *half_width,
gint *half_height,
gdouble *_s,
gdouble *_c,
GimpVector2 *_x_axis,
GimpVector2 *_y_axis);
static void gimp_brush_generated_real_get_scaled_size
(GimpBrush *gbrush,
gdouble scale,
gint *width,
gint *height);
G_DEFINE_TYPE (GimpBrushGenerated, gimp_brush_generated, GIMP_TYPE_BRUSH)
@ -97,16 +78,15 @@ gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
GimpDataClass *data_class = GIMP_DATA_CLASS (klass);
GimpBrushClass *brush_class = GIMP_BRUSH_CLASS (klass);
object_class->set_property = gimp_brush_generated_set_property;
object_class->get_property = gimp_brush_generated_get_property;
object_class->set_property = gimp_brush_generated_set_property;
object_class->get_property = gimp_brush_generated_get_property;
data_class->save = gimp_brush_generated_save;
data_class->dirty = gimp_brush_generated_dirty;
data_class->get_extension = gimp_brush_generated_get_extension;
data_class->duplicate = gimp_brush_generated_duplicate;
data_class->save = gimp_brush_generated_save;
data_class->dirty = gimp_brush_generated_dirty;
data_class->get_extension = gimp_brush_generated_get_extension;
data_class->duplicate = gimp_brush_generated_duplicate;
brush_class->scale_mask = gimp_brush_generated_scale_mask;
brush_class->get_scaled_size = gimp_brush_generated_real_get_scaled_size;
brush_class->scale_mask = gimp_brush_generated_scale_mask;
g_object_class_install_property (object_class, PROP_SHAPE,
g_param_spec_enum ("shape", NULL, NULL,
@ -274,31 +254,62 @@ gimp_brush_generated_calc (GimpBrushGenerated *brush,
gdouble exponent;
guchar a;
gint length;
gint half_width = 0;
gint half_height = 0;
gint width = 0;
gint height = 0;
guchar *lookup;
gdouble sum;
gdouble c, s, cs, ss;
gdouble short_radius;
gdouble buffer[OVERSAMPLING];
GimpVector2 x_axis;
GimpVector2 y_axis;
TempBuf *mask;
gimp_brush_generated_get_half_width_and_height (brush,
shape,
radius,
spikes,
hardness,
aspect_ratio,
angle,
&half_width, &half_height,
&s, &c, &x_axis, &y_axis);
s = sin (gimp_deg_to_rad (angle));
c = cos (gimp_deg_to_rad (angle));
mask = temp_buf_new (half_width * 2 + 1,
half_height * 2 + 1,
1, half_width, half_height, NULL);
short_radius = radius / aspect_ratio;
centerp = temp_buf_data (mask) + half_height * mask->width + half_width;
x_axis.x = c * radius;
x_axis.y = -1.0 * s * radius;
y_axis.x = s * short_radius;
y_axis.y = c * short_radius;
switch (shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
width = ceil (sqrt (x_axis.x * x_axis.x + y_axis.x * y_axis.x));
height = ceil (sqrt (x_axis.y * x_axis.y + y_axis.y * y_axis.y));
break;
case GIMP_BRUSH_GENERATED_SQUARE:
width = ceil (fabs (x_axis.x) + fabs (y_axis.x));
height = ceil (fabs (x_axis.y) + fabs (y_axis.y));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
width = ceil (MAX (fabs (x_axis.x), fabs (y_axis.x)));
height = ceil (MAX (fabs (x_axis.y), fabs (y_axis.y)));
break;
default:
g_return_val_if_reached (NULL);
}
if (spikes > 2)
{
/* could be optimized by respecting the angle */
width = height = ceil (sqrt (radius * radius +
short_radius * short_radius));
y_axis.x = s * radius;
y_axis.y = c * radius;
}
mask = temp_buf_new (width * 2 + 1,
height * 2 + 1,
1, width, height, NULL);
centerp = temp_buf_data (mask) + height * mask->width + width;
/* set up lookup table */
length = OVERSAMPLING * ceil (1 + sqrt (2 *
@ -347,9 +358,9 @@ gimp_brush_generated_calc (GimpBrushGenerated *brush,
ss = sin (- 2 * G_PI / spikes);
/* for an even number of spikes compute one half and mirror it */
for (y = (spikes % 2 ? -half_height : 0); y <= half_height; y++)
for (y = (spikes % 2 ? -height : 0); y <= height; y++)
{
for (x = -half_width; x <= half_width; x++)
for (x = -width; x <= width; x++)
{
gdouble tx, ty, angle;
@ -443,108 +454,6 @@ gimp_brush_generated_scale_mask (GimpBrush *gbrush,
NULL, NULL);
}
/* This function is shared between gimp_brush_get_scaled_size and
gimp_brush_generated_calc, therefore we provide a bunch of optional pointers
for returnvalues. */
static void
gimp_brush_generated_get_half_width_and_height
(GimpBrushGenerated *gbrush,
GimpBrushGeneratedShape shape,
gfloat radius,
gint spikes,
gfloat hardness,
gfloat aspect_ratio,
gdouble angle_in_degrees,
gint *half_width,
gint *half_height,
gdouble *_s,
gdouble *_c,
GimpVector2 *_x_axis,
GimpVector2 *_y_axis)
{
gdouble c, s;
gdouble short_radius;
GimpVector2 x_axis;
GimpVector2 y_axis;
s = sin (gimp_deg_to_rad (angle_in_degrees));
c = cos (gimp_deg_to_rad (angle_in_degrees));
short_radius = radius / aspect_ratio;
x_axis.x = c * radius;
x_axis.y = -1.0 * s * radius;
y_axis.x = s * short_radius;
y_axis.y = c * short_radius;
switch (shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
*half_width = ceil (sqrt (x_axis.x * x_axis.x + y_axis.x * y_axis.x));
*half_height = ceil (sqrt (x_axis.y * x_axis.y + y_axis.y * y_axis.y));
break;
case GIMP_BRUSH_GENERATED_SQUARE:
*half_width = ceil (fabs (x_axis.x) + fabs (y_axis.x));
*half_height = ceil (fabs (x_axis.y) + fabs (y_axis.y));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
*half_width = ceil (MAX (fabs (x_axis.x), fabs (y_axis.x)));
*half_height = ceil (MAX (fabs (x_axis.y), fabs (y_axis.y)));
break;
}
if (spikes > 2)
{
/* could be optimized by respecting the angle */
*half_width = *half_height = ceil (sqrt (radius * radius +
short_radius * short_radius));
y_axis.x = s * radius;
y_axis.y = c * radius;
}
/* These will typically be set then this function is called by
gimp_brush_generated_calc, which needs the values in its algorithms. */
if (_s != NULL)
*_s = s;
if (_c != NULL)
*_c = c;
if (_x_axis != NULL)
*_x_axis = x_axis;
if (_y_axis != NULL)
*_y_axis = y_axis;
}
static void
gimp_brush_generated_real_get_scaled_size (GimpBrush *brush,
gdouble scale,
gint *width,
gint *height)
{
GimpBrushGenerated *gbrush;
gint half_width;
gint half_height;
gbrush = GIMP_BRUSH_GENERATED (brush);
gimp_brush_generated_get_half_width_and_height (gbrush,
gbrush->shape,
gbrush->radius * scale,
gbrush->spikes,
gbrush->hardness,
gbrush->aspect_ratio,
gbrush->angle,
&half_width, &half_height,
NULL, NULL, NULL, NULL);
*width = half_width * 2 + 1;
*height = half_height * 2 + 1;
}
GimpData *
gimp_brush_generated_new (const gchar *name,
GimpBrushGeneratedShape shape,

View file

@ -83,10 +83,11 @@ static TempBuf *gimp_brush_core_get_paint_area (GimpPaintCore *paint_core,
static void gimp_brush_core_real_set_brush (GimpBrushCore *core,
GimpBrush *brush);
static gdouble gimp_brush_core_calc_brush_length_scale
(GimpBrushCore *core,
gdouble scale);
static gdouble gimp_brush_core_calc_brush_size (GimpBrushCore *core,
MaskBuf *mask,
gdouble scale,
gint *width,
gint *height);
static inline void rotate_pointers (gulong **p,
guint32 n);
static MaskBuf * gimp_brush_core_subsample_mask (GimpBrushCore *core,
@ -446,7 +447,8 @@ gimp_brush_core_interpolate (GimpPaintCore *paint_core,
! delta_wheel)
return;
scale = gimp_brush_core_calc_brush_length_scale (core, core->scale);
scale = gimp_brush_core_calc_brush_size (core, NULL, core->scale,
NULL, NULL);
/* calculate the distance traveled in the coordinate space of the brush */
temp_vec = core->brush->x_axis;
@ -679,7 +681,6 @@ gimp_brush_core_get_paint_area (GimpPaintCore *paint_core,
GimpPaintOptions *paint_options)
{
GimpBrushCore *core = GIMP_BRUSH_CORE (paint_core);
gdouble length_scale;
gint x, y;
gint x1, y1, x2, y2;
gint drawable_width, drawable_height;
@ -702,8 +703,8 @@ gimp_brush_core_get_paint_area (GimpPaintCore *paint_core,
core->scale *= paint_options->brush_scale;
}
length_scale = gimp_brush_core_calc_brush_length_scale (core, core->scale);
gimp_brush_get_scaled_size (core->brush, length_scale, &brush_width, &brush_height);
gimp_brush_core_calc_brush_size (core, core->brush->mask, core->scale,
&brush_width, &brush_height);
/* adjust the x and y coordinates to the upper left corner of the brush */
x = (gint) floor (paint_core->cur_coords.x) - (brush_width >> 1);
@ -783,6 +784,8 @@ gimp_brush_core_create_bound_segs (GimpBrushCore *core,
{
TempBuf *mask = NULL;
gdouble scale = 1.0;
gint brush_width;
gint brush_height;
g_return_if_fail (GIMP_IS_BRUSH_CORE (core));
g_return_if_fail (core->main_brush != NULL);
@ -791,7 +794,8 @@ gimp_brush_core_create_bound_segs (GimpBrushCore *core,
if (GIMP_BRUSH_CORE_GET_CLASS (core)->use_scale)
scale *= paint_options->brush_scale;
scale = gimp_brush_core_calc_brush_length_scale (core, scale);
scale = gimp_brush_core_calc_brush_size (core, core->main_brush->mask, scale,
&brush_width, &brush_height);
if (scale > 0.0)
mask = gimp_brush_scale_mask (core->main_brush, scale);
@ -928,14 +932,25 @@ gimp_brush_core_invalidate_cache (GimpBrush *brush,
************************************************************/
static gdouble
gimp_brush_core_calc_brush_length_scale (GimpBrushCore *core,
gdouble scale)
gimp_brush_core_calc_brush_size (GimpBrushCore *core,
MaskBuf *mask,
gdouble scale,
gint *width,
gint *height)
{
gdouble ratio = 1.0;
scale = CLAMP (scale, 0.0, 1.0);
if (scale == 1.0)
{
ratio = scale;
if (mask)
{
*width = mask->width;
*height = mask->height;
}
}
else
{
@ -943,6 +958,12 @@ gimp_brush_core_calc_brush_length_scale (GimpBrushCore *core,
ratio = 1 / 16;
else
ratio = sqrt (scale);
if (mask)
{
*width = MAX ((gint) (mask->width * ratio + 0.5), 1);
*height = MAX ((gint) (mask->height * ratio + 0.5), 1);
}
}
return ratio;
@ -1042,8 +1063,7 @@ gimp_brush_core_subsample_mask (GimpBrushCore *core,
}
dest = mask_buf_new (mask->width + 2,
mask->height + 2,
mask->bytes);
mask->height + 2);
/* Allocate and initialize the accum buffer */
for (i = 0; i < KERNEL_HEIGHT ; i++)
@ -1122,8 +1142,7 @@ gimp_brush_core_pressurize_mask (GimpBrushCore *core,
mask_buf_free (core->pressure_brush);
core->pressure_brush = mask_buf_new (brush_mask->width + 2,
brush_mask->height + 2,
1);
brush_mask->height + 2);
#ifdef FANCY_PRESSURE
/* Create the pressure profile
@ -1259,8 +1278,7 @@ gimp_brush_core_solidify_mask (GimpBrushCore *core,
}
dest = mask_buf_new (brush_mask->width + 2,
brush_mask->height + 2,
brush_mask->bytes);
brush_mask->height + 2);
core->solid_brushes[dest_offset_y][dest_offset_x] = dest;
@ -1296,8 +1314,8 @@ gimp_brush_core_scale_mask (GimpBrushCore *core,
if (scale == 1.0)
return brush->mask;
scale = gimp_brush_core_calc_brush_length_scale (core, scale);
gimp_brush_get_scaled_size (brush, scale, &dest_width, &dest_height);
scale = gimp_brush_core_calc_brush_size (core, brush->mask, scale,
&dest_width, &dest_height);
if (! core->cache_invalid &&
brush->mask == core->last_scale_brush &&
@ -1339,7 +1357,8 @@ gimp_brush_core_scale_pixmap (GimpBrushCore *core,
if (scale == 1.0)
return brush->pixmap;
scale = gimp_brush_core_calc_brush_length_scale (core, scale);
scale = gimp_brush_core_calc_brush_size (core, brush->pixmap, scale,
&dest_width, &dest_height);
if (! core->cache_invalid &&
brush->pixmap == core->last_scale_pixmap &&

View file

@ -131,7 +131,7 @@ gimp_paint_options_class_init (GimpPaintOptionsClass *klass)
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_BRUSH_SCALE,
"brush-scale", NULL,
0.0, 100.0, DEFAULT_BRUSH_SCALE,
0.0, 1.0, DEFAULT_BRUSH_SCALE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_APPLICATION_MODE,
"application-mode", NULL,

View file

@ -78,7 +78,6 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
GtkWidget *menu;
GtkWidget *label;
GtkWidget *button;
GtkWidget *adj;
GtkWidget *incremental_toggle = NULL;
gint table_row = 0;
GType tool_type;
@ -125,14 +124,11 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
if (tool_type != GIMP_TYPE_SMUDGE_TOOL)
{
adj = gimp_prop_scale_entry_new (config, "brush-scale",
GTK_TABLE (table), 0, table_row++,
_("Scale:"),
0.01, 0.1, 2,
FALSE, 0.0, 0.0);
gimp_scale_entry_set_logarithmic (adj, TRUE);
gimp_prop_scale_entry_new (config, "brush-scale",
GTK_TABLE (table), 0, table_row++,
_("Scale:"),
0.01, 0.1, 2,
FALSE, 0.0, 0.0);
}
}