fixed algorithm that calculates the brush size, some code cleanup.
2003-04-09 Sven Neumann <sven@gimp.org> * app/core/gimpbrushgenerated.c: fixed algorithm that calculates the brush size, some code cleanup.
This commit is contained in:

committed by
Sven Neumann

parent
d64317a0cc
commit
fb23d14946
@ -1,3 +1,8 @@
|
|||||||
|
2003-04-09 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
|
* app/core/gimpbrushgenerated.c: fixed algorithm that calculates
|
||||||
|
the brush size, some code cleanup.
|
||||||
|
|
||||||
2003-04-09 Sven Neumann <sven@gimp.org>
|
2003-04-09 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* app/gui/image-menu.c (image_menu_setup): don't try to hide the
|
* app/gui/image-menu.c (image_menu_setup): don't try to hide the
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
|
|
||||||
#include "base/temp-buf.h"
|
#include "base/temp-buf.h"
|
||||||
|
|
||||||
#include "config/gimpbaseconfig.h"
|
|
||||||
|
|
||||||
#include "gimpbrushgenerated.h"
|
#include "gimpbrushgenerated.h"
|
||||||
|
|
||||||
#include "gimp-intl.h"
|
#include "gimp-intl.h"
|
||||||
@ -193,43 +191,40 @@ gimp_brush_generated_duplicate (GimpData *data,
|
|||||||
stingy_memory_use);
|
stingy_memory_use);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static gdouble
|
||||||
gauss (gdouble f)
|
gauss (gdouble f)
|
||||||
{
|
{
|
||||||
/* this aint' a real gauss function */
|
/* this aint' a real gauss function */
|
||||||
if (f < -.5)
|
if (f < -0.5)
|
||||||
{
|
{
|
||||||
f = -1.0 - f;
|
f = -1.0 - f;
|
||||||
return (2.0 * f*f);
|
return (2.0 * f*f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f < .5)
|
if (f < 0.5)
|
||||||
return (1.0 - 2.0 * f*f);
|
return (1.0 - 2.0 * f*f);
|
||||||
|
|
||||||
f = 1.0 -f;
|
f = 1.0 - f;
|
||||||
return (2.0 * f*f);
|
return (2.0 * f*f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#warning FIXME: extern GimpBaseConfig *base_config;
|
|
||||||
#endif
|
|
||||||
extern GimpBaseConfig *base_config;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_brush_generated_dirty (GimpData *data)
|
gimp_brush_generated_dirty (GimpData *data)
|
||||||
{
|
{
|
||||||
GimpBrushGenerated *brush;
|
GimpBrushGenerated *brush;
|
||||||
register GimpBrush *gbrush = NULL;
|
GimpBrush *gbrush = NULL;
|
||||||
register gint x, y;
|
gint x, y;
|
||||||
register guchar *centerp;
|
guchar *centerp;
|
||||||
register gdouble d;
|
gdouble d;
|
||||||
register gdouble exponent;
|
gdouble exponent;
|
||||||
register guchar a;
|
guchar a;
|
||||||
register gint length;
|
gint length;
|
||||||
register guchar *lookup;
|
gint width, height;
|
||||||
register gdouble sum, c, s, tx, ty;
|
guchar *lookup;
|
||||||
gdouble buffer[OVERSAMPLING];
|
gdouble sum;
|
||||||
gint width, height;
|
gdouble c, s;
|
||||||
|
gdouble short_radius;
|
||||||
|
gdouble buffer[OVERSAMPLING];
|
||||||
|
|
||||||
brush = GIMP_BRUSH_GENERATED (data);
|
brush = GIMP_BRUSH_GENERATED (data);
|
||||||
|
|
||||||
@ -238,100 +233,92 @@ gimp_brush_generated_dirty (GimpData *data)
|
|||||||
|
|
||||||
gbrush = GIMP_BRUSH (brush);
|
gbrush = GIMP_BRUSH (brush);
|
||||||
|
|
||||||
if (base_config->stingy_memory_use && gbrush->mask)
|
|
||||||
temp_buf_unswap (gbrush->mask);
|
|
||||||
|
|
||||||
if (gbrush->mask)
|
if (gbrush->mask)
|
||||||
{
|
temp_buf_free (gbrush->mask);
|
||||||
temp_buf_free (gbrush->mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compute the range of the brush. should do a better job than this? */
|
|
||||||
s = sin (gimp_deg_to_rad (brush->angle));
|
s = sin (gimp_deg_to_rad (brush->angle));
|
||||||
c = cos (gimp_deg_to_rad (brush->angle));
|
c = cos (gimp_deg_to_rad (brush->angle));
|
||||||
|
|
||||||
tx = MAX (fabs (c*ceil (brush->radius) - s*ceil (brush->radius)
|
short_radius = brush->radius / brush->aspect_ratio;
|
||||||
/ 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));
|
|
||||||
|
|
||||||
if (brush->radius > tx)
|
gbrush->x_axis.x = c * brush->radius;
|
||||||
width = ceil (tx);
|
gbrush->x_axis.y = -1.0 * s * brush->radius;
|
||||||
else
|
gbrush->y_axis.x = s * short_radius;
|
||||||
width = ceil (brush->radius);
|
gbrush->y_axis.y = c * short_radius;
|
||||||
|
|
||||||
if (brush->radius > ty)
|
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
|
||||||
height = ceil (ty);
|
gbrush->y_axis.x * gbrush->y_axis.x));
|
||||||
else
|
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
|
||||||
height = ceil (brush->radius);
|
gbrush->y_axis.y * gbrush->y_axis.y));
|
||||||
|
|
||||||
/* compute the axis for spacing */
|
gbrush->mask = temp_buf_new (width * 2 + 1,
|
||||||
GIMP_BRUSH (brush)->x_axis.x = c * brush->radius;
|
|
||||||
GIMP_BRUSH (brush)->x_axis.y = -1.0 * s * brush->radius;
|
|
||||||
|
|
||||||
GIMP_BRUSH (brush)->y_axis.x = (s * brush->radius / brush->aspect_ratio);
|
|
||||||
GIMP_BRUSH (brush)->y_axis.y = (c * brush->radius / brush->aspect_ratio);
|
|
||||||
|
|
||||||
gbrush->mask = temp_buf_new (width * 2 + 1,
|
|
||||||
height * 2 + 1,
|
height * 2 + 1,
|
||||||
1, width, height, 0);
|
1, width, height, 0);
|
||||||
centerp = &gbrush->mask->data[height * gbrush->mask->width + width];
|
|
||||||
|
|
||||||
if ((1.0 - brush->hardness) < 0.000001)
|
centerp = temp_buf_data (gbrush->mask) + height * gbrush->mask->width + width;
|
||||||
exponent = 1000000;
|
|
||||||
else
|
|
||||||
exponent = 1/(1.0 - brush->hardness);
|
|
||||||
|
|
||||||
/* set up lookup table */
|
/* set up lookup table */
|
||||||
length = ceil (sqrt (2 * ceil (brush->radius+1) * ceil (brush->radius+1))+1) * OVERSAMPLING;
|
length = OVERSAMPLING * ceil (1 + sqrt (2 *
|
||||||
|
ceil (brush->radius + 1.0) *
|
||||||
|
ceil (brush->radius + 1.0)));
|
||||||
|
|
||||||
|
if ((1.0 - brush->hardness) < 0.000001)
|
||||||
|
exponent = 1000000.0;
|
||||||
|
else
|
||||||
|
exponent = 1.0 / (1.0 - brush->hardness);
|
||||||
|
|
||||||
lookup = g_malloc (length);
|
lookup = g_malloc (length);
|
||||||
sum = 0.0;
|
sum = 0.0;
|
||||||
|
|
||||||
for (x = 0; x < OVERSAMPLING; x++)
|
for (x = 0; x < OVERSAMPLING; x++)
|
||||||
{
|
{
|
||||||
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
|
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
|
||||||
|
|
||||||
if (d > brush->radius)
|
if (d > brush->radius)
|
||||||
buffer[x] = 0.0;
|
buffer[x] = 0.0;
|
||||||
else
|
else
|
||||||
/* buffer[x] = (1.0 - pow (d/brush->radius, exponent)); */
|
buffer[x] = gauss (pow (d / brush->radius, exponent));
|
||||||
buffer[x] = gauss (pow (d/brush->radius, exponent));
|
|
||||||
sum += buffer[x];
|
sum += buffer[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = 0; d < brush->radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
|
for (x = 0; d < brush->radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
|
||||||
{
|
{
|
||||||
sum -= buffer[x % OVERSAMPLING];
|
sum -= buffer[x % OVERSAMPLING];
|
||||||
|
|
||||||
if (d > brush->radius)
|
if (d > brush->radius)
|
||||||
buffer[x % OVERSAMPLING] = 0.0;
|
buffer[x % OVERSAMPLING] = 0.0;
|
||||||
else
|
else
|
||||||
/* buffer[x%OVERSAMPLING] = (1.0 - pow (d/brush->radius, exponent)); */
|
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
|
||||||
buffer[x % OVERSAMPLING] = gauss (pow (d/brush->radius, exponent));
|
|
||||||
sum += buffer[x%OVERSAMPLING];
|
sum += buffer[x % OVERSAMPLING];
|
||||||
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
|
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (x < length)
|
while (x < length)
|
||||||
{
|
{
|
||||||
lookup[x++] = 0;
|
lookup[x++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute one half and mirror it */
|
/* compute one half and mirror it */
|
||||||
for (y = 0; y <= height; y++)
|
for (y = 0; y <= height; y++)
|
||||||
{
|
{
|
||||||
for (x = -width; x <= width; x++)
|
for (x = -width; x <= width; x++)
|
||||||
{
|
{
|
||||||
|
gdouble tx, ty;
|
||||||
|
|
||||||
tx = c*x - s*y;
|
tx = c*x - s*y;
|
||||||
ty = c*y + s*x;
|
ty = c*y + s*x;
|
||||||
ty *= brush->aspect_ratio;
|
ty *= brush->aspect_ratio;
|
||||||
d = sqrt (tx*tx + ty*ty);
|
d = sqrt (tx*tx + ty*ty);
|
||||||
if (d < brush->radius+1)
|
|
||||||
|
if (d < brush->radius + 1)
|
||||||
a = lookup[(gint) RINT (d * OVERSAMPLING)];
|
a = lookup[(gint) RINT (d * OVERSAMPLING)];
|
||||||
else
|
else
|
||||||
a = 0;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
|
|
||||||
#include "base/temp-buf.h"
|
#include "base/temp-buf.h"
|
||||||
|
|
||||||
#include "config/gimpbaseconfig.h"
|
|
||||||
|
|
||||||
#include "gimpbrushgenerated.h"
|
#include "gimpbrushgenerated.h"
|
||||||
|
|
||||||
#include "gimp-intl.h"
|
#include "gimp-intl.h"
|
||||||
@ -193,43 +191,40 @@ gimp_brush_generated_duplicate (GimpData *data,
|
|||||||
stingy_memory_use);
|
stingy_memory_use);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static gdouble
|
||||||
gauss (gdouble f)
|
gauss (gdouble f)
|
||||||
{
|
{
|
||||||
/* this aint' a real gauss function */
|
/* this aint' a real gauss function */
|
||||||
if (f < -.5)
|
if (f < -0.5)
|
||||||
{
|
{
|
||||||
f = -1.0 - f;
|
f = -1.0 - f;
|
||||||
return (2.0 * f*f);
|
return (2.0 * f*f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f < .5)
|
if (f < 0.5)
|
||||||
return (1.0 - 2.0 * f*f);
|
return (1.0 - 2.0 * f*f);
|
||||||
|
|
||||||
f = 1.0 -f;
|
f = 1.0 - f;
|
||||||
return (2.0 * f*f);
|
return (2.0 * f*f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#warning FIXME: extern GimpBaseConfig *base_config;
|
|
||||||
#endif
|
|
||||||
extern GimpBaseConfig *base_config;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_brush_generated_dirty (GimpData *data)
|
gimp_brush_generated_dirty (GimpData *data)
|
||||||
{
|
{
|
||||||
GimpBrushGenerated *brush;
|
GimpBrushGenerated *brush;
|
||||||
register GimpBrush *gbrush = NULL;
|
GimpBrush *gbrush = NULL;
|
||||||
register gint x, y;
|
gint x, y;
|
||||||
register guchar *centerp;
|
guchar *centerp;
|
||||||
register gdouble d;
|
gdouble d;
|
||||||
register gdouble exponent;
|
gdouble exponent;
|
||||||
register guchar a;
|
guchar a;
|
||||||
register gint length;
|
gint length;
|
||||||
register guchar *lookup;
|
gint width, height;
|
||||||
register gdouble sum, c, s, tx, ty;
|
guchar *lookup;
|
||||||
gdouble buffer[OVERSAMPLING];
|
gdouble sum;
|
||||||
gint width, height;
|
gdouble c, s;
|
||||||
|
gdouble short_radius;
|
||||||
|
gdouble buffer[OVERSAMPLING];
|
||||||
|
|
||||||
brush = GIMP_BRUSH_GENERATED (data);
|
brush = GIMP_BRUSH_GENERATED (data);
|
||||||
|
|
||||||
@ -238,100 +233,92 @@ gimp_brush_generated_dirty (GimpData *data)
|
|||||||
|
|
||||||
gbrush = GIMP_BRUSH (brush);
|
gbrush = GIMP_BRUSH (brush);
|
||||||
|
|
||||||
if (base_config->stingy_memory_use && gbrush->mask)
|
|
||||||
temp_buf_unswap (gbrush->mask);
|
|
||||||
|
|
||||||
if (gbrush->mask)
|
if (gbrush->mask)
|
||||||
{
|
temp_buf_free (gbrush->mask);
|
||||||
temp_buf_free (gbrush->mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compute the range of the brush. should do a better job than this? */
|
|
||||||
s = sin (gimp_deg_to_rad (brush->angle));
|
s = sin (gimp_deg_to_rad (brush->angle));
|
||||||
c = cos (gimp_deg_to_rad (brush->angle));
|
c = cos (gimp_deg_to_rad (brush->angle));
|
||||||
|
|
||||||
tx = MAX (fabs (c*ceil (brush->radius) - s*ceil (brush->radius)
|
short_radius = brush->radius / brush->aspect_ratio;
|
||||||
/ 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));
|
|
||||||
|
|
||||||
if (brush->radius > tx)
|
gbrush->x_axis.x = c * brush->radius;
|
||||||
width = ceil (tx);
|
gbrush->x_axis.y = -1.0 * s * brush->radius;
|
||||||
else
|
gbrush->y_axis.x = s * short_radius;
|
||||||
width = ceil (brush->radius);
|
gbrush->y_axis.y = c * short_radius;
|
||||||
|
|
||||||
if (brush->radius > ty)
|
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
|
||||||
height = ceil (ty);
|
gbrush->y_axis.x * gbrush->y_axis.x));
|
||||||
else
|
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
|
||||||
height = ceil (brush->radius);
|
gbrush->y_axis.y * gbrush->y_axis.y));
|
||||||
|
|
||||||
/* compute the axis for spacing */
|
gbrush->mask = temp_buf_new (width * 2 + 1,
|
||||||
GIMP_BRUSH (brush)->x_axis.x = c * brush->radius;
|
|
||||||
GIMP_BRUSH (brush)->x_axis.y = -1.0 * s * brush->radius;
|
|
||||||
|
|
||||||
GIMP_BRUSH (brush)->y_axis.x = (s * brush->radius / brush->aspect_ratio);
|
|
||||||
GIMP_BRUSH (brush)->y_axis.y = (c * brush->radius / brush->aspect_ratio);
|
|
||||||
|
|
||||||
gbrush->mask = temp_buf_new (width * 2 + 1,
|
|
||||||
height * 2 + 1,
|
height * 2 + 1,
|
||||||
1, width, height, 0);
|
1, width, height, 0);
|
||||||
centerp = &gbrush->mask->data[height * gbrush->mask->width + width];
|
|
||||||
|
|
||||||
if ((1.0 - brush->hardness) < 0.000001)
|
centerp = temp_buf_data (gbrush->mask) + height * gbrush->mask->width + width;
|
||||||
exponent = 1000000;
|
|
||||||
else
|
|
||||||
exponent = 1/(1.0 - brush->hardness);
|
|
||||||
|
|
||||||
/* set up lookup table */
|
/* set up lookup table */
|
||||||
length = ceil (sqrt (2 * ceil (brush->radius+1) * ceil (brush->radius+1))+1) * OVERSAMPLING;
|
length = OVERSAMPLING * ceil (1 + sqrt (2 *
|
||||||
|
ceil (brush->radius + 1.0) *
|
||||||
|
ceil (brush->radius + 1.0)));
|
||||||
|
|
||||||
|
if ((1.0 - brush->hardness) < 0.000001)
|
||||||
|
exponent = 1000000.0;
|
||||||
|
else
|
||||||
|
exponent = 1.0 / (1.0 - brush->hardness);
|
||||||
|
|
||||||
lookup = g_malloc (length);
|
lookup = g_malloc (length);
|
||||||
sum = 0.0;
|
sum = 0.0;
|
||||||
|
|
||||||
for (x = 0; x < OVERSAMPLING; x++)
|
for (x = 0; x < OVERSAMPLING; x++)
|
||||||
{
|
{
|
||||||
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
|
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
|
||||||
|
|
||||||
if (d > brush->radius)
|
if (d > brush->radius)
|
||||||
buffer[x] = 0.0;
|
buffer[x] = 0.0;
|
||||||
else
|
else
|
||||||
/* buffer[x] = (1.0 - pow (d/brush->radius, exponent)); */
|
buffer[x] = gauss (pow (d / brush->radius, exponent));
|
||||||
buffer[x] = gauss (pow (d/brush->radius, exponent));
|
|
||||||
sum += buffer[x];
|
sum += buffer[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = 0; d < brush->radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
|
for (x = 0; d < brush->radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
|
||||||
{
|
{
|
||||||
sum -= buffer[x % OVERSAMPLING];
|
sum -= buffer[x % OVERSAMPLING];
|
||||||
|
|
||||||
if (d > brush->radius)
|
if (d > brush->radius)
|
||||||
buffer[x % OVERSAMPLING] = 0.0;
|
buffer[x % OVERSAMPLING] = 0.0;
|
||||||
else
|
else
|
||||||
/* buffer[x%OVERSAMPLING] = (1.0 - pow (d/brush->radius, exponent)); */
|
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
|
||||||
buffer[x % OVERSAMPLING] = gauss (pow (d/brush->radius, exponent));
|
|
||||||
sum += buffer[x%OVERSAMPLING];
|
sum += buffer[x % OVERSAMPLING];
|
||||||
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
|
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (x < length)
|
while (x < length)
|
||||||
{
|
{
|
||||||
lookup[x++] = 0;
|
lookup[x++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute one half and mirror it */
|
/* compute one half and mirror it */
|
||||||
for (y = 0; y <= height; y++)
|
for (y = 0; y <= height; y++)
|
||||||
{
|
{
|
||||||
for (x = -width; x <= width; x++)
|
for (x = -width; x <= width; x++)
|
||||||
{
|
{
|
||||||
|
gdouble tx, ty;
|
||||||
|
|
||||||
tx = c*x - s*y;
|
tx = c*x - s*y;
|
||||||
ty = c*y + s*x;
|
ty = c*y + s*x;
|
||||||
ty *= brush->aspect_ratio;
|
ty *= brush->aspect_ratio;
|
||||||
d = sqrt (tx*tx + ty*ty);
|
d = sqrt (tx*tx + ty*ty);
|
||||||
if (d < brush->radius+1)
|
|
||||||
|
if (d < brush->radius + 1)
|
||||||
a = lookup[(gint) RINT (d * OVERSAMPLING)];
|
a = lookup[(gint) RINT (d * OVERSAMPLING)];
|
||||||
else
|
else
|
||||||
a = 0;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
|
|
||||||
#include "base/temp-buf.h"
|
#include "base/temp-buf.h"
|
||||||
|
|
||||||
#include "config/gimpbaseconfig.h"
|
|
||||||
|
|
||||||
#include "gimpbrushgenerated.h"
|
#include "gimpbrushgenerated.h"
|
||||||
|
|
||||||
#include "gimp-intl.h"
|
#include "gimp-intl.h"
|
||||||
@ -193,43 +191,40 @@ gimp_brush_generated_duplicate (GimpData *data,
|
|||||||
stingy_memory_use);
|
stingy_memory_use);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static gdouble
|
||||||
gauss (gdouble f)
|
gauss (gdouble f)
|
||||||
{
|
{
|
||||||
/* this aint' a real gauss function */
|
/* this aint' a real gauss function */
|
||||||
if (f < -.5)
|
if (f < -0.5)
|
||||||
{
|
{
|
||||||
f = -1.0 - f;
|
f = -1.0 - f;
|
||||||
return (2.0 * f*f);
|
return (2.0 * f*f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f < .5)
|
if (f < 0.5)
|
||||||
return (1.0 - 2.0 * f*f);
|
return (1.0 - 2.0 * f*f);
|
||||||
|
|
||||||
f = 1.0 -f;
|
f = 1.0 - f;
|
||||||
return (2.0 * f*f);
|
return (2.0 * f*f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#warning FIXME: extern GimpBaseConfig *base_config;
|
|
||||||
#endif
|
|
||||||
extern GimpBaseConfig *base_config;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_brush_generated_dirty (GimpData *data)
|
gimp_brush_generated_dirty (GimpData *data)
|
||||||
{
|
{
|
||||||
GimpBrushGenerated *brush;
|
GimpBrushGenerated *brush;
|
||||||
register GimpBrush *gbrush = NULL;
|
GimpBrush *gbrush = NULL;
|
||||||
register gint x, y;
|
gint x, y;
|
||||||
register guchar *centerp;
|
guchar *centerp;
|
||||||
register gdouble d;
|
gdouble d;
|
||||||
register gdouble exponent;
|
gdouble exponent;
|
||||||
register guchar a;
|
guchar a;
|
||||||
register gint length;
|
gint length;
|
||||||
register guchar *lookup;
|
gint width, height;
|
||||||
register gdouble sum, c, s, tx, ty;
|
guchar *lookup;
|
||||||
gdouble buffer[OVERSAMPLING];
|
gdouble sum;
|
||||||
gint width, height;
|
gdouble c, s;
|
||||||
|
gdouble short_radius;
|
||||||
|
gdouble buffer[OVERSAMPLING];
|
||||||
|
|
||||||
brush = GIMP_BRUSH_GENERATED (data);
|
brush = GIMP_BRUSH_GENERATED (data);
|
||||||
|
|
||||||
@ -238,100 +233,92 @@ gimp_brush_generated_dirty (GimpData *data)
|
|||||||
|
|
||||||
gbrush = GIMP_BRUSH (brush);
|
gbrush = GIMP_BRUSH (brush);
|
||||||
|
|
||||||
if (base_config->stingy_memory_use && gbrush->mask)
|
|
||||||
temp_buf_unswap (gbrush->mask);
|
|
||||||
|
|
||||||
if (gbrush->mask)
|
if (gbrush->mask)
|
||||||
{
|
temp_buf_free (gbrush->mask);
|
||||||
temp_buf_free (gbrush->mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compute the range of the brush. should do a better job than this? */
|
|
||||||
s = sin (gimp_deg_to_rad (brush->angle));
|
s = sin (gimp_deg_to_rad (brush->angle));
|
||||||
c = cos (gimp_deg_to_rad (brush->angle));
|
c = cos (gimp_deg_to_rad (brush->angle));
|
||||||
|
|
||||||
tx = MAX (fabs (c*ceil (brush->radius) - s*ceil (brush->radius)
|
short_radius = brush->radius / brush->aspect_ratio;
|
||||||
/ 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));
|
|
||||||
|
|
||||||
if (brush->radius > tx)
|
gbrush->x_axis.x = c * brush->radius;
|
||||||
width = ceil (tx);
|
gbrush->x_axis.y = -1.0 * s * brush->radius;
|
||||||
else
|
gbrush->y_axis.x = s * short_radius;
|
||||||
width = ceil (brush->radius);
|
gbrush->y_axis.y = c * short_radius;
|
||||||
|
|
||||||
if (brush->radius > ty)
|
width = ceil (sqrt (gbrush->x_axis.x * gbrush->x_axis.x +
|
||||||
height = ceil (ty);
|
gbrush->y_axis.x * gbrush->y_axis.x));
|
||||||
else
|
height = ceil (sqrt (gbrush->x_axis.y * gbrush->x_axis.y +
|
||||||
height = ceil (brush->radius);
|
gbrush->y_axis.y * gbrush->y_axis.y));
|
||||||
|
|
||||||
/* compute the axis for spacing */
|
gbrush->mask = temp_buf_new (width * 2 + 1,
|
||||||
GIMP_BRUSH (brush)->x_axis.x = c * brush->radius;
|
|
||||||
GIMP_BRUSH (brush)->x_axis.y = -1.0 * s * brush->radius;
|
|
||||||
|
|
||||||
GIMP_BRUSH (brush)->y_axis.x = (s * brush->radius / brush->aspect_ratio);
|
|
||||||
GIMP_BRUSH (brush)->y_axis.y = (c * brush->radius / brush->aspect_ratio);
|
|
||||||
|
|
||||||
gbrush->mask = temp_buf_new (width * 2 + 1,
|
|
||||||
height * 2 + 1,
|
height * 2 + 1,
|
||||||
1, width, height, 0);
|
1, width, height, 0);
|
||||||
centerp = &gbrush->mask->data[height * gbrush->mask->width + width];
|
|
||||||
|
|
||||||
if ((1.0 - brush->hardness) < 0.000001)
|
centerp = temp_buf_data (gbrush->mask) + height * gbrush->mask->width + width;
|
||||||
exponent = 1000000;
|
|
||||||
else
|
|
||||||
exponent = 1/(1.0 - brush->hardness);
|
|
||||||
|
|
||||||
/* set up lookup table */
|
/* set up lookup table */
|
||||||
length = ceil (sqrt (2 * ceil (brush->radius+1) * ceil (brush->radius+1))+1) * OVERSAMPLING;
|
length = OVERSAMPLING * ceil (1 + sqrt (2 *
|
||||||
|
ceil (brush->radius + 1.0) *
|
||||||
|
ceil (brush->radius + 1.0)));
|
||||||
|
|
||||||
|
if ((1.0 - brush->hardness) < 0.000001)
|
||||||
|
exponent = 1000000.0;
|
||||||
|
else
|
||||||
|
exponent = 1.0 / (1.0 - brush->hardness);
|
||||||
|
|
||||||
lookup = g_malloc (length);
|
lookup = g_malloc (length);
|
||||||
sum = 0.0;
|
sum = 0.0;
|
||||||
|
|
||||||
for (x = 0; x < OVERSAMPLING; x++)
|
for (x = 0; x < OVERSAMPLING; x++)
|
||||||
{
|
{
|
||||||
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
|
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
|
||||||
|
|
||||||
if (d > brush->radius)
|
if (d > brush->radius)
|
||||||
buffer[x] = 0.0;
|
buffer[x] = 0.0;
|
||||||
else
|
else
|
||||||
/* buffer[x] = (1.0 - pow (d/brush->radius, exponent)); */
|
buffer[x] = gauss (pow (d / brush->radius, exponent));
|
||||||
buffer[x] = gauss (pow (d/brush->radius, exponent));
|
|
||||||
sum += buffer[x];
|
sum += buffer[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = 0; d < brush->radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
|
for (x = 0; d < brush->radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
|
||||||
{
|
{
|
||||||
sum -= buffer[x % OVERSAMPLING];
|
sum -= buffer[x % OVERSAMPLING];
|
||||||
|
|
||||||
if (d > brush->radius)
|
if (d > brush->radius)
|
||||||
buffer[x % OVERSAMPLING] = 0.0;
|
buffer[x % OVERSAMPLING] = 0.0;
|
||||||
else
|
else
|
||||||
/* buffer[x%OVERSAMPLING] = (1.0 - pow (d/brush->radius, exponent)); */
|
buffer[x % OVERSAMPLING] = gauss (pow (d / brush->radius, exponent));
|
||||||
buffer[x % OVERSAMPLING] = gauss (pow (d/brush->radius, exponent));
|
|
||||||
sum += buffer[x%OVERSAMPLING];
|
sum += buffer[x % OVERSAMPLING];
|
||||||
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
|
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (x < length)
|
while (x < length)
|
||||||
{
|
{
|
||||||
lookup[x++] = 0;
|
lookup[x++] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute one half and mirror it */
|
/* compute one half and mirror it */
|
||||||
for (y = 0; y <= height; y++)
|
for (y = 0; y <= height; y++)
|
||||||
{
|
{
|
||||||
for (x = -width; x <= width; x++)
|
for (x = -width; x <= width; x++)
|
||||||
{
|
{
|
||||||
|
gdouble tx, ty;
|
||||||
|
|
||||||
tx = c*x - s*y;
|
tx = c*x - s*y;
|
||||||
ty = c*y + s*x;
|
ty = c*y + s*x;
|
||||||
ty *= brush->aspect_ratio;
|
ty *= brush->aspect_ratio;
|
||||||
d = sqrt (tx*tx + ty*ty);
|
d = sqrt (tx*tx + ty*ty);
|
||||||
if (d < brush->radius+1)
|
|
||||||
|
if (d < brush->radius + 1)
|
||||||
a = lookup[(gint) RINT (d * OVERSAMPLING)];
|
a = lookup[(gint) RINT (d * OVERSAMPLING)];
|
||||||
else
|
else
|
||||||
a = 0;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user