Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi> * app/gimpbrushpipe.c: Implement the selection of brush based on cursor direction, pressure, tilt, or a random value. (Hmm, forgot velocity, later.) (In addition to just incrementally stepping.) Read the brush pipe parameters from the gih file's second line. There is no way to tune the parameters in the GIMP, they must currently be set when saving the gih file (in the gpb plug-in). * app/gimpbrushpipe.h * app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the "private" header. Add a stride array to GimpBrushPipe to make indexing easier. * plug-ins/common/gpb.c: Add selection mode fields to the dialog. Attach the pipe parameters entered as a parasite, too. * docs/parasites.txt * plug-ins/common/psp.c: Use "placement", not "spacing" (which means another thing).
This commit is contained in:
parent
58d782985a
commit
70fca093f3
11 changed files with 846 additions and 144 deletions
21
ChangeLog
21
ChangeLog
|
|
@ -1,3 +1,24 @@
|
|||
1999-08-28 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* app/gimpbrushpipe.c: Implement the selection of brush based on
|
||||
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
|
||||
velocity, later.) (In addition to just incrementally stepping.)
|
||||
Read the brush pipe parameters from the gih file's second line.
|
||||
There is no way to tune the parameters in the GIMP, they must
|
||||
currently be set when saving the gih file (in the gpb plug-in).
|
||||
|
||||
* app/gimpbrushpipe.h
|
||||
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
|
||||
"private" header. Add a stride array to GimpBrushPipe to make
|
||||
indexing easier.
|
||||
|
||||
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
|
||||
Attach the pipe parameters entered as a parasite, too.
|
||||
|
||||
* docs/parasites.txt
|
||||
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
|
||||
means another thing).
|
||||
|
||||
Fri Aug 27 18:08:55 PDT 1999 Manish Singh <yosh@gimp.org>
|
||||
|
||||
* app/color_display.h: just include parasiteF.h
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "appenv.h"
|
||||
#include "brush_header.h"
|
||||
|
|
@ -35,6 +36,26 @@
|
|||
#include "gimprc.h"
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
/* Code duplicated from plug-ins/common/gpb.c...
|
||||
* The struct, and code to parse/build it probably should be in libgimp.
|
||||
*/
|
||||
|
||||
/* Parameters related to one single gih file, collected in a struct
|
||||
* just for clarity.
|
||||
*/
|
||||
#define MAXDIM 4
|
||||
static struct {
|
||||
gint step;
|
||||
gint ncells;
|
||||
gint dim;
|
||||
gint cols;
|
||||
gint rows;
|
||||
gchar *placement;
|
||||
gint rank[MAXDIM];
|
||||
gchar *selection[MAXDIM];
|
||||
} gihparms;
|
||||
|
||||
|
||||
static GimpBrushClass* gimp_brush_class;
|
||||
static GtkObjectClass* gimp_object_class;
|
||||
|
||||
|
|
@ -107,23 +128,60 @@ gimp_brush_pixmap_get_type (void)
|
|||
static GimpBrush *
|
||||
gimp_brush_pixmap_select_brush (PaintCore *paint_core)
|
||||
{
|
||||
GimpBrushPixmap *pixmap;
|
||||
GimpBrushPipe *pipe;
|
||||
int i, brushix, value;
|
||||
double angle;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), NULL);
|
||||
|
||||
pixmap = GIMP_BRUSH_PIXMAP (paint_core->brush);
|
||||
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
|
||||
|
||||
if (pixmap->pipe->nbrushes == 1)
|
||||
return GIMP_BRUSH (pixmap->pipe->current);
|
||||
if (pipe->nbrushes == 1)
|
||||
return GIMP_BRUSH (pipe->current);
|
||||
|
||||
/* Just select the next one for now. This is the place where we
|
||||
* will select the correct brush based on various parameters
|
||||
* in paint_core.
|
||||
*/
|
||||
pixmap->pipe->index[0] = (pixmap->pipe->index[0] + 1) % pixmap->pipe->nbrushes;
|
||||
pixmap->pipe->current = pixmap->pipe->brushes[pixmap->pipe->index[0]];
|
||||
brushix = 0;
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
switch (pipe->select[i])
|
||||
{
|
||||
case PIPE_SELECT_CONSTANT:
|
||||
/* What constant? */
|
||||
value = 0;
|
||||
break;
|
||||
case PIPE_SELECT_INCREMENTAL:
|
||||
value = pipe->index[i] = (pipe->index[i] + 1) % pipe->rank[i];
|
||||
break;
|
||||
case PIPE_SELECT_ANGULAR:
|
||||
angle = atan2 (paint_core->cury - paint_core->lasty,
|
||||
paint_core->curx - paint_core->lastx);
|
||||
if (angle < 0)
|
||||
angle += 2.*G_PI;
|
||||
value = RINT (angle / (2.*G_PI) * pipe->rank[i]);
|
||||
break;
|
||||
case PIPE_SELECT_RANDOM:
|
||||
/* This probably isn't the right way */
|
||||
value = rand () % pipe->rank[i];
|
||||
break;
|
||||
case PIPE_SELECT_PRESSURE:
|
||||
value = RINT (paint_core->curpressure * (pipe->rank[i] - 1));
|
||||
break;
|
||||
case PIPE_SELECT_TILT_X:
|
||||
value = RINT (paint_core->curxtilt / 2.0 * pipe->rank[i]) + pipe->rank[i]/2;
|
||||
break;
|
||||
case PIPE_SELECT_TILT_Y:
|
||||
value = RINT (paint_core->curytilt / 2.0 * pipe->rank[i]) + pipe->rank[i]/2;
|
||||
break;
|
||||
}
|
||||
brushix += pipe->stride[i] * value;
|
||||
/* g_print ("value at %d: %d, brushix: %d\n", i, value, brushix); */
|
||||
}
|
||||
|
||||
return GIMP_BRUSH (pixmap->pipe->current);
|
||||
/* If out of bounds, just select the first brush... */
|
||||
brushix = BOUNDS (brushix, 0, pipe->nbrushes-1);
|
||||
|
||||
pipe->current = pipe->brushes[brushix];
|
||||
|
||||
return GIMP_BRUSH (pipe->current);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -138,6 +196,7 @@ gimp_brush_pipe_destroy(GtkObject *object)
|
|||
pipe = GIMP_BRUSH_PIPE (object);
|
||||
|
||||
g_free (pipe->rank);
|
||||
g_free (pipe->stride);
|
||||
|
||||
for (i = 1; i < pipe->nbrushes; i++)
|
||||
gimp_object_destroy (pipe->brushes[i]);
|
||||
|
|
@ -190,6 +249,91 @@ gimp_brush_pipe_get_type (void)
|
|||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
init_pipe_parameters ()
|
||||
{
|
||||
int i;
|
||||
|
||||
gihparms.step = 100;
|
||||
gihparms.ncells = 1;
|
||||
gihparms.dim = 1;
|
||||
gihparms.cols = 1;
|
||||
gihparms.rows = 1;
|
||||
gihparms.placement = "constant";
|
||||
for (i = 0; i < MAXDIM; i++)
|
||||
gihparms.selection[i] = "random";
|
||||
gihparms.rank[0] = 1;
|
||||
for (i = 1; i < MAXDIM; i++)
|
||||
gihparms.rank[i] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_brush_pipe_parameters (gchar *parameters)
|
||||
{
|
||||
guchar *p, *q, *r, *s; /* Don't you love single-char identifiers? */
|
||||
gint i;
|
||||
|
||||
q = parameters;
|
||||
while ((p = strtok (q, " \r\n")) != NULL)
|
||||
{
|
||||
q = NULL;
|
||||
r = strchr (p, ':');
|
||||
if (r)
|
||||
*r = 0;
|
||||
|
||||
if (strcmp (p, "ncells") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.ncells = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "step") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.step = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "dim") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.dim = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "cols") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.cols = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "rows") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.rows = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "placement") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.placement = g_strdup (r + 1);
|
||||
}
|
||||
else if (strncmp (p, "rank", strlen ("rank")) == 0)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("rank"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.rank[i] = atoi (r + 1);
|
||||
}
|
||||
}
|
||||
else if (strncmp (p, "sel", strlen ("sel")) == 0)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("sel"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.selection[i] = g_strdup (r + 1);
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
*r = ':';
|
||||
}
|
||||
}
|
||||
|
||||
GimpBrushPipe *
|
||||
gimp_brush_pipe_load (char *filename)
|
||||
{
|
||||
|
|
@ -198,8 +342,10 @@ gimp_brush_pipe_load (char *filename)
|
|||
FILE *fp;
|
||||
guchar buf[1024];
|
||||
guchar *name;
|
||||
int i;
|
||||
int num_of_brushes;
|
||||
guchar *params;
|
||||
int totalcells;
|
||||
gchar *params;
|
||||
|
||||
if ((fp = fopen (filename, "rb")) == NULL)
|
||||
return NULL;
|
||||
|
|
@ -233,16 +379,62 @@ gimp_brush_pipe_load (char *filename)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Here we should parse the params to get the dimension, ranks,
|
||||
* placement options, etc. But just use defaults for now.
|
||||
*/
|
||||
pipe->dimension = 1;
|
||||
pipe->rank = g_new (int, 1);
|
||||
pipe->rank[0] = num_of_brushes;
|
||||
pipe->select = g_new (PipeSelectModes, 1);
|
||||
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
|
||||
pipe->index = g_new (int, 1);
|
||||
pipe->index[0] = 0;
|
||||
while (*params && isspace(*params))
|
||||
params++;
|
||||
|
||||
if (*params)
|
||||
{
|
||||
init_pipe_parameters ();
|
||||
parse_brush_pipe_parameters (params);
|
||||
pipe->dimension = gihparms.dim;
|
||||
pipe->rank = g_new (int, pipe->dimension);
|
||||
pipe->select = g_new (PipeSelectModes, pipe->dimension);
|
||||
pipe->index = g_new (int, pipe->dimension);
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
pipe->rank[i] = gihparms.rank[i];
|
||||
if (strcmp (gihparms.selection[i], "incremental") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_INCREMENTAL;
|
||||
else if (strcmp (gihparms.selection[i], "angular") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_ANGULAR;
|
||||
else if (strcmp (gihparms.selection[i], "velocity") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_VELOCITY;
|
||||
else if (strcmp (gihparms.selection[i], "random") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_RANDOM;
|
||||
else if (strcmp (gihparms.selection[i], "pressure") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_PRESSURE;
|
||||
else if (strcmp (gihparms.selection[i], "xtilt") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_TILT_X;
|
||||
else if (strcmp (gihparms.selection[i], "ytilt") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_TILT_Y;
|
||||
else
|
||||
pipe->select[i] = PIPE_SELECT_CONSTANT;
|
||||
pipe->index[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pipe->dimension = 1;
|
||||
pipe->rank = g_new (int, 1);
|
||||
pipe->rank[0] = num_of_brushes;
|
||||
pipe->select = g_new (PipeSelectModes, 1);
|
||||
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
|
||||
pipe->index = g_new (int, 1);
|
||||
pipe->index[0] = 0;
|
||||
}
|
||||
|
||||
totalcells = 1; /* Not all necessarily present, maybe */
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
totalcells *= pipe->rank[i];
|
||||
pipe->stride = g_new (int, pipe->dimension);
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
pipe->stride[i] = totalcells / pipe->rank[i];
|
||||
else
|
||||
pipe->stride[i] = pipe->stride[i-1] / pipe->rank[i];
|
||||
}
|
||||
g_assert (pipe->stride[pipe->dimension-1] == 1);
|
||||
|
||||
pattern = (GPatternP) g_malloc (sizeof (GPattern));
|
||||
pattern->filename = NULL;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "appenv.h"
|
||||
#include "brush_header.h"
|
||||
|
|
@ -35,6 +36,26 @@
|
|||
#include "gimprc.h"
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
/* Code duplicated from plug-ins/common/gpb.c...
|
||||
* The struct, and code to parse/build it probably should be in libgimp.
|
||||
*/
|
||||
|
||||
/* Parameters related to one single gih file, collected in a struct
|
||||
* just for clarity.
|
||||
*/
|
||||
#define MAXDIM 4
|
||||
static struct {
|
||||
gint step;
|
||||
gint ncells;
|
||||
gint dim;
|
||||
gint cols;
|
||||
gint rows;
|
||||
gchar *placement;
|
||||
gint rank[MAXDIM];
|
||||
gchar *selection[MAXDIM];
|
||||
} gihparms;
|
||||
|
||||
|
||||
static GimpBrushClass* gimp_brush_class;
|
||||
static GtkObjectClass* gimp_object_class;
|
||||
|
||||
|
|
@ -107,23 +128,60 @@ gimp_brush_pixmap_get_type (void)
|
|||
static GimpBrush *
|
||||
gimp_brush_pixmap_select_brush (PaintCore *paint_core)
|
||||
{
|
||||
GimpBrushPixmap *pixmap;
|
||||
GimpBrushPipe *pipe;
|
||||
int i, brushix, value;
|
||||
double angle;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), NULL);
|
||||
|
||||
pixmap = GIMP_BRUSH_PIXMAP (paint_core->brush);
|
||||
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
|
||||
|
||||
if (pixmap->pipe->nbrushes == 1)
|
||||
return GIMP_BRUSH (pixmap->pipe->current);
|
||||
if (pipe->nbrushes == 1)
|
||||
return GIMP_BRUSH (pipe->current);
|
||||
|
||||
/* Just select the next one for now. This is the place where we
|
||||
* will select the correct brush based on various parameters
|
||||
* in paint_core.
|
||||
*/
|
||||
pixmap->pipe->index[0] = (pixmap->pipe->index[0] + 1) % pixmap->pipe->nbrushes;
|
||||
pixmap->pipe->current = pixmap->pipe->brushes[pixmap->pipe->index[0]];
|
||||
brushix = 0;
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
switch (pipe->select[i])
|
||||
{
|
||||
case PIPE_SELECT_CONSTANT:
|
||||
/* What constant? */
|
||||
value = 0;
|
||||
break;
|
||||
case PIPE_SELECT_INCREMENTAL:
|
||||
value = pipe->index[i] = (pipe->index[i] + 1) % pipe->rank[i];
|
||||
break;
|
||||
case PIPE_SELECT_ANGULAR:
|
||||
angle = atan2 (paint_core->cury - paint_core->lasty,
|
||||
paint_core->curx - paint_core->lastx);
|
||||
if (angle < 0)
|
||||
angle += 2.*G_PI;
|
||||
value = RINT (angle / (2.*G_PI) * pipe->rank[i]);
|
||||
break;
|
||||
case PIPE_SELECT_RANDOM:
|
||||
/* This probably isn't the right way */
|
||||
value = rand () % pipe->rank[i];
|
||||
break;
|
||||
case PIPE_SELECT_PRESSURE:
|
||||
value = RINT (paint_core->curpressure * (pipe->rank[i] - 1));
|
||||
break;
|
||||
case PIPE_SELECT_TILT_X:
|
||||
value = RINT (paint_core->curxtilt / 2.0 * pipe->rank[i]) + pipe->rank[i]/2;
|
||||
break;
|
||||
case PIPE_SELECT_TILT_Y:
|
||||
value = RINT (paint_core->curytilt / 2.0 * pipe->rank[i]) + pipe->rank[i]/2;
|
||||
break;
|
||||
}
|
||||
brushix += pipe->stride[i] * value;
|
||||
/* g_print ("value at %d: %d, brushix: %d\n", i, value, brushix); */
|
||||
}
|
||||
|
||||
return GIMP_BRUSH (pixmap->pipe->current);
|
||||
/* If out of bounds, just select the first brush... */
|
||||
brushix = BOUNDS (brushix, 0, pipe->nbrushes-1);
|
||||
|
||||
pipe->current = pipe->brushes[brushix];
|
||||
|
||||
return GIMP_BRUSH (pipe->current);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -138,6 +196,7 @@ gimp_brush_pipe_destroy(GtkObject *object)
|
|||
pipe = GIMP_BRUSH_PIPE (object);
|
||||
|
||||
g_free (pipe->rank);
|
||||
g_free (pipe->stride);
|
||||
|
||||
for (i = 1; i < pipe->nbrushes; i++)
|
||||
gimp_object_destroy (pipe->brushes[i]);
|
||||
|
|
@ -190,6 +249,91 @@ gimp_brush_pipe_get_type (void)
|
|||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
init_pipe_parameters ()
|
||||
{
|
||||
int i;
|
||||
|
||||
gihparms.step = 100;
|
||||
gihparms.ncells = 1;
|
||||
gihparms.dim = 1;
|
||||
gihparms.cols = 1;
|
||||
gihparms.rows = 1;
|
||||
gihparms.placement = "constant";
|
||||
for (i = 0; i < MAXDIM; i++)
|
||||
gihparms.selection[i] = "random";
|
||||
gihparms.rank[0] = 1;
|
||||
for (i = 1; i < MAXDIM; i++)
|
||||
gihparms.rank[i] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_brush_pipe_parameters (gchar *parameters)
|
||||
{
|
||||
guchar *p, *q, *r, *s; /* Don't you love single-char identifiers? */
|
||||
gint i;
|
||||
|
||||
q = parameters;
|
||||
while ((p = strtok (q, " \r\n")) != NULL)
|
||||
{
|
||||
q = NULL;
|
||||
r = strchr (p, ':');
|
||||
if (r)
|
||||
*r = 0;
|
||||
|
||||
if (strcmp (p, "ncells") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.ncells = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "step") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.step = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "dim") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.dim = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "cols") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.cols = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "rows") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.rows = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "placement") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.placement = g_strdup (r + 1);
|
||||
}
|
||||
else if (strncmp (p, "rank", strlen ("rank")) == 0)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("rank"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.rank[i] = atoi (r + 1);
|
||||
}
|
||||
}
|
||||
else if (strncmp (p, "sel", strlen ("sel")) == 0)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("sel"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.selection[i] = g_strdup (r + 1);
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
*r = ':';
|
||||
}
|
||||
}
|
||||
|
||||
GimpBrushPipe *
|
||||
gimp_brush_pipe_load (char *filename)
|
||||
{
|
||||
|
|
@ -198,8 +342,10 @@ gimp_brush_pipe_load (char *filename)
|
|||
FILE *fp;
|
||||
guchar buf[1024];
|
||||
guchar *name;
|
||||
int i;
|
||||
int num_of_brushes;
|
||||
guchar *params;
|
||||
int totalcells;
|
||||
gchar *params;
|
||||
|
||||
if ((fp = fopen (filename, "rb")) == NULL)
|
||||
return NULL;
|
||||
|
|
@ -233,16 +379,62 @@ gimp_brush_pipe_load (char *filename)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Here we should parse the params to get the dimension, ranks,
|
||||
* placement options, etc. But just use defaults for now.
|
||||
*/
|
||||
pipe->dimension = 1;
|
||||
pipe->rank = g_new (int, 1);
|
||||
pipe->rank[0] = num_of_brushes;
|
||||
pipe->select = g_new (PipeSelectModes, 1);
|
||||
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
|
||||
pipe->index = g_new (int, 1);
|
||||
pipe->index[0] = 0;
|
||||
while (*params && isspace(*params))
|
||||
params++;
|
||||
|
||||
if (*params)
|
||||
{
|
||||
init_pipe_parameters ();
|
||||
parse_brush_pipe_parameters (params);
|
||||
pipe->dimension = gihparms.dim;
|
||||
pipe->rank = g_new (int, pipe->dimension);
|
||||
pipe->select = g_new (PipeSelectModes, pipe->dimension);
|
||||
pipe->index = g_new (int, pipe->dimension);
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
pipe->rank[i] = gihparms.rank[i];
|
||||
if (strcmp (gihparms.selection[i], "incremental") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_INCREMENTAL;
|
||||
else if (strcmp (gihparms.selection[i], "angular") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_ANGULAR;
|
||||
else if (strcmp (gihparms.selection[i], "velocity") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_VELOCITY;
|
||||
else if (strcmp (gihparms.selection[i], "random") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_RANDOM;
|
||||
else if (strcmp (gihparms.selection[i], "pressure") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_PRESSURE;
|
||||
else if (strcmp (gihparms.selection[i], "xtilt") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_TILT_X;
|
||||
else if (strcmp (gihparms.selection[i], "ytilt") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_TILT_Y;
|
||||
else
|
||||
pipe->select[i] = PIPE_SELECT_CONSTANT;
|
||||
pipe->index[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pipe->dimension = 1;
|
||||
pipe->rank = g_new (int, 1);
|
||||
pipe->rank[0] = num_of_brushes;
|
||||
pipe->select = g_new (PipeSelectModes, 1);
|
||||
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
|
||||
pipe->index = g_new (int, 1);
|
||||
pipe->index[0] = 0;
|
||||
}
|
||||
|
||||
totalcells = 1; /* Not all necessarily present, maybe */
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
totalcells *= pipe->rank[i];
|
||||
pipe->stride = g_new (int, pipe->dimension);
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
pipe->stride[i] = totalcells / pipe->rank[i];
|
||||
else
|
||||
pipe->stride[i] = pipe->stride[i-1] / pipe->rank[i];
|
||||
}
|
||||
g_assert (pipe->stride[pipe->dimension-1] == 1);
|
||||
|
||||
pattern = (GPatternP) g_malloc (sizeof (GPattern));
|
||||
pattern->filename = NULL;
|
||||
|
|
|
|||
|
|
@ -25,17 +25,6 @@
|
|||
#include "gimpbrush.h"
|
||||
#include "temp_buf.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIPE_SELECT_INCREMENTAL,
|
||||
PIPE_SELECT_DIRECTION,
|
||||
PIPE_SELECT_VELOCITY,
|
||||
PIPE_SELECT_RANDOM,
|
||||
PIPE_SELECT_PRESSURE,
|
||||
PIPE_SELECT_TILT_X,
|
||||
PIPE_SELECT_TILT_Y
|
||||
} PipeSelectModes;
|
||||
|
||||
typedef struct _GimpBrushPixmap GimpBrushPixmap;
|
||||
typedef struct _GimpBrushPipe GimpBrushPipe;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "appenv.h"
|
||||
#include "brush_header.h"
|
||||
|
|
@ -35,6 +36,26 @@
|
|||
#include "gimprc.h"
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
/* Code duplicated from plug-ins/common/gpb.c...
|
||||
* The struct, and code to parse/build it probably should be in libgimp.
|
||||
*/
|
||||
|
||||
/* Parameters related to one single gih file, collected in a struct
|
||||
* just for clarity.
|
||||
*/
|
||||
#define MAXDIM 4
|
||||
static struct {
|
||||
gint step;
|
||||
gint ncells;
|
||||
gint dim;
|
||||
gint cols;
|
||||
gint rows;
|
||||
gchar *placement;
|
||||
gint rank[MAXDIM];
|
||||
gchar *selection[MAXDIM];
|
||||
} gihparms;
|
||||
|
||||
|
||||
static GimpBrushClass* gimp_brush_class;
|
||||
static GtkObjectClass* gimp_object_class;
|
||||
|
||||
|
|
@ -107,23 +128,60 @@ gimp_brush_pixmap_get_type (void)
|
|||
static GimpBrush *
|
||||
gimp_brush_pixmap_select_brush (PaintCore *paint_core)
|
||||
{
|
||||
GimpBrushPixmap *pixmap;
|
||||
GimpBrushPipe *pipe;
|
||||
int i, brushix, value;
|
||||
double angle;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_BRUSH_PIXMAP (paint_core->brush), NULL);
|
||||
|
||||
pixmap = GIMP_BRUSH_PIXMAP (paint_core->brush);
|
||||
pipe = GIMP_BRUSH_PIXMAP (paint_core->brush)->pipe;
|
||||
|
||||
if (pixmap->pipe->nbrushes == 1)
|
||||
return GIMP_BRUSH (pixmap->pipe->current);
|
||||
if (pipe->nbrushes == 1)
|
||||
return GIMP_BRUSH (pipe->current);
|
||||
|
||||
/* Just select the next one for now. This is the place where we
|
||||
* will select the correct brush based on various parameters
|
||||
* in paint_core.
|
||||
*/
|
||||
pixmap->pipe->index[0] = (pixmap->pipe->index[0] + 1) % pixmap->pipe->nbrushes;
|
||||
pixmap->pipe->current = pixmap->pipe->brushes[pixmap->pipe->index[0]];
|
||||
brushix = 0;
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
switch (pipe->select[i])
|
||||
{
|
||||
case PIPE_SELECT_CONSTANT:
|
||||
/* What constant? */
|
||||
value = 0;
|
||||
break;
|
||||
case PIPE_SELECT_INCREMENTAL:
|
||||
value = pipe->index[i] = (pipe->index[i] + 1) % pipe->rank[i];
|
||||
break;
|
||||
case PIPE_SELECT_ANGULAR:
|
||||
angle = atan2 (paint_core->cury - paint_core->lasty,
|
||||
paint_core->curx - paint_core->lastx);
|
||||
if (angle < 0)
|
||||
angle += 2.*G_PI;
|
||||
value = RINT (angle / (2.*G_PI) * pipe->rank[i]);
|
||||
break;
|
||||
case PIPE_SELECT_RANDOM:
|
||||
/* This probably isn't the right way */
|
||||
value = rand () % pipe->rank[i];
|
||||
break;
|
||||
case PIPE_SELECT_PRESSURE:
|
||||
value = RINT (paint_core->curpressure * (pipe->rank[i] - 1));
|
||||
break;
|
||||
case PIPE_SELECT_TILT_X:
|
||||
value = RINT (paint_core->curxtilt / 2.0 * pipe->rank[i]) + pipe->rank[i]/2;
|
||||
break;
|
||||
case PIPE_SELECT_TILT_Y:
|
||||
value = RINT (paint_core->curytilt / 2.0 * pipe->rank[i]) + pipe->rank[i]/2;
|
||||
break;
|
||||
}
|
||||
brushix += pipe->stride[i] * value;
|
||||
/* g_print ("value at %d: %d, brushix: %d\n", i, value, brushix); */
|
||||
}
|
||||
|
||||
return GIMP_BRUSH (pixmap->pipe->current);
|
||||
/* If out of bounds, just select the first brush... */
|
||||
brushix = BOUNDS (brushix, 0, pipe->nbrushes-1);
|
||||
|
||||
pipe->current = pipe->brushes[brushix];
|
||||
|
||||
return GIMP_BRUSH (pipe->current);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -138,6 +196,7 @@ gimp_brush_pipe_destroy(GtkObject *object)
|
|||
pipe = GIMP_BRUSH_PIPE (object);
|
||||
|
||||
g_free (pipe->rank);
|
||||
g_free (pipe->stride);
|
||||
|
||||
for (i = 1; i < pipe->nbrushes; i++)
|
||||
gimp_object_destroy (pipe->brushes[i]);
|
||||
|
|
@ -190,6 +249,91 @@ gimp_brush_pipe_get_type (void)
|
|||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
init_pipe_parameters ()
|
||||
{
|
||||
int i;
|
||||
|
||||
gihparms.step = 100;
|
||||
gihparms.ncells = 1;
|
||||
gihparms.dim = 1;
|
||||
gihparms.cols = 1;
|
||||
gihparms.rows = 1;
|
||||
gihparms.placement = "constant";
|
||||
for (i = 0; i < MAXDIM; i++)
|
||||
gihparms.selection[i] = "random";
|
||||
gihparms.rank[0] = 1;
|
||||
for (i = 1; i < MAXDIM; i++)
|
||||
gihparms.rank[i] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_brush_pipe_parameters (gchar *parameters)
|
||||
{
|
||||
guchar *p, *q, *r, *s; /* Don't you love single-char identifiers? */
|
||||
gint i;
|
||||
|
||||
q = parameters;
|
||||
while ((p = strtok (q, " \r\n")) != NULL)
|
||||
{
|
||||
q = NULL;
|
||||
r = strchr (p, ':');
|
||||
if (r)
|
||||
*r = 0;
|
||||
|
||||
if (strcmp (p, "ncells") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.ncells = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "step") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.step = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "dim") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.dim = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "cols") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.cols = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "rows") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.rows = atoi (r + 1);
|
||||
}
|
||||
else if (strcmp (p, "placement") == 0)
|
||||
{
|
||||
if (r)
|
||||
gihparms.placement = g_strdup (r + 1);
|
||||
}
|
||||
else if (strncmp (p, "rank", strlen ("rank")) == 0)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("rank"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.rank[i] = atoi (r + 1);
|
||||
}
|
||||
}
|
||||
else if (strncmp (p, "sel", strlen ("sel")) == 0)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("sel"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.selection[i] = g_strdup (r + 1);
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
*r = ':';
|
||||
}
|
||||
}
|
||||
|
||||
GimpBrushPipe *
|
||||
gimp_brush_pipe_load (char *filename)
|
||||
{
|
||||
|
|
@ -198,8 +342,10 @@ gimp_brush_pipe_load (char *filename)
|
|||
FILE *fp;
|
||||
guchar buf[1024];
|
||||
guchar *name;
|
||||
int i;
|
||||
int num_of_brushes;
|
||||
guchar *params;
|
||||
int totalcells;
|
||||
gchar *params;
|
||||
|
||||
if ((fp = fopen (filename, "rb")) == NULL)
|
||||
return NULL;
|
||||
|
|
@ -233,16 +379,62 @@ gimp_brush_pipe_load (char *filename)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Here we should parse the params to get the dimension, ranks,
|
||||
* placement options, etc. But just use defaults for now.
|
||||
*/
|
||||
pipe->dimension = 1;
|
||||
pipe->rank = g_new (int, 1);
|
||||
pipe->rank[0] = num_of_brushes;
|
||||
pipe->select = g_new (PipeSelectModes, 1);
|
||||
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
|
||||
pipe->index = g_new (int, 1);
|
||||
pipe->index[0] = 0;
|
||||
while (*params && isspace(*params))
|
||||
params++;
|
||||
|
||||
if (*params)
|
||||
{
|
||||
init_pipe_parameters ();
|
||||
parse_brush_pipe_parameters (params);
|
||||
pipe->dimension = gihparms.dim;
|
||||
pipe->rank = g_new (int, pipe->dimension);
|
||||
pipe->select = g_new (PipeSelectModes, pipe->dimension);
|
||||
pipe->index = g_new (int, pipe->dimension);
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
pipe->rank[i] = gihparms.rank[i];
|
||||
if (strcmp (gihparms.selection[i], "incremental") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_INCREMENTAL;
|
||||
else if (strcmp (gihparms.selection[i], "angular") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_ANGULAR;
|
||||
else if (strcmp (gihparms.selection[i], "velocity") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_VELOCITY;
|
||||
else if (strcmp (gihparms.selection[i], "random") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_RANDOM;
|
||||
else if (strcmp (gihparms.selection[i], "pressure") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_PRESSURE;
|
||||
else if (strcmp (gihparms.selection[i], "xtilt") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_TILT_X;
|
||||
else if (strcmp (gihparms.selection[i], "ytilt") == 0)
|
||||
pipe->select[i] = PIPE_SELECT_TILT_Y;
|
||||
else
|
||||
pipe->select[i] = PIPE_SELECT_CONSTANT;
|
||||
pipe->index[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pipe->dimension = 1;
|
||||
pipe->rank = g_new (int, 1);
|
||||
pipe->rank[0] = num_of_brushes;
|
||||
pipe->select = g_new (PipeSelectModes, 1);
|
||||
pipe->select[0] = PIPE_SELECT_INCREMENTAL;
|
||||
pipe->index = g_new (int, 1);
|
||||
pipe->index[0] = 0;
|
||||
}
|
||||
|
||||
totalcells = 1; /* Not all necessarily present, maybe */
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
totalcells *= pipe->rank[i];
|
||||
pipe->stride = g_new (int, pipe->dimension);
|
||||
for (i = 0; i < pipe->dimension; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
pipe->stride[i] = totalcells / pipe->rank[i];
|
||||
else
|
||||
pipe->stride[i] = pipe->stride[i-1] / pipe->rank[i];
|
||||
}
|
||||
g_assert (pipe->stride[pipe->dimension-1] == 1);
|
||||
|
||||
pattern = (GPatternP) g_malloc (sizeof (GPattern));
|
||||
pattern->filename = NULL;
|
||||
|
|
|
|||
|
|
@ -25,17 +25,6 @@
|
|||
#include "gimpbrush.h"
|
||||
#include "temp_buf.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIPE_SELECT_INCREMENTAL,
|
||||
PIPE_SELECT_DIRECTION,
|
||||
PIPE_SELECT_VELOCITY,
|
||||
PIPE_SELECT_RANDOM,
|
||||
PIPE_SELECT_PRESSURE,
|
||||
PIPE_SELECT_TILT_X,
|
||||
PIPE_SELECT_TILT_Y
|
||||
} PipeSelectModes;
|
||||
|
||||
typedef struct _GimpBrushPixmap GimpBrushPixmap;
|
||||
typedef struct _GimpBrushPipe GimpBrushPipe;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,18 @@
|
|||
#ifndef __GIMPBRUSHPIPEP_H__
|
||||
#define __GIMPBRUSHPIPEP_H__
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIPE_SELECT_CONSTANT,
|
||||
PIPE_SELECT_INCREMENTAL,
|
||||
PIPE_SELECT_ANGULAR,
|
||||
PIPE_SELECT_VELOCITY,
|
||||
PIPE_SELECT_RANDOM,
|
||||
PIPE_SELECT_PRESSURE,
|
||||
PIPE_SELECT_TILT_X,
|
||||
PIPE_SELECT_TILT_Y
|
||||
} PipeSelectModes;
|
||||
|
||||
/* A GimpBrushPixmap always exists as part in one and only one GimpBrushPipe
|
||||
* It contains a back-pointer to the GimpBrushPipe so that we can select
|
||||
* the next brush in the pipe with just a reference to the GimpBrushPipe.
|
||||
|
|
@ -38,8 +50,10 @@ struct _GimpBrushPipe
|
|||
GimpBrushPixmap *current; /* Currently selected brush */
|
||||
int dimension;
|
||||
int *rank; /* Size in each dimension */
|
||||
int *stride; /* Aux for indexing */
|
||||
int nbrushes; /* Might be less than the product of the
|
||||
* ranks in some special case */
|
||||
* ranks in some odd special case
|
||||
*/
|
||||
GimpBrushPixmap **brushes;
|
||||
PipeSelectModes *select; /* One mode per dimension */
|
||||
int *index; /* Current index for incremental dimensions */
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ gimp.exe : ../config.h $(gimp_OBJECTS) libgimpim.a gimp.def gimpres.o
|
|||
$(DLLTOOL) --base-file gimp.base --input-def gimp.def --output-exp gimp.exp
|
||||
$(CC) $(CFLAGS) -Wl,--base-file,gimp.base,gimp.exp -mwindows -o gimp.exe $(gimp_OBJECTS) -L . -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk/win32 -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32
|
||||
$(DLLTOOL) --base-file gimp.base --input-def gimp.def --output-exp gimp.exp
|
||||
$(CC) -v $(CFLAGS) -Wl,gimp.exp -mwindows -o gimp.exe $(gimp_OBJECTS) -L. -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk/win32 -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32
|
||||
$(CC) $(CFLAGS) -Wl,gimp.exp -mwindows -o gimp.exe $(gimp_OBJECTS) -L. -lgimpim -L ../libgimp -lgimpi -L $(GTK)/gtk -lgtk-$(GTK_VER) -L $(GTK)/gdk/win32 -lgdk-$(GTK_VER) -L $(INTL) -lgnu-intl -L $(GLIB) -lglib-$(GLIB_VER) -lgmodule-$(GLIB_VER) gimpres.o -lgdi32 -luser32
|
||||
$(DLLTOOL) --dllname gimp.exe gimp.def --output-lib libgimp.a $(gimp_OBJECTS)
|
||||
|
||||
.SUFFIXES: .c .o .i
|
||||
|
|
|
|||
|
|
@ -65,15 +65,15 @@ gimp-brush-pipe-parameters" (IMAGE, PERSISTENT)
|
|||
and three-dimensional pipes, it probably is.
|
||||
rank0, rank1, ...: (one for each dimension): the index range
|
||||
for that dimension
|
||||
spacing: "default", "constant" or "random". "constant" means
|
||||
use the spacing in the first brush in the pipe.
|
||||
"random" means perturb that with some suitable
|
||||
random number function. (Hmm, would it be overdoing it
|
||||
if the pipe also could specify what random function
|
||||
and its parameters...?)
|
||||
placement: "default", "constant" or "random". "constant" means
|
||||
use the spacing in the first brush in the pipe.
|
||||
"random" means perturb that with some suitable
|
||||
random number function. (Hmm, would it be overdoing it
|
||||
if the pipe also could specify what random function
|
||||
and its parameters...?)
|
||||
sel0, sel1, ...: "default", "random", "incremental", "angular",
|
||||
"pressure", "velocity", and whatever else suitable we might
|
||||
think of ;-) How one index from each dimension is
|
||||
think of ;-) Determines how one index from each dimension is
|
||||
selected (until we have pinpointed the brush to use).
|
||||
|
||||
"tiff-save-options" (IMAGE)
|
||||
|
|
|
|||
|
|
@ -59,14 +59,17 @@ static gint run_flag = 0;
|
|||
static gint num_layers_with_alpha;
|
||||
|
||||
/* Parameters related to one single gih file, collected in a struct
|
||||
* just for clarity. */
|
||||
* just for clarity.
|
||||
*/
|
||||
static struct {
|
||||
gint step;
|
||||
gint ncells;
|
||||
gint dim;
|
||||
gint cols;
|
||||
gint rows;
|
||||
gchar *placement;
|
||||
gint rank[MAXDIM];
|
||||
gchar *selection[MAXDIM];
|
||||
} gihparms;
|
||||
|
||||
/* Declare some local functions.
|
||||
|
|
@ -171,6 +174,13 @@ entry_callback (GtkWidget *widget,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cb_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
*((char **) data) = gtk_entry_get_text (GTK_ENTRY (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
close_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
|
|
@ -315,12 +325,14 @@ static gint
|
|||
gih_save_dialog ()
|
||||
{
|
||||
GtkWidget *dlg;
|
||||
GtkWidget *table;
|
||||
GtkWidget *table, *dimtable;
|
||||
GtkWidget *label;
|
||||
GtkObject *adjustment;
|
||||
GtkWidget *spinbutton;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *box;
|
||||
GtkWidget *cb;
|
||||
GList *cbitems = NULL;
|
||||
gint i;
|
||||
gchar **argv;
|
||||
gint argc;
|
||||
|
|
@ -353,6 +365,36 @@ gih_save_dialog ()
|
|||
|
||||
common_save_dialog (dlg, table);
|
||||
|
||||
/*
|
||||
* Number of cells: ___
|
||||
*/
|
||||
|
||||
gtk_table_resize (GTK_TABLE (table),
|
||||
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
||||
|
||||
label = gtk_label_new ("Number of cells:");
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
||||
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
adjustment = gtk_adjustment_new (gihparms.ncells, 1, 1000, 1, 10, 10);
|
||||
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
||||
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
||||
GTK_SHADOW_NONE);
|
||||
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
||||
gtk_widget_set_usize (spinbutton, 75, 0);
|
||||
box = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, TRUE, 0);
|
||||
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
||||
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
||||
(GtkSignalFunc) adjustment_callback, &gihparms.ncells);
|
||||
gtk_widget_show (spinbutton);
|
||||
gtk_widget_show (box);
|
||||
|
||||
/*
|
||||
* Display as: __ rows x __ cols
|
||||
*/
|
||||
|
|
@ -403,36 +445,6 @@ gih_save_dialog ()
|
|||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (box);
|
||||
|
||||
/*
|
||||
* Number of cells: ___
|
||||
*/
|
||||
|
||||
gtk_table_resize (GTK_TABLE (table),
|
||||
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
||||
|
||||
label = gtk_label_new ("Number of cells:");
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
||||
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
adjustment = gtk_adjustment_new (gihparms.ncells, 1, 1000, 1, 10, 10);
|
||||
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
||||
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
||||
GTK_SHADOW_NONE);
|
||||
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
||||
gtk_widget_set_usize (spinbutton, 75, 0);
|
||||
box = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, TRUE, 0);
|
||||
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
||||
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
||||
(GtkSignalFunc) adjustment_callback, &gihparms.ncells);
|
||||
gtk_widget_show (spinbutton);
|
||||
gtk_widget_show (box);
|
||||
|
||||
/*
|
||||
* Dimension: ___
|
||||
*/
|
||||
|
|
@ -477,7 +489,7 @@ gih_save_dialog ()
|
|||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
box = gtk_hbox_new (FALSE, 0);
|
||||
dimtable = gtk_table_new (MAXDIM, 1, FALSE);
|
||||
for (i = 0; i < MAXDIM; i++)
|
||||
{
|
||||
adjustment = gtk_adjustment_new (gihparms.rank[i], 0, 100, 1, 1, 1);
|
||||
|
|
@ -486,15 +498,64 @@ gih_save_dialog ()
|
|||
GTK_SHADOW_NONE);
|
||||
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
||||
gtk_widget_set_usize (spinbutton, 75, 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, TRUE, 2);
|
||||
box = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, TRUE, 0);
|
||||
gtk_table_attach (GTK_TABLE (dimtable), box, i, i + 1, 0, 1,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 3, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
||||
(GtkSignalFunc) adjustment_callback, &gihparms.rank[i]);
|
||||
gtk_widget_show (spinbutton);
|
||||
gtk_widget_show (box);
|
||||
}
|
||||
gtk_table_attach (GTK_TABLE (table), dimtable, 1, 2,
|
||||
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
||||
GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_widget_show (dimtable);
|
||||
|
||||
/*
|
||||
* Selection: ______ ______ ______ ______ ______
|
||||
*/
|
||||
|
||||
gtk_table_resize (GTK_TABLE (table),
|
||||
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
||||
|
||||
label = gtk_label_new ("Selection:");
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
||||
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
||||
GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
cbitems = g_list_append (cbitems, "incremental");
|
||||
cbitems = g_list_append (cbitems, "angular");
|
||||
cbitems = g_list_append (cbitems, "random");
|
||||
cbitems = g_list_append (cbitems, "velocity");
|
||||
cbitems = g_list_append (cbitems, "pressure");
|
||||
cbitems = g_list_append (cbitems, "xtilt");
|
||||
cbitems = g_list_append (cbitems, "ytilt");
|
||||
|
||||
box = gtk_hbox_new (FALSE, 0);
|
||||
for (i = 0; i < MAXDIM; i++)
|
||||
{
|
||||
cb = gtk_combo_new ();
|
||||
gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
|
||||
if (gihparms.selection[i])
|
||||
gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (cb)->entry), gihparms.selection[i]);
|
||||
gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (cb)->entry), FALSE);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (box), cb, FALSE, TRUE, 2);
|
||||
gtk_signal_connect (GTK_OBJECT (GTK_COMBO (cb)->entry), "changed",
|
||||
(GtkSignalFunc) cb_callback, &gihparms.selection[i]);
|
||||
gtk_widget_show (cb);
|
||||
}
|
||||
|
||||
g_list_free (cbitems);
|
||||
|
||||
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
||||
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
||||
GTK_SHRINK, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_widget_show (box);
|
||||
|
||||
gtk_widget_show (dlg);
|
||||
|
||||
gtk_main ();
|
||||
|
|
@ -700,6 +761,24 @@ gpb_save_image (char *filename,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_pipe_parameters ()
|
||||
{
|
||||
int i;
|
||||
|
||||
gihparms.step = 100;
|
||||
gihparms.ncells = 1;
|
||||
gihparms.dim = 1;
|
||||
gihparms.cols = 1;
|
||||
gihparms.rows = 1;
|
||||
gihparms.placement = "constant";
|
||||
for (i = 0; i < MAXDIM; i++)
|
||||
gihparms.selection[i] = "random";
|
||||
gihparms.rank[0] = 1;
|
||||
for (i = 1; i < MAXDIM; i++)
|
||||
gihparms.rank[i] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_brush_pipe_parameters (gchar *parameters)
|
||||
{
|
||||
|
|
@ -741,11 +820,28 @@ parse_brush_pipe_parameters (gchar *parameters)
|
|||
if (r)
|
||||
gihparms.rows = atoi (r + 1);
|
||||
}
|
||||
else if (strncmp (p, "rank", 4) == 0 && r)
|
||||
else if (strcmp (p, "placement") == 0)
|
||||
{
|
||||
i = atoi (p + 4);
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.rank[i] = atoi (r + 1);
|
||||
if (r)
|
||||
gihparms.placement = g_strdup (r + 1);
|
||||
}
|
||||
else if (strncmp (p, "rank", strlen ("rank")) == 0 && r)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("rank"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.rank[i] = atoi (r + 1);
|
||||
}
|
||||
}
|
||||
else if (strncmp (p, "sel", strlen ("sel")) == 0 && r)
|
||||
{
|
||||
if (r)
|
||||
{
|
||||
i = atoi (p + strlen ("sel"));
|
||||
if (i >= 0 && i < gihparms.dim)
|
||||
gihparms.selection[i] = g_strdup (r + 1);
|
||||
}
|
||||
}
|
||||
if (r)
|
||||
*r = ':';
|
||||
|
|
@ -753,12 +849,16 @@ parse_brush_pipe_parameters (gchar *parameters)
|
|||
|
||||
IFDBG(2) g_message ("parsed parasite: "
|
||||
"ncells:%d step:%d dim:%d cols:%d rows:%d "
|
||||
"rank0:%d rank1:%d rank2:%d rank3:%d",
|
||||
"placement:%s "
|
||||
"rank0:%d rank1:%d rank2:%d rank3:%d"
|
||||
"sel%d:%s sel%d:%s sel%d:%s ",
|
||||
gihparms.ncells, gihparms.step,
|
||||
gihparms.dim,
|
||||
gihparms.cols, gihparms.rows,
|
||||
gihparms.dim, gihparms.cols, gihparms.rows,
|
||||
gihparms.placement,
|
||||
gihparms.rank[0], gihparms.rank[1],
|
||||
gihparms.rank[2], gihparms.rank[3]);
|
||||
gihparms.rank[2], gihparms.rank[3],
|
||||
gihparms.selection[0], gihparms.selection[1],
|
||||
gihparms.selection[2], gihparms.selection[3]);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
|
@ -769,13 +869,17 @@ build_brush_pipe_parameters ()
|
|||
|
||||
int i;
|
||||
|
||||
g_string_sprintf (s, "ncells:%d step:%d dim:%d cols:%d rows:%d",
|
||||
g_string_sprintf (s, "ncells:%d step:%d dim:%d cols:%d rows:%d placement:%s",
|
||||
gihparms.ncells, gihparms.step,
|
||||
gihparms.dim,
|
||||
gihparms.cols, gihparms.rows);
|
||||
gihparms.cols, gihparms.rows,
|
||||
gihparms.placement);
|
||||
|
||||
for (i = 0; i < gihparms.dim; i++)
|
||||
g_string_sprintfa (s, " rank%d:%d", i, gihparms.rank[i]);
|
||||
{
|
||||
g_string_sprintfa (s, " rank%d:%d", i, gihparms.rank[i]);
|
||||
g_string_sprintfa (s, " sel%d:%s", i, gihparms.selection[i]);
|
||||
}
|
||||
|
||||
str = s->str;
|
||||
g_string_free (s, FALSE);
|
||||
|
|
@ -792,6 +896,7 @@ gih_save_image (char *filename,
|
|||
GDrawable *drawable;
|
||||
GPixelRgn pixel_rgn;
|
||||
FILE *file;
|
||||
Parasite *pipe_parasite;
|
||||
gchar *msg, *pars, *ncells;
|
||||
gint32 *layer_ID;
|
||||
gint nlayers, layer, row, col;
|
||||
|
|
@ -826,6 +931,13 @@ gih_save_image (char *filename,
|
|||
g_free (ncells);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pipe_parasite = parasite_new ("gimp-brush-pipe-parameters",
|
||||
PARASITE_PERSISTENT,
|
||||
strlen (pars) + 1, pars);
|
||||
gimp_image_attach_parasite (image_ID, pipe_parasite);
|
||||
parasite_free (pipe_parasite);
|
||||
|
||||
g_free (pars);
|
||||
g_free (ncells);
|
||||
|
||||
|
|
@ -958,11 +1070,12 @@ run (char *name,
|
|||
/* Possibly retrieve data */
|
||||
gimp_get_data ("file_gih_save", &info);
|
||||
pipe_parasite = gimp_image_find_parasite (image_ID, "gimp-brush-pipe-parameters");
|
||||
init_pipe_parameters ();
|
||||
if (pipe_parasite)
|
||||
{
|
||||
parse_brush_pipe_parameters (pipe_parasite->data);
|
||||
}
|
||||
|
||||
|
||||
if (!gih_save_dialog ())
|
||||
return;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1499,7 +1499,7 @@ read_tube_block (FILE *f,
|
|||
parasite_text =
|
||||
g_strdup_printf ("ncells:%d step:%d dim:%d cols:%d rows:%d "
|
||||
"rank0:%d "
|
||||
"spacing:%s sel0:%s",
|
||||
"placement:%s sel0:%s",
|
||||
cell_count, step_size, 1, column_count, row_count,
|
||||
cell_count,
|
||||
(placement_mode == tpmRandom ? "random" :
|
||||
|
|
|
|||
Loading…
Reference in a new issue