----------------------------------------------------------------------

----------------------------------------------------------------------
 Modified Files:
 	ChangeLog app/Makefile.am app/brush_select.c app/gimpbrush.c
 	app/gimpbrush.h app/gimpbrushgenerated.c app/gimpbrushlist.c
 	app/gimplist.c app/paint_core.c app/paint_core.h
    added axis to brushes.  paint_core now references a brush instead
    of a mask.  cleaned up some [brush]list removal stuff.


 Added Files:
 	app/vector2d.c app/vector2d.h
    very basic vector math struct/functions.
----------------------------------------------------------------------
This commit is contained in:
jaycox 1998-07-24 08:56:18 +00:00
parent cb8a1d0231
commit 69d922412a
22 changed files with 324 additions and 104 deletions

View File

@ -1,3 +1,17 @@
Fri Jul 24 01:33:13 PDT 1998 Jay Cox <jaycox@earthlink.net>
* app/vector2d.[ch] Makefile.am: new files for vector math.
Very minimal.
* gimpbrush.[ch]: added support for brush axis.
* paint_core.[ch]: replaced the mask field with a brush field.
modified paint_core_interpolate to use brush axis.
* gimpbrushlist.c: modified gimp_list_destroy.
* gimpbrushlist.c: fixed some broken brush removal stuff.
Thu Jul 23 21:57:25 CDT 1998 Shawn T. Amundson <amundson@gimp.org>
* app/interface.c: usize statusbar to 1 width

View File

@ -293,6 +293,8 @@ gimp_SOURCES = \
undo_cmds.c \
undo_cmds.h \
wilber.h \
vector2d.c \
vector2d.h \
xcf.c \
xcf.h

View File

@ -353,7 +353,8 @@ brush_select_select (BrushSelectP bsp,
int index)
{
int row, col;
if (index < 0)
return;
update_active_brush_field (bsp);
row = index / NUM_BRUSH_COLUMNS;
col = index - row * NUM_BRUSH_COLUMNS;
@ -950,6 +951,8 @@ preview_scroll_update (GtkAdjustment *adjustment,
if (active)
{
index = gimp_brush_list_get_brush_index(brush_list, active);
if (index < 0)
return;
row = index / NUM_BRUSH_COLUMNS;
col = index - row * NUM_BRUSH_COLUMNS;
brush_select_show_selected (bsp, row, col);

View File

@ -78,6 +78,10 @@ gimp_brush_init(GimpBrush *brush)
brush->name = NULL;
brush->spacing = 20;
brush->mask = NULL;
brush->x_axis.x = 15.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = 15.0;
}
GtkType gimp_brush_get_type(void)
@ -208,7 +212,11 @@ gimp_brush_load(GimpBrush *brush, char *filename)
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
0, 0, NULL);
brush->spacing = header.spacing;
/* set up spacing axis */
brush->x_axis.x = header.width / 2.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = header.height / 2.0;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask), 1, header.width * header.height,
fp)) < header.width * header.height)

View File

@ -78,6 +78,10 @@ gimp_brush_init(GimpBrush *brush)
brush->name = NULL;
brush->spacing = 20;
brush->mask = NULL;
brush->x_axis.x = 15.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = 15.0;
}
GtkType gimp_brush_get_type(void)
@ -208,7 +212,11 @@ gimp_brush_load(GimpBrush *brush, char *filename)
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
0, 0, NULL);
brush->spacing = header.spacing;
/* set up spacing axis */
brush->x_axis.x = header.width / 2.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = header.height / 2.0;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask), 1, header.width * header.height,
fp)) < header.width * header.height)

View File

@ -21,6 +21,7 @@
#include "gimpobjectP.h"
#include "temp_buf.h"
#include "vector2d.h"
typedef struct _GimpBrush GimpBrush, * GimpBrushP;
@ -30,6 +31,8 @@ struct _GimpBrush
char * filename; /* actual filename--brush's location on disk */
char * name; /* brush's name--for brush selection dialog */
int spacing; /* brush's spacing */
vector2d x_axis; /* for calculating brush spacing */
vector2d y_axis; /* for calculating brush spacing */
TempBuf * mask; /* the actual mask... */
};

View File

@ -199,6 +199,19 @@ gimp_brush_generated_thaw(GimpBrushGenerated *brush)
if (brush->freeze == 0)
gimp_brush_generated_generate(brush);
}
static
double gauss(double f)
{ /* this aint' a real gauss function */
if (f < -.5)
{
f = -1.0-f;
return (2.0*f*f);
}
if (f < .5)
return (1.0-2.0*f*f);
f = 1.0 -f;
return (2.0*f*f);
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
@ -243,7 +256,13 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
height = ceil(ty);
else
height = ceil(brush->radius);
/* compute the axis for spacing */
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,
1, width, height, 0);
@ -262,7 +281,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x] = (1.0 - pow(d/brush->radius, exponent));*/
buffer[x] = gauss(pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
@ -271,7 +291,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x%OVERSAMPLING] = (1.0 - 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));
}

View File

@ -199,6 +199,19 @@ gimp_brush_generated_thaw(GimpBrushGenerated *brush)
if (brush->freeze == 0)
gimp_brush_generated_generate(brush);
}
static
double gauss(double f)
{ /* this aint' a real gauss function */
if (f < -.5)
{
f = -1.0-f;
return (2.0*f*f);
}
if (f < .5)
return (1.0-2.0*f*f);
f = 1.0 -f;
return (2.0*f*f);
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
@ -243,7 +256,13 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
height = ceil(ty);
else
height = ceil(brush->radius);
/* compute the axis for spacing */
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,
1, width, height, 0);
@ -262,7 +281,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x] = (1.0 - pow(d/brush->radius, exponent));*/
buffer[x] = gauss(pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
@ -271,7 +291,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x%OVERSAMPLING] = (1.0 - 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));
}

View File

@ -199,6 +199,19 @@ gimp_brush_generated_thaw(GimpBrushGenerated *brush)
if (brush->freeze == 0)
gimp_brush_generated_generate(brush);
}
static
double gauss(double f)
{ /* this aint' a real gauss function */
if (f < -.5)
{
f = -1.0-f;
return (2.0*f*f);
}
if (f < .5)
return (1.0-2.0*f*f);
f = 1.0 -f;
return (2.0*f*f);
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
@ -243,7 +256,13 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
height = ceil(ty);
else
height = ceil(brush->radius);
/* compute the axis for spacing */
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,
1, width, height, 0);
@ -262,7 +281,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x] = (1.0 - pow(d/brush->radius, exponent));*/
buffer[x] = gauss(pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
@ -271,7 +291,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x%OVERSAMPLING] = (1.0 - 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));
}

View File

@ -38,13 +38,9 @@ static void
gimp_list_destroy (GtkObject* ob)
{
GimpList* list=GIMP_LIST(ob);
GSList* node;
for(node=list->list;node;node=node->next){
if(!list->weak)
gtk_object_unref(GTK_OBJECT(node->data));
gtk_signal_emit (GTK_OBJECT(list),
gimp_list_signals[REMOVE],
node->data);
while(list->list) /* ought to put a sanity check in here... */
{
gimp_list_remove(list, list->list->data);
}
g_slist_free(list->list);
GTK_OBJECT_CLASS(parent_class)->destroy (ob);
@ -68,12 +64,10 @@ gimp_list_class_init (GimpListClass* klass)
object_class->destroy = gimp_list_destroy;
gimp_list_signals[ADD]=
gimp_signal_new ("add", GTK_RUN_FIRST, type,
GTK_SIGNAL_OFFSET (GimpListClass, add),
gimp_signal_new ("add", GTK_RUN_FIRST, type, 0,
gimp_sigtype_pointer);
gimp_list_signals[REMOVE]=
gimp_signal_new ("remove", GTK_RUN_FIRST, type,
GTK_SIGNAL_OFFSET (GimpListClass, remove),
gimp_signal_new ("remove", GTK_RUN_FIRST, type, 0,
gimp_sigtype_pointer);
gtk_object_class_add_signals (object_class,
gimp_list_signals,
@ -137,6 +131,8 @@ gimp_list_add (GimpList* list, gpointer val)
else
gtk_object_ref(GTK_OBJECT(val));
GIMP_LIST_CLASS(GTK_OBJECT(list)->klass)->add(list, val);
gtk_signal_emit (GTK_OBJECT(list), gimp_list_signals[ADD], val);
return TRUE;
}
@ -147,8 +143,11 @@ gimp_list_remove (GimpList* list, gpointer val)
g_return_val_if_fail(list, FALSE);
if(!g_slist_find(list->list, val))
return FALSE;
{
printf("can't find val\n");
return FALSE;
}
GIMP_LIST_CLASS(GTK_OBJECT(list)->klass)->remove(list, val);
gtk_signal_emit (GTK_OBJECT(list), gimp_list_signals[REMOVE], val);

View File

@ -78,6 +78,10 @@ gimp_brush_init(GimpBrush *brush)
brush->name = NULL;
brush->spacing = 20;
brush->mask = NULL;
brush->x_axis.x = 15.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = 15.0;
}
GtkType gimp_brush_get_type(void)
@ -208,7 +212,11 @@ gimp_brush_load(GimpBrush *brush, char *filename)
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
0, 0, NULL);
brush->spacing = header.spacing;
/* set up spacing axis */
brush->x_axis.x = header.width / 2.0;
brush->x_axis.y = 0.0;
brush->y_axis.x = 0.0;
brush->y_axis.y = header.height / 2.0;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask), 1, header.width * header.height,
fp)) < header.width * header.height)

View File

@ -21,6 +21,7 @@
#include "gimpobjectP.h"
#include "temp_buf.h"
#include "vector2d.h"
typedef struct _GimpBrush GimpBrush, * GimpBrushP;
@ -30,6 +31,8 @@ struct _GimpBrush
char * filename; /* actual filename--brush's location on disk */
char * name; /* brush's name--for brush selection dialog */
int spacing; /* brush's spacing */
vector2d x_axis; /* for calculating brush spacing */
vector2d y_axis; /* for calculating brush spacing */
TempBuf * mask; /* the actual mask... */
};

View File

@ -199,6 +199,19 @@ gimp_brush_generated_thaw(GimpBrushGenerated *brush)
if (brush->freeze == 0)
gimp_brush_generated_generate(brush);
}
static
double gauss(double f)
{ /* this aint' a real gauss function */
if (f < -.5)
{
f = -1.0-f;
return (2.0*f*f);
}
if (f < .5)
return (1.0-2.0*f*f);
f = 1.0 -f;
return (2.0*f*f);
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
@ -243,7 +256,13 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
height = ceil(ty);
else
height = ceil(brush->radius);
/* compute the axis for spacing */
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,
1, width, height, 0);
@ -262,7 +281,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x] = (1.0 - pow(d/brush->radius, exponent));*/
buffer[x] = gauss(pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
@ -271,7 +291,8 @@ gimp_brush_generated_generate(GimpBrushGenerated *brush)
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
/* buffer[x%OVERSAMPLING] = (1.0 - 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));
}

View File

@ -76,7 +76,7 @@ gimp_brush_list_add_func(GimpList* list, gpointer val)
}
static void
gimp_list_remove_func(GimpList* list, gpointer val)
gimp_brush_list_remove_func(GimpList* list, gpointer val)
{
list->list=g_slist_remove(list->list, val);
GIMP_BRUSH_LIST(list)->num_brushes--;
@ -89,7 +89,7 @@ gimp_brush_list_class_init (GimpBrushListClass *klass)
gimp_list_class = GIMP_LIST_CLASS(klass);
gimp_list_class->add = gimp_brush_list_add_func;
gimp_list_class->remove = gimp_brush_list_add_func;
gimp_list_class->remove = gimp_brush_list_remove_func;
parent_class = gtk_type_class (gimp_list_get_type ());
}
@ -135,10 +135,8 @@ brushes_init (int no_data)
if (brush_list)
brushes_free();
brush_list = NULL;
brush_list = gimp_brush_list_new();
else
brush_list = gimp_brush_list_new();
if (brush_path == NULL || (no_data))
create_default_brush ();
@ -171,13 +169,14 @@ brush_compare_func (gconstpointer first, gconstpointer second)
void
brushes_free ()
{
if (brush_list) {
gimp_object_unref (GIMP_OBJECT(brush_list));
if (brush_list)
{
while (GIMP_LIST(brush_list)->list)
gimp_brush_list_remove(brush_list, GIMP_LIST(brush_list)->list->data);
}
have_default_brush = 0;
active_brush = NULL;
brush_list = NULL;
}
@ -203,7 +202,7 @@ get_active_brush ()
}
else if (! active_brush && brush_list)
/* need a gimp_list_get_first() type function */
active_brush = (GimpBrush *) GIMP_LIST(brush_list)->list->data;
select_brush((GimpBrush *) GIMP_LIST(brush_list)->list->data);
return active_brush;
}
@ -227,7 +226,7 @@ create_default_brush ()
temp_buf_swap (GIMP_BRUSH(brush)->mask);
/* Make this the default, active brush */
active_brush = GIMP_BRUSH(brush);
select_brush(GIMP_BRUSH(brush));
have_default_brush = 1;
}
@ -237,18 +236,8 @@ int
gimp_brush_list_get_brush_index (GimpBrushList *brush_list,
GimpBrush *brush)
{
int index = 0;
GSList *list;
/* fix me: make a gimp_list function that does this? */
list = GIMP_LIST(brush_list)->list;
while (list)
{
if (list->data == brush)
return index;
index++;
list = list->next;
}
return -1;
return g_slist_index (GIMP_LIST(brush_list)->list, brush);
}
GimpBrush *
@ -390,8 +379,13 @@ select_brush (GimpBrush * brush)
if (stingy_memory_use)
temp_buf_swap (active_brush->mask);
if (active_brush)
gtk_object_unref(GTK_OBJECT(active_brush));
/* Set the active brush */
active_brush = brush;
gtk_object_ref(GTK_OBJECT(active_brush));
/* Make sure the active brush is unswapped... */
if (stingy_memory_use)

View File

@ -38,13 +38,9 @@ static void
gimp_list_destroy (GtkObject* ob)
{
GimpList* list=GIMP_LIST(ob);
GSList* node;
for(node=list->list;node;node=node->next){
if(!list->weak)
gtk_object_unref(GTK_OBJECT(node->data));
gtk_signal_emit (GTK_OBJECT(list),
gimp_list_signals[REMOVE],
node->data);
while(list->list) /* ought to put a sanity check in here... */
{
gimp_list_remove(list, list->list->data);
}
g_slist_free(list->list);
GTK_OBJECT_CLASS(parent_class)->destroy (ob);
@ -68,12 +64,10 @@ gimp_list_class_init (GimpListClass* klass)
object_class->destroy = gimp_list_destroy;
gimp_list_signals[ADD]=
gimp_signal_new ("add", GTK_RUN_FIRST, type,
GTK_SIGNAL_OFFSET (GimpListClass, add),
gimp_signal_new ("add", GTK_RUN_FIRST, type, 0,
gimp_sigtype_pointer);
gimp_list_signals[REMOVE]=
gimp_signal_new ("remove", GTK_RUN_FIRST, type,
GTK_SIGNAL_OFFSET (GimpListClass, remove),
gimp_signal_new ("remove", GTK_RUN_FIRST, type, 0,
gimp_sigtype_pointer);
gtk_object_class_add_signals (object_class,
gimp_list_signals,
@ -137,6 +131,8 @@ gimp_list_add (GimpList* list, gpointer val)
else
gtk_object_ref(GTK_OBJECT(val));
GIMP_LIST_CLASS(GTK_OBJECT(list)->klass)->add(list, val);
gtk_signal_emit (GTK_OBJECT(list), gimp_list_signals[ADD], val);
return TRUE;
}
@ -147,8 +143,11 @@ gimp_list_remove (GimpList* list, gpointer val)
g_return_val_if_fail(list, FALSE);
if(!g_slist_find(list->list, val))
return FALSE;
{
printf("can't find val\n");
return FALSE;
}
GIMP_LIST_CLASS(GTK_OBJECT(list)->klass)->remove(list, val);
gtk_signal_emit (GTK_OBJECT(list), gimp_list_signals[REMOVE], val);

View File

@ -353,7 +353,8 @@ brush_select_select (BrushSelectP bsp,
int index)
{
int row, col;
if (index < 0)
return;
update_active_brush_field (bsp);
row = index / NUM_BRUSH_COLUMNS;
col = index - row * NUM_BRUSH_COLUMNS;
@ -950,6 +951,8 @@ preview_scroll_update (GtkAdjustment *adjustment,
if (active)
{
index = gimp_brush_list_get_brush_index(brush_list, active);
if (index < 0)
return;
row = index / NUM_BRUSH_COLUMNS;
col = index - row * NUM_BRUSH_COLUMNS;
brush_select_show_selected (bsp, row, col);

View File

@ -429,12 +429,13 @@ paint_core_init (paint_core, drawable, x, y)
GTK_SIGNAL_FUNC(paint_core_invalidate_cache),
NULL);
paint_core->spacing =
paint_core->spacing = (double) gimp_brush_get_spacing () / 100.0;
/* paint_core->spacing =
(double) MAXIMUM (brush->mask->width, brush->mask->height) *
((double) gimp_brush_get_spacing () / 100.0);
if (paint_core->spacing < 1.0)
paint_core->spacing = 1.0;
paint_core->brush_mask = brush->mask;
paint_core->spacing = 1.0; */
paint_core->brush = brush;
/* free the block structures */
if (undo_tiles)
@ -465,23 +466,32 @@ paint_core_interpolate (paint_core, drawable)
GimpDrawable *drawable;
{
int n;
double dx, dy, dpressure, dxtilt, dytilt;
vector2d delta;
double dpressure, dxtilt, dytilt;
double left;
double t;
double initial;
double dist;
double total;
dx = paint_core->curx - paint_core->lastx;
dy = paint_core->cury - paint_core->lasty;
double xd, yd;
double mag;
delta.x = paint_core->curx - paint_core->lastx;
delta.y = paint_core->cury - paint_core->lasty;
dpressure = paint_core->curpressure - paint_core->lastpressure;
dxtilt = paint_core->curxtilt - paint_core->lastxtilt;
dytilt = paint_core->curytilt - paint_core->lastytilt;
if (!dx && !dy && !dpressure && !dxtilt && !dytilt)
if (!delta.x && !delta.y && !dpressure && !dxtilt && !dytilt)
return;
mag = vector2d_magnitude (&(paint_core->brush->x_axis));
xd = vector2d_dot_product(&delta, &(paint_core->brush->x_axis)) / (mag*mag);
mag = vector2d_magnitude (&(paint_core->brush->y_axis));
yd = vector2d_dot_product(&delta, &(paint_core->brush->y_axis)) /
SQR(vector2d_magnitude(&(paint_core->brush->y_axis)));
dist = .5 * sqrt (xd*xd + yd*yd);
dist = sqrt (SQR (dx) + SQR (dy));
total = dist + paint_core->distance;
initial = paint_core->distance;
@ -495,8 +505,8 @@ paint_core_interpolate (paint_core, drawable)
{
t = (paint_core->distance - initial) / dist;
paint_core->curx = paint_core->lastx + dx * t;
paint_core->cury = paint_core->lasty + dy * t;
paint_core->curx = paint_core->lastx + delta.x * t;
paint_core->cury = paint_core->lasty + delta.y * t;
paint_core->curpressure = paint_core->lastpressure + dpressure * t;
paint_core->curxtilt = paint_core->lastxtilt + dxtilt * t;
paint_core->curytilt = paint_core->lastytilt + dytilt * t;
@ -505,8 +515,8 @@ paint_core_interpolate (paint_core, drawable)
}
paint_core->distance = total;
paint_core->curx = paint_core->lastx + dx;
paint_core->cury = paint_core->lasty + dy;
paint_core->curx = paint_core->lastx + delta.x;
paint_core->cury = paint_core->lasty + delta.y;
paint_core->curpressure = paint_core->lastpressure + dpressure;
paint_core->curxtilt = paint_core->lastxtilt + dxtilt;
paint_core->curytilt = paint_core->lastytilt + dytilt;
@ -598,14 +608,14 @@ paint_core_get_paint_area (paint_core, drawable)
drawable_bytes (drawable) : drawable_bytes (drawable) + 1;
/* adjust the x and y coordinates to the upper left corner of the brush */
x = (int) paint_core->curx - (paint_core->brush_mask->width >> 1);
y = (int) paint_core->cury - (paint_core->brush_mask->height >> 1);
x = (int) paint_core->curx - (paint_core->brush->mask->width >> 1);
y = (int) paint_core->cury - (paint_core->brush->mask->height >> 1);
x1 = BOUNDS (x - 1, 0, drawable_width (drawable));
y1 = BOUNDS (y - 1, 0, drawable_height (drawable));
x2 = BOUNDS (x + paint_core->brush_mask->width + 1,
x2 = BOUNDS (x + paint_core->brush->mask->width + 1,
0, drawable_width (drawable));
y2 = BOUNDS (y + paint_core->brush_mask->height + 1,
y2 = BOUNDS (y + paint_core->brush->mask->height + 1,
0, drawable_height (drawable));
/* configure the canvas buffer */
@ -959,13 +969,13 @@ paint_core_get_brush_mask (paint_core, brush_hardness)
switch (brush_hardness)
{
case SOFT:
bm = paint_core_subsample_mask (paint_core->brush_mask, paint_core->curx, paint_core->cury);
bm = paint_core_subsample_mask (paint_core->brush->mask, paint_core->curx, paint_core->cury);
break;
case HARD:
bm = paint_core_solidify_mask (paint_core->brush_mask);
bm = paint_core_solidify_mask (paint_core->brush->mask);
break;
case PRESSURE:
bm = paint_core_pressurize_mask (paint_core->brush_mask, paint_core->curx, paint_core->cury, paint_core->curpressure);
bm = paint_core_pressurize_mask (paint_core->brush->mask, paint_core->curx, paint_core->cury, paint_core->curpressure);
break;
default:
bm = NULL;

View File

@ -20,6 +20,7 @@
#include "draw_core.h"
#include "temp_buf.h"
#include "gimpbrush.h"
/* the different states that the painting function can be called with */
#define INIT_PAINT 0
@ -69,7 +70,7 @@ struct _paint_core
int x1, y1; /* image space coordinate */
int x2, y2; /* image space coords */
MaskBuf * brush_mask; /* mask for current brush */
GimpBrush * brush; /* current brush */
PaintFunc paint_func; /* painting function */
};

View File

@ -429,12 +429,13 @@ paint_core_init (paint_core, drawable, x, y)
GTK_SIGNAL_FUNC(paint_core_invalidate_cache),
NULL);
paint_core->spacing =
paint_core->spacing = (double) gimp_brush_get_spacing () / 100.0;
/* paint_core->spacing =
(double) MAXIMUM (brush->mask->width, brush->mask->height) *
((double) gimp_brush_get_spacing () / 100.0);
if (paint_core->spacing < 1.0)
paint_core->spacing = 1.0;
paint_core->brush_mask = brush->mask;
paint_core->spacing = 1.0; */
paint_core->brush = brush;
/* free the block structures */
if (undo_tiles)
@ -465,23 +466,32 @@ paint_core_interpolate (paint_core, drawable)
GimpDrawable *drawable;
{
int n;
double dx, dy, dpressure, dxtilt, dytilt;
vector2d delta;
double dpressure, dxtilt, dytilt;
double left;
double t;
double initial;
double dist;
double total;
dx = paint_core->curx - paint_core->lastx;
dy = paint_core->cury - paint_core->lasty;
double xd, yd;
double mag;
delta.x = paint_core->curx - paint_core->lastx;
delta.y = paint_core->cury - paint_core->lasty;
dpressure = paint_core->curpressure - paint_core->lastpressure;
dxtilt = paint_core->curxtilt - paint_core->lastxtilt;
dytilt = paint_core->curytilt - paint_core->lastytilt;
if (!dx && !dy && !dpressure && !dxtilt && !dytilt)
if (!delta.x && !delta.y && !dpressure && !dxtilt && !dytilt)
return;
mag = vector2d_magnitude (&(paint_core->brush->x_axis));
xd = vector2d_dot_product(&delta, &(paint_core->brush->x_axis)) / (mag*mag);
mag = vector2d_magnitude (&(paint_core->brush->y_axis));
yd = vector2d_dot_product(&delta, &(paint_core->brush->y_axis)) /
SQR(vector2d_magnitude(&(paint_core->brush->y_axis)));
dist = .5 * sqrt (xd*xd + yd*yd);
dist = sqrt (SQR (dx) + SQR (dy));
total = dist + paint_core->distance;
initial = paint_core->distance;
@ -495,8 +505,8 @@ paint_core_interpolate (paint_core, drawable)
{
t = (paint_core->distance - initial) / dist;
paint_core->curx = paint_core->lastx + dx * t;
paint_core->cury = paint_core->lasty + dy * t;
paint_core->curx = paint_core->lastx + delta.x * t;
paint_core->cury = paint_core->lasty + delta.y * t;
paint_core->curpressure = paint_core->lastpressure + dpressure * t;
paint_core->curxtilt = paint_core->lastxtilt + dxtilt * t;
paint_core->curytilt = paint_core->lastytilt + dytilt * t;
@ -505,8 +515,8 @@ paint_core_interpolate (paint_core, drawable)
}
paint_core->distance = total;
paint_core->curx = paint_core->lastx + dx;
paint_core->cury = paint_core->lasty + dy;
paint_core->curx = paint_core->lastx + delta.x;
paint_core->cury = paint_core->lasty + delta.y;
paint_core->curpressure = paint_core->lastpressure + dpressure;
paint_core->curxtilt = paint_core->lastxtilt + dxtilt;
paint_core->curytilt = paint_core->lastytilt + dytilt;
@ -598,14 +608,14 @@ paint_core_get_paint_area (paint_core, drawable)
drawable_bytes (drawable) : drawable_bytes (drawable) + 1;
/* adjust the x and y coordinates to the upper left corner of the brush */
x = (int) paint_core->curx - (paint_core->brush_mask->width >> 1);
y = (int) paint_core->cury - (paint_core->brush_mask->height >> 1);
x = (int) paint_core->curx - (paint_core->brush->mask->width >> 1);
y = (int) paint_core->cury - (paint_core->brush->mask->height >> 1);
x1 = BOUNDS (x - 1, 0, drawable_width (drawable));
y1 = BOUNDS (y - 1, 0, drawable_height (drawable));
x2 = BOUNDS (x + paint_core->brush_mask->width + 1,
x2 = BOUNDS (x + paint_core->brush->mask->width + 1,
0, drawable_width (drawable));
y2 = BOUNDS (y + paint_core->brush_mask->height + 1,
y2 = BOUNDS (y + paint_core->brush->mask->height + 1,
0, drawable_height (drawable));
/* configure the canvas buffer */
@ -959,13 +969,13 @@ paint_core_get_brush_mask (paint_core, brush_hardness)
switch (brush_hardness)
{
case SOFT:
bm = paint_core_subsample_mask (paint_core->brush_mask, paint_core->curx, paint_core->cury);
bm = paint_core_subsample_mask (paint_core->brush->mask, paint_core->curx, paint_core->cury);
break;
case HARD:
bm = paint_core_solidify_mask (paint_core->brush_mask);
bm = paint_core_solidify_mask (paint_core->brush->mask);
break;
case PRESSURE:
bm = paint_core_pressurize_mask (paint_core->brush_mask, paint_core->curx, paint_core->cury, paint_core->curpressure);
bm = paint_core_pressurize_mask (paint_core->brush->mask, paint_core->curx, paint_core->cury, paint_core->curpressure);
break;
default:
bm = NULL;

View File

@ -20,6 +20,7 @@
#include "draw_core.h"
#include "temp_buf.h"
#include "gimpbrush.h"
/* the different states that the painting function can be called with */
#define INIT_PAINT 0
@ -69,7 +70,7 @@ struct _paint_core
int x1, y1; /* image space coordinate */
int x2, y2; /* image space coords */
MaskBuf * brush_mask; /* mask for current brush */
GimpBrush * brush; /* current brush */
PaintFunc paint_func; /* painting function */
};

39
app/vector2d.c Normal file
View File

@ -0,0 +1,39 @@
/* vector2d
* Copyright (C) 1998 Jay Cox <jaycox@earthlink.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "vector2d.h"
#include <math.h>
double
vector2d_dot_product (vector2d *v1, vector2d *v2)
{
return ((v1->x * v2->x) + (v1->y * v2->y));
}
double
vector2d_magnitude (vector2d *v)
{
return (sqrt((v->x*v->x) + (v->y*v->y)));
}
void
vector2d_set (vector2d *v, double x, double y)
{
v->x = x; v->y = y;
}

31
app/vector2d.h Normal file
View File

@ -0,0 +1,31 @@
/* vector2d
* Copyright (C) 1998 Jay Cox <jaycox@earthlink.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __VECTOR2D_H__
#define __VECTOR2D_H__
typedef struct _vector2d
{
double x, y;
} vector2d;
void vector2d_set (vector2d *v, double x, double y);
double vector2d_dot_product (vector2d *v1, vector2d *v2);
double vector2d_magnitude (vector2d *v);
#endif /* __VECTOR2D_H__ */